File size: 3,304 Bytes
2475edf
 
 
8ad17fe
 
2475edf
8ad17fe
2475edf
8ad17fe
 
2475edf
 
8ad17fe
 
 
2475edf
8ad17fe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2475edf
 
 
 
8ad17fe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2475edf
8ad17fe
 
2475edf
8ad17fe
 
 
2475edf
 
 
 
8ad17fe
f7eafd6
8ad17fe
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# app.py
import streamlit as st
import streamlit.components.v1 as components
import os
import json # To safely embed the python variable into JS

# --- 1. Set Page Configuration (Set first!) ---
st.set_page_config(
    page_title="Three.js Editor",
    layout="wide"  # Use the full screen width
)

# --- Initialize Session State ---
if 'selected_object' not in st.session_state:
    st.session_state.selected_object = 'None' # Default selection

# --- Sidebar Controls ---
with st.sidebar:
    st.title("🛠️ Controls & State")
    st.caption("Select an object type and click on the ground in the main view to place it.")

    # Define available object types (keys should ideally match JS functions/identifiers)
    object_types = ["None", "Simple House", "Tree", "Rock", "Fence Post"] # Add more as needed

    # Selectbox to choose object type - this updates session_state on change
    selected = st.selectbox(
        "Select Object to Place:",
        options=object_types,
        key='selected_object' # Link to session state key
    )

    st.write("---")
    st.header("Current State:")
    st.write(f"Selected Object Type: **{st.session_state.selected_object}**")
    # Add more state tracking here later if needed
    st.info("Use WASD/Arrows in the main view if player movement is enabled in JS.")


# --- Main Area for the 3D View ---
st.header("🏗️ Three.js Primitive Builder")

# --- Load and Prepare HTML ---
html_file_path = 'index.html'

try:
    with open(html_file_path, 'r', encoding='utf-8') as f:
        html_template = f.read()

    # --- Inject Python state into JavaScript ---
    # We'll add a script tag to set a global JS variable before the main script runs
    js_injection_script = f"""
<script>
    // Set this global variable based on Streamlit state BEFORE the main script runs
    window.SELECTED_OBJECT_TYPE = {json.dumps(st.session_state.selected_object)};
    console.log("Streamlit selected object:", window.SELECTED_OBJECT_TYPE);
</script>
"""
    # Insert the injection script just before the closing </head> or starting <script type="module">
    # A simple approach: find the main script tag and insert before it.
    # More robust: add a placeholder like in index.html
    # For now, let's find the module script tag:
    module_script_tag = '<script type="module">'
    if module_script_tag in html_template:
         # Inject our script right before the main module script
         html_content_with_state = html_template.replace(
             module_script_tag,
             js_injection_script + "\n" + module_script_tag,
             1 # Replace only the first occurrence
        )
    else:
         # Fallback: inject before closing head (less ideal if script needs DOM)
         html_content_with_state = html_template.replace('</head>', js_injection_script + '\n</head>', 1)


    # --- Embed HTML Component ---
    components.html(
        html_content_with_state,
        height=750, # Adjust height as needed
        scrolling=False
    )

except FileNotFoundError:
    st.error(f"Error: Could not find the file '{html_file_path}'.")
    st.warning("Please make sure `index.html` is in the same directory as `app.py`.")
except Exception as e:
    st.error(f"An error occurred: {e}")
    st.exception(e) # Show full traceback for debugging