use crate::{
fyrox::{
core::{
algebra::Vector2, color::Color, pool::ErasedHandle, pool::Handle, visitor::Visitor,
},
graph::SceneGraph,
gui::{
brush::Brush,
button::ButtonBuilder,
file_browser::{FileSelectorBuilder, PathFilter},
image::ImageBuilder,
widget::{WidgetBuilder, WidgetMessage},
window::{Window, WindowBuilder},
BuildContext, HorizontalAlignment, Thickness, UiNode, UserInterface, VerticalAlignment,
},
},
load_image,
};
use fyrox::core::pool::ObjectOrVariant;
use fyrox::gui::button::Button;
use fyrox::gui::file_browser::{FileSelector, FileSelectorMode, FileType};
use std::{fs::File, path::Path};
pub mod doc;
pub fn make_pick_button(column: usize, ctx: &mut BuildContext) -> Handle<Button> {
ButtonBuilder::new(
WidgetBuilder::new()
.with_width(22.0)
.with_height(22.0)
.with_vertical_alignment(VerticalAlignment::Center)
.with_horizontal_alignment(HorizontalAlignment::Center)
.on_column(column)
.with_margin(Thickness::uniform(1.0)),
)
.with_content(
ImageBuilder::new(
WidgetBuilder::new()
.with_margin(Thickness::uniform(3.0))
.with_background(Brush::Solid(Color::opaque(0, 180, 0)).into()),
)
.with_opt_texture(load_image!("../../resources/pick.png"))
.build(ctx),
)
.build(ctx)
}
pub fn is_slice_equal_permutation<T: PartialEq>(a: &[T], b: &[T]) -> bool {
a.len() == b.len() && is_slice_subset_permutation(a, b) && is_slice_subset_permutation(b, a)
}
pub fn is_slice_subset_permutation<T: PartialEq>(a: &[T], b: &[T]) -> bool {
for source in a.iter() {
let mut found = false;
for other in b.iter() {
if other == source {
found = true;
break;
}
}
if !found {
return false;
}
}
true
}
pub fn window_content(window: Handle<Window>, ui: &UserInterface) -> Handle<UiNode> {
ui.try_get(window)
.ok()
.map(|w| w.content)
.unwrap_or_default()
}
pub fn enable_widget(
handle: Handle<impl ObjectOrVariant<UiNode>>,
state: bool,
ui: &UserInterface,
) {
ui.send(handle, WidgetMessage::Enabled(state));
}
pub fn create_file_selector(
ctx: &mut BuildContext,
file_type: FileType,
mode: FileSelectorMode,
) -> Handle<FileSelector> {
FileSelectorBuilder::new(
WindowBuilder::new(WidgetBuilder::new().with_width(300.0).with_height(400.0)).open(false),
)
.with_filter(PathFilter::new().with_file_type(file_type))
.with_mode(mode)
.build(ctx)
}
pub fn fetch_node_center(handle: Handle<UiNode>, ctx: &BuildContext) -> Vector2<f32> {
ctx.try_get_node(handle)
.map(|node| node.center())
.unwrap_or_default()
}
pub fn fetch_node_screen_center(
handle: Handle<impl ObjectOrVariant<UiNode>>,
ctx: &BuildContext,
) -> Vector2<f32> {
ctx.try_get_node(handle.to_base())
.map(|node| node.screen_bounds().center())
.unwrap_or_default()
}
pub fn fetch_node_screen_center_ui(handle: Handle<UiNode>, ui: &UserInterface) -> Vector2<f32> {
ui.try_get_node(handle)
.map(|node| node.screen_bounds().center())
.unwrap_or_default()
}
pub fn make_node_name(name: &str, handle: ErasedHandle) -> String {
format!("{} ({}:{})", name, handle.index(), handle.generation())
}
pub fn apply_visibility_filter<F>(root: Handle<UiNode>, ui: &UserInterface, filter: F)
where
F: Fn(&UiNode) -> Option<bool>,
{
fn apply_filter_recursive<F>(node: Handle<UiNode>, ui: &UserInterface, filter: &F) -> bool
where
F: Fn(&UiNode) -> Option<bool>,
{
let node_ref = ui.node(node);
let mut is_any_match = false;
for &child in node_ref.children() {
is_any_match |= apply_filter_recursive(child, ui, filter)
}
if let Some(has_match) = filter(node_ref) {
is_any_match |= has_match;
ui.send(node, WidgetMessage::Visibility(is_any_match));
}
is_any_match
}
apply_filter_recursive(root, ui, &filter);
}
pub fn is_native_scene(path: &Path) -> bool {
if let Ok(mut file) = File::open(path) {
Visitor::is_supported(&mut file)
} else {
false
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn empty_subset() {
assert!(is_slice_subset_permutation(&[], &[1, 2, 3]));
}
#[test]
fn subset() {
assert!(is_slice_subset_permutation(&[2, 3], &[1, 2, 3]));
}
#[test]
fn not_subset() {
assert!(!is_slice_subset_permutation(&[1, 2, 3], &[1, 2]));
}
#[test]
fn not_empty() {
assert!(!is_slice_subset_permutation(&[1, 2], &[]));
}
#[test]
fn equal() {
assert!(is_slice_equal_permutation(&[1, 2], &[1, 2]));
assert!(is_slice_equal_permutation(&[1, 2], &[2, 1]));
}
#[test]
fn not_equal() {
assert!(!is_slice_equal_permutation(&[1, 2], &[1]));
assert!(!is_slice_equal_permutation(&[1], &[2, 1]));
assert!(!is_slice_equal_permutation(&[1, 2], &[2, 3]));
assert!(!is_slice_equal_permutation(&[1, 1], &[1, 2]));
assert!(!is_slice_equal_permutation(&[1, 2], &[2, 2]));
}
}