Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@

<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
<script type="module" src="/src/app.tsx"></script>
</body>
</html>
14 changes: 2 additions & 12 deletions src-tauri/src/frontend_commands.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,7 @@
use std::sync::Mutex;
use tauri::{AppHandle, Manager, State, WebviewWindow};

pub struct SetupState {
pub frontend_ready: bool,
}
use tauri::{AppHandle, Manager, WebviewWindow};

#[tauri::command]
pub async fn set_frontend_ready(
app: AppHandle,
state: State<'_, Mutex<SetupState>>,
) -> Result<(), ()> {
let mut state_lock = state.lock().unwrap();
state_lock.frontend_ready = true;
pub async fn set_frontend_ready(app: AppHandle) -> Result<(), ()> {
let main_window = app.get_webview_window("main").unwrap();
main_window.show().unwrap();
Ok(())
Expand Down
83 changes: 11 additions & 72 deletions src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@ mod frontend_commands;
mod lua_commands;
mod lua_setup;
mod lua_types;
use frontend_commands::{resize_window, set_frontend_ready, window_scale, SetupState};
use frontend_commands::{resize_window, set_frontend_ready, window_scale};
use lua_commands::{
delete_entity, duplicate_entity, get_entity_string, handle_inspector_save, load_scene,
new_entity, run_script, save_scene, tick, update_entity,
};
use lua_setup::init_lua_thread;
use std::sync::Mutex;
use tauri::{
menu::{Menu, MenuItem, SubmenuBuilder},
Emitter, Listener, Manager,
Emitter, Manager,
};

#[cfg_attr(mobile, tauri::mobile_entry_point)]
Expand All @@ -20,9 +19,6 @@ pub fn run() {
.plugin(tauri_plugin_os::init())
.plugin(tauri_plugin_clipboard_manager::init())
.plugin(tauri_plugin_dialog::init())
.manage(Mutex::new(SetupState {
frontend_ready: false,
}))
.setup(|app| {
let window = app.get_webview_window("main").unwrap();
let state = init_lua_thread(window.clone()).expect("Error initializing lua thread");
Expand Down Expand Up @@ -63,41 +59,35 @@ pub fn run() {
handle,
"save_entity",
"Save Entity",
false,
Some("CmdOrCtrl+S"),
true,
Some("CmdOrCtrl+alt+S"),
)?)
.item(&MenuItem::with_id(
handle,
"revert_entity",
"Revert Changes",
false,
Some("CmdOrCtrl+R"),
true,
Some("CmdOrCtrl+alt+R"),
)?)
.build()?;
menu.append(&file_menu)?;

let window_clone = window.clone();
app.set_menu(menu)?;
app.on_menu_event(move |app_handle: &tauri::AppHandle, event| {
match event.id().0.as_str() {
file_op @ ("save_scene" | "open_scene") => {
if window_clone
.is_focused()
.expect("Couldn't find main window focus status")
{
app_handle
.emit_to("main", "file_operation", file_op)
.expect(&format!("Failed to emit {}", file_op));
}
app_handle
.emit_to("main", "file_operation", file_op)
.expect(&format!("Failed to emit {}", file_op));
}
"save_entity" => {
app_handle
.emit_to("inspector", "save_entity", ())
.emit_to("main", "save_entity", ())
.expect("Failed to emit save_entity to inspector");
}
"revert_entity" => {
app_handle
.emit_to("inspector", "revert_entity", ())
.emit_to("main", "revert_entity", ())
.expect("Failed to emit revert_entity to inspector");
}
"quit" => {
Expand All @@ -107,57 +97,6 @@ pub fn run() {
}
});

// enable/disable menu items based on focused window
fn on_focus_change(handle: &tauri::AppHandle, focus_window: String) {
if let Some(menu) = handle.menu() {
if let Some(file_menu) = menu.get("file") {
if let Some(submenu) = file_menu.as_submenu() {
if let Some(save_item) = submenu.get("save_scene") {
if let Some(menu_item) = save_item.as_menuitem() {
let _ = menu_item.set_enabled(focus_window == "main");
}
}
if let Some(open_item) = submenu.get("open_scene") {
if let Some(menu_item) = open_item.as_menuitem() {
let _ = menu_item.set_enabled(focus_window == "main");
}
}
if let Some(save_item) = submenu.get("save_entity") {
if let Some(menu_item) = save_item.as_menuitem() {
let _ = menu_item.set_enabled(focus_window == "inspector");
}
}
if let Some(save_item) = submenu.get("revert_entity") {
if let Some(menu_item) = save_item.as_menuitem() {
let _ = menu_item.set_enabled(focus_window == "inspector");
}
}
}
}
}
}

let handle_for_main = handle.clone();
window.listen("tauri://focus", move |_| {
on_focus_change(&handle_for_main, "main".to_string())
});

let handle_for_created = handle.clone();
app.listen("tauri://window-created", move |event| {
if let Ok(payload) = serde_json::from_str::<serde_json::Value>(event.payload()) {
if let Some(label) = payload.get("label").and_then(|l| l.as_str()) {
let label = label.to_string();
if let Some(w) = handle_for_created.get_webview_window(label.as_str()) {
let handle_for_focus = handle_for_created.clone();
let label_for_focus = label.clone();
w.listen("tauri://focus", move |_| {
on_focus_change(&handle_for_focus, label_for_focus.clone());
});
}
}
}
});

Ok(())
})
.plugin(tauri_plugin_opener::init())
Expand Down
70 changes: 70 additions & 0 deletions src/app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { render } from "preact";
import "./style.css";
import Scene from "./scene-window";
import Inspector from "./inspector/inspector";
import { useEffect, useRef, useState } from "preact/hooks";
import { getCurrentWindow } from "@tauri-apps/api/window";
import { MoreVertical } from "preact-feather";

export default function App() {
const [theme, setTheme] = useState<"light" | "dark">("light");
const [sidebarWidth, setSidebarWidth] = useState<number>(300);
const sidebarRef = useRef<HTMLDivElement>(null);

useEffect(() => {
let listeners: (() => void)[] = [];

(async () => {
listeners.push(
await getCurrentWindow().onThemeChanged(({ payload: theme }) =>
setTheme(theme),
),
);
})().then(async () =>
setTheme((await getCurrentWindow().theme()) || "light"),
);

return () => listeners.forEach((unsubscribe) => unsubscribe());
});

return (
<div class="w-screen h-screen flex flex-row">
<div class="w-full h-full flex flex-col">
<Scene />
<div class="flex-auto bg-border" />
</div>
<div
class="flex flex-row"
style={{ width: `${sidebarWidth}px` }}
ref={sidebarRef}
>
<div
class="h-full w-[6px] border-x-1 border-secondary cursor-ew-resize flex justify-center items-center p-0"
onMouseDown={(startEvent) => {
const startWidth = sidebarWidth || 128;
const startX = startEvent.clientX;

function onMouseMove(moveEvent: MouseEvent) {
setSidebarWidth(
Math.max(64, startWidth + (startX - moveEvent.clientX)), // TODO why is this not moving enough???
);
}

function onMouseUp() {
document.removeEventListener("mousemove", onMouseMove);
document.removeEventListener("mouseup", onMouseUp);
}

document.addEventListener("mousemove", onMouseMove);
document.addEventListener("mouseup", onMouseUp);
}}
>
<MoreVertical class="h-3 text-border" />
</div>
<Inspector theme={theme} />
</div>
</div>
);
}

render(<App />, document.getElementById("root")!);
2 changes: 1 addition & 1 deletion src/components/tab-bar/tab-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default function TabBar(props: TabBarProps) {

return (
<nav
class={`w-screen flex flex-row ${props.atBottom ? "border-t" : "border-b"} border-border bg-secondary`}
class={`w-full flex flex-row ${props.atBottom ? "border-t" : "border-b"} border-border bg-secondary`}
>
{children.map((child, index) => {
if (child && typeof child === "object" && "type" in child) {
Expand Down
42 changes: 6 additions & 36 deletions src/entity/entity-component.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import { Menu } from "@tauri-apps/api/menu";
import { invoke } from "@tauri-apps/api/core";
import { WebviewWindow } from "@tauri-apps/api/webviewWindow";
import { emitTo } from "@tauri-apps/api/event";
import { getCurrentWindow } from "@tauri-apps/api/window";
import Markdown from "marked-react";
import { JSX } from "preact/jsx-runtime";
import { message } from "@tauri-apps/plugin-dialog";
import { Entity } from "./entity-type";

interface EntityProps {
entity: any;
onSelect: () => void;
onSelect: (select: boolean) => void;
isSelected: boolean;
}

Expand Down Expand Up @@ -103,38 +101,10 @@ export default function EntityComponent(props: EntityProps) {
}

async function openInspector() {
emitTo(getCurrentWindow().label, "select_entity", { id: undefined });
props.onSelect(false);

// If window already exists, focus & update instead of creating a new one
const existing = await WebviewWindow.getByLabel("inspector");
if (existing) {
emitTo("inspector", "provide_entity", props.entity);
existing.setFocus();
return;
}

// Create new inspector window
const inspectorWindow = new WebviewWindow("inspector", {
title: "Inspector",
url: "src/inspector/inspector.html",
width: 300,
height: 600,
resizable: true,
minWidth: 200,
minHeight: 300,
focus: false,
backgroundColor: window
.getComputedStyle(document.body)
.getPropertyValue("--background-color"),
});

inspectorWindow.once("mounted", () => {
emitTo("inspector", "provide_entity", props.entity);
});

inspectorWindow.once("tauri://error", (e) => {
console.error("Inspector webview had ERROR!", e);
});
// TODO
emitTo("inspector", "provide_entity", props.entity);
}

return (
Expand All @@ -147,11 +117,11 @@ export default function EntityComponent(props: EntityProps) {
onMouseDown={(e) => {
e.stopPropagation();
if (props.isSelected) e.stopPropagation();
else if (props.entity.selectable) props.onSelect();
else if (props.entity.selectable) props.onSelect(true);
}}
onDblClick={async (e) => {
e.stopPropagation();
emitTo(getCurrentWindow().label, "select_entity", { id: undefined });
props.onSelect(false);
if (props.entity.scripts.on_click) runScript("on_click", {});
}}
onContextMenu={async (e) => {
Expand Down
20 changes: 0 additions & 20 deletions src/inspector/inspector.html

This file was deleted.

Loading