mirror of
https://github.com/storytold/storyteller-bevy.git
synced 2026-10-17 00:13:17 +00:00
Grid based style and pretty number inputs
This commit is contained in:
@@ -66,6 +66,9 @@ export class AppElement extends LitElement {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
font-family: "Fira Sans", sans-serif;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -17,9 +17,16 @@ function unpack_vnode(
|
||||
var attr = node_data["attributes"][i];
|
||||
element.setAttribute(attr[0], attr[1]);
|
||||
}
|
||||
|
||||
//Create custom elements
|
||||
if (node_data["tag"] == "input" && element["type"] == "number") {
|
||||
create_float_input(element);
|
||||
}
|
||||
|
||||
if (node_data["id"] != undefined) {
|
||||
element.setAttribute("id", node_data["id"]);
|
||||
};
|
||||
|
||||
//apply children
|
||||
if (node_data["children"] != undefined) {
|
||||
for (var j = 0; j < node_data["children"].length; j++) {
|
||||
@@ -76,6 +83,8 @@ function apply_muts(
|
||||
root.removeChild(root.firstChild);
|
||||
}
|
||||
root.appendChild(element);
|
||||
append_style(root);
|
||||
|
||||
} else if (mut["SetAttibute"] != undefined) {
|
||||
let m = mut["SetAttibute"];
|
||||
let id = m["id"];
|
||||
@@ -120,3 +129,87 @@ document.addEventListener('inspector-dom-changed', (event: CustomEvent) => {
|
||||
apply_muts(customEvent);
|
||||
});
|
||||
|
||||
function create_float_input(element : HTMLInputElement) {
|
||||
|
||||
console.log("create_float_input", element);
|
||||
|
||||
let value = 0; // Начальное значение
|
||||
let isMouseDown = false;
|
||||
let startX = 0;
|
||||
|
||||
element.addEventListener('mousedown', (e: MouseEvent) => {
|
||||
isMouseDown = true;
|
||||
startX = e.clientX;
|
||||
value = parseInt(element.value, 10);
|
||||
document.addEventListener('mousemove', onMouseMove);
|
||||
document.addEventListener('mouseup', onMouseUp);
|
||||
});
|
||||
|
||||
const onMouseMove = (e: MouseEvent) => {
|
||||
if (isMouseDown) {
|
||||
const dx = e.clientX - startX;
|
||||
element.value = (value + dx / 10).toString(); // Изменение на 1 за каждые 5 пикселей движения мыши
|
||||
//dispatch update event
|
||||
const event = new Event('input', {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
});
|
||||
element.dispatchEvent(event);
|
||||
}
|
||||
};
|
||||
|
||||
const onMouseUp = () => {
|
||||
isMouseDown = false;
|
||||
document.removeEventListener('mousemove', onMouseMove);
|
||||
document.removeEventListener('mouseup', onMouseUp);
|
||||
};
|
||||
|
||||
element.addEventListener('keydown', (e: KeyboardEvent) => {
|
||||
if (!e.key.match(/^[0-9]$/)) {
|
||||
e.preventDefault(); // Предотвратить ввод нечисловых символов
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function append_style(parent : HTMLElement) {
|
||||
let style = document.createElement('style');
|
||||
|
||||
// Устанавливаем тип содержимого для <style>
|
||||
style.type = 'text/css';
|
||||
|
||||
// Добавляем CSS правила в элемент <style>. Используйте обратные кавычки для многострочного текста
|
||||
style.innerHTML = `
|
||||
input[type="number"] {
|
||||
background-color: #3333336e; /* Темный фон */
|
||||
color: #fff; /* Светлый текст */
|
||||
border: none; /* Убрать стандартную рамку */
|
||||
border-radius: 7px; /* Закругленные границы */
|
||||
padding: 5px; /* Внутренний отступ */
|
||||
outline: none; /* Убрать контур при фокусе */
|
||||
}
|
||||
input[type="number"]:focus {
|
||||
border: 2px solid #555; /* Стиль границы при фокусе */
|
||||
background-color: #222; /* Немного темнее фон при фокусе */
|
||||
}
|
||||
|
||||
input[type="number"]::-webkit-inner-spin-button,
|
||||
input[type="number"]::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
input[type="number"] {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
|
||||
.struct-grid {
|
||||
display: grid;
|
||||
grid-template-columns: min-content 1fr;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
`;
|
||||
|
||||
parent.appendChild(style);
|
||||
}
|
||||
@@ -94,7 +94,7 @@ fn show_selected(
|
||||
let element = Element::Component(super::utils::Component {
|
||||
tag: "div".to_string(),
|
||||
attributes: vec![
|
||||
|
||||
("style".to_string(), "display: flex; flex-direction: column; height: 100%; overflow: auto;".to_string())
|
||||
],
|
||||
children: inspected.components.into_iter().map(|c| {
|
||||
show_reflect(
|
||||
|
||||
+16
-8
@@ -209,19 +209,22 @@ impl EntityChangeExecutor {
|
||||
fn check_predefined(r : &dyn Reflect, onchange : ReflectChange) -> Option<Element> {
|
||||
if let Some(name) = r.downcast_ref::<Name>() {
|
||||
Some(Element::Component(Component {
|
||||
tag: "input".to_string(),
|
||||
tag: "div".to_string(),
|
||||
attributes: vec![
|
||||
("type".to_string(), "text".to_string()),
|
||||
("value".to_string(), name.to_string()),
|
||||
("style".to_string(), "font-weight: bold".to_string()),
|
||||
],
|
||||
children: vec![],
|
||||
onchange: Some(Box::new(ReflectValueExecutor::from(onchange.add_path("name"))))
|
||||
children: vec![
|
||||
Element::Text(format!("{}", &name)),
|
||||
],
|
||||
onchange: None
|
||||
}))
|
||||
} else if let Some(transform) = r.downcast_ref::<Transform>() {
|
||||
|
||||
Some(Element::Component(Component {
|
||||
tag: "div".to_string(),
|
||||
attributes: vec![],
|
||||
attributes: vec![
|
||||
("style".to_string(), "display: flex; flex-direction: column".to_string()),
|
||||
],
|
||||
children: vec![
|
||||
Element::Text("Pos: ".to_string()),
|
||||
show_reflect(&transform.translation, onchange.add_path("translation")).unwrap(),
|
||||
@@ -236,7 +239,9 @@ fn check_predefined(r : &dyn Reflect, onchange : ReflectChange) -> Option<Elemen
|
||||
let euler = quat.to_euler(EulerRot::XYZ);
|
||||
Some(Element::Component(Component {
|
||||
tag: "div".to_string(),
|
||||
attributes: vec![],
|
||||
attributes: vec![
|
||||
("class".to_string(), "struct-grid".to_string()),
|
||||
],
|
||||
children: vec![
|
||||
Element::Text("X: ".to_string()),
|
||||
Element::Component(Component {
|
||||
@@ -283,7 +288,9 @@ fn check_predefined(r : &dyn Reflect, onchange : ReflectChange) -> Option<Elemen
|
||||
else if let Some(vec) = r.downcast_ref::<Vec3>() {
|
||||
Some(Element::Component(Component {
|
||||
tag: "div".to_string(),
|
||||
attributes: vec![],
|
||||
attributes: vec![
|
||||
("class".to_string(), "struct-grid".to_string()),
|
||||
],
|
||||
children: vec![
|
||||
Element::Text("X: ".to_string()),
|
||||
Element::Component(Component {
|
||||
@@ -291,6 +298,7 @@ fn check_predefined(r : &dyn Reflect, onchange : ReflectChange) -> Option<Elemen
|
||||
attributes: vec![
|
||||
("type".to_string(), "number".to_string()),
|
||||
("value".to_string(), vec.x.to_string()),
|
||||
|
||||
],
|
||||
children: vec![],
|
||||
onchange: Some(Box::new(ReflectValueExecutor::from(onchange.add_path("x"))))
|
||||
|
||||
Reference in New Issue
Block a user