Spaces:
Running
Running
Upload app_builder.py
Browse files- ui/app_builder.py +105 -0
ui/app_builder.py
CHANGED
|
@@ -1293,6 +1293,48 @@ def build_app() -> gr.Blocks:
|
|
| 1293 |
# Resolution manager popup (hidden by default)
|
| 1294 |
with gr.Column(visible=False, elem_id="resolution-popup-container") as res_popup:
|
| 1295 |
gr.Markdown("#### Manage Resolutions")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1296 |
gr.Markdown("Toggle which resolutions are available for random selection:")
|
| 1297 |
res_checkboxes = gr.CheckboxGroup(
|
| 1298 |
choices=DEFAULT_RESOLUTIONS,
|
|
@@ -2055,6 +2097,69 @@ def build_app() -> gr.Blocks:
|
|
| 2055 |
outputs=[enabled_resolutions]
|
| 2056 |
)
|
| 2057 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2058 |
# ========== Character Panel Handlers ==========
|
| 2059 |
|
| 2060 |
# Helper function to build character status text
|
|
|
|
| 1293 |
# Resolution manager popup (hidden by default)
|
| 1294 |
with gr.Column(visible=False, elem_id="resolution-popup-container") as res_popup:
|
| 1295 |
gr.Markdown("#### Manage Resolutions")
|
| 1296 |
+
|
| 1297 |
+
# Custom Resolution Section
|
| 1298 |
+
with gr.Group():
|
| 1299 |
+
gr.Markdown("##### Custom Resolution")
|
| 1300 |
+
use_custom_res = gr.Checkbox(
|
| 1301 |
+
label="Use Custom Resolution",
|
| 1302 |
+
value=False,
|
| 1303 |
+
elem_id="naia-use-custom-res"
|
| 1304 |
+
)
|
| 1305 |
+
|
| 1306 |
+
with gr.Row(visible=False) as custom_res_inputs:
|
| 1307 |
+
custom_width = gr.Number(
|
| 1308 |
+
label="Width",
|
| 1309 |
+
value=1024,
|
| 1310 |
+
step=64,
|
| 1311 |
+
minimum=64,
|
| 1312 |
+
precision=0,
|
| 1313 |
+
elem_id="naia-custom-width"
|
| 1314 |
+
)
|
| 1315 |
+
custom_height = gr.Number(
|
| 1316 |
+
label="Height",
|
| 1317 |
+
value=1024,
|
| 1318 |
+
step=64,
|
| 1319 |
+
minimum=64,
|
| 1320 |
+
precision=0,
|
| 1321 |
+
elem_id="naia-custom-height"
|
| 1322 |
+
)
|
| 1323 |
+
|
| 1324 |
+
custom_res_warning = gr.Markdown(
|
| 1325 |
+
"",
|
| 1326 |
+
visible=False,
|
| 1327 |
+
elem_id="naia-custom-res-warning"
|
| 1328 |
+
)
|
| 1329 |
+
apply_custom_btn = gr.Button(
|
| 1330 |
+
"Apply Custom Resolution",
|
| 1331 |
+
size="sm",
|
| 1332 |
+
visible=False,
|
| 1333 |
+
elem_id="naia-apply-custom-btn"
|
| 1334 |
+
)
|
| 1335 |
+
|
| 1336 |
+
gr.HTML("<hr style='margin: 16px 0; border: 0; border-top: 1px solid #eee;'>")
|
| 1337 |
+
|
| 1338 |
gr.Markdown("Toggle which resolutions are available for random selection:")
|
| 1339 |
res_checkboxes = gr.CheckboxGroup(
|
| 1340 |
choices=DEFAULT_RESOLUTIONS,
|
|
|
|
| 2097 |
outputs=[enabled_resolutions]
|
| 2098 |
)
|
| 2099 |
|
| 2100 |
+
# ========== Custom Resolution Handlers ==========
|
| 2101 |
+
|
| 2102 |
+
def toggle_custom_inputs(enabled):
|
| 2103 |
+
return gr.update(visible=enabled), gr.update(visible=enabled)
|
| 2104 |
+
|
| 2105 |
+
use_custom_res.change(
|
| 2106 |
+
fn=toggle_custom_inputs,
|
| 2107 |
+
inputs=[use_custom_res],
|
| 2108 |
+
outputs=[custom_res_inputs, apply_custom_btn]
|
| 2109 |
+
)
|
| 2110 |
+
|
| 2111 |
+
def validate_custom_res(w, h):
|
| 2112 |
+
if w is None or h is None:
|
| 2113 |
+
return gr.update(visible=False, value="")
|
| 2114 |
+
|
| 2115 |
+
msg = ""
|
| 2116 |
+
|
| 2117 |
+
# Check 64 multiple
|
| 2118 |
+
if w % 64 != 0 or h % 64 != 0:
|
| 2119 |
+
msg += "⚠️ Resolution must be a multiple of 64.<br>"
|
| 2120 |
+
|
| 2121 |
+
# Check 1MP limit
|
| 2122 |
+
pixels = w * h
|
| 2123 |
+
if pixels > 1024 * 1024:
|
| 2124 |
+
msg += "<span style='color: red; font-weight: bold;'>🔴 Resolution exceeds 1MP (1024x1024). This will incur Anlas cost!</span>"
|
| 2125 |
+
|
| 2126 |
+
return gr.update(value=msg, visible=bool(msg))
|
| 2127 |
+
|
| 2128 |
+
custom_width.change(
|
| 2129 |
+
fn=validate_custom_res,
|
| 2130 |
+
inputs=[custom_width, custom_height],
|
| 2131 |
+
outputs=[custom_res_warning]
|
| 2132 |
+
)
|
| 2133 |
+
custom_height.change(
|
| 2134 |
+
fn=validate_custom_res,
|
| 2135 |
+
inputs=[custom_width, custom_height],
|
| 2136 |
+
outputs=[custom_res_warning]
|
| 2137 |
+
)
|
| 2138 |
+
|
| 2139 |
+
def apply_custom_resolution(w, h):
|
| 2140 |
+
# Enforce 64 multiple (round to nearest)
|
| 2141 |
+
w = int(round(w / 64) * 64)
|
| 2142 |
+
h = int(round(h / 64) * 64)
|
| 2143 |
+
|
| 2144 |
+
res_str = f"{w} x {h}"
|
| 2145 |
+
|
| 2146 |
+
# Add to choices if not present
|
| 2147 |
+
new_choices = DEFAULT_RESOLUTIONS.copy()
|
| 2148 |
+
if res_str not in new_choices:
|
| 2149 |
+
new_choices.append(res_str)
|
| 2150 |
+
|
| 2151 |
+
return (
|
| 2152 |
+
gr.update(choices=new_choices, value=res_str), # Update dropdown
|
| 2153 |
+
False, # Uncheck Random
|
| 2154 |
+
gr.update(visible=False) # Close popup
|
| 2155 |
+
)
|
| 2156 |
+
|
| 2157 |
+
apply_custom_btn.click(
|
| 2158 |
+
fn=apply_custom_resolution,
|
| 2159 |
+
inputs=[custom_width, custom_height],
|
| 2160 |
+
outputs=[resolution, random_resolution, res_popup]
|
| 2161 |
+
)
|
| 2162 |
+
|
| 2163 |
# ========== Character Panel Handlers ==========
|
| 2164 |
|
| 2165 |
# Helper function to build character status text
|