artel3D commited on
Commit
ea821ac
·
1 Parent(s): 844f6a6

fix: gr.Plot.select n'existe pas en Gradio 6 — UI grille de boutons (8 az + 4 el + 3 di)

Browse files
Files changed (1) hide show
  1. app.py +46 -41
app.py CHANGED
@@ -164,14 +164,18 @@ def infer(image, az, el, di, seed, randomize_seed):
164
 
165
  # ── UI Gradio ─────────────────────────────────────────────────────────────────
166
 
167
- with gr.Blocks(title="Angle Studio", theme=gr.themes.Base()) as demo:
 
 
 
 
 
168
  gr.Markdown("""
169
  # 🎥 Angle Studio
170
- **Cliquez un point sur le diagramme pour choisir l'angle, puis générez.**
171
- *Click a dot on the diagram to pick the angle, then generate.*
172
  """)
173
 
174
- # États courants
175
  az_state = gr.State(0)
176
  el_state = gr.State(0)
177
  di_state = gr.State(1.0)
@@ -180,11 +184,23 @@ with gr.Blocks(title="Angle Studio", theme=gr.themes.Base()) as demo:
180
  with gr.Column(scale=1):
181
  input_image = gr.Image(label="Image source / Source image", type="pil")
182
 
183
- gr.Markdown("**Distance**")
 
 
 
 
 
 
 
 
 
 
 
 
184
  with gr.Row():
185
- btn_close = gr.Button("🔍 Close-up (0.6)", size="sm")
186
- btn_medium = gr.Button("📷 Medium (1.0)", size="sm", variant="primary")
187
- btn_wide = gr.Button("🌄 Wide (1.8)", size="sm")
188
 
189
  prompt_preview = gr.Textbox(
190
  label="Prompt", interactive=False,
@@ -196,7 +212,7 @@ with gr.Blocks(title="Angle Studio", theme=gr.themes.Base()) as demo:
196
  generate_btn = gr.Button("▶ Générer / Generate", variant="primary", size="lg")
197
 
198
  with gr.Column(scale=1):
199
- viewer = gr.Plot(value=build_viewer(0, 0, 1.0), label=None, show_label=False)
200
  output_image = gr.Image(label="Résultat / Result", type="pil")
201
  output_seed = gr.Number(label="Seed utilisé", interactive=False)
202
 
@@ -204,43 +220,32 @@ with gr.Blocks(title="Angle Studio", theme=gr.themes.Base()) as demo:
204
  gallery = gr.Gallery(columns=4, height=260)
205
  session_images = gr.State([])
206
 
207
- # ── Click sur le viewer set az + el ────────────────────────────────────
208
- def on_pick(di, evt: gr.SelectData):
209
- # Le clic peut tomber sur n'importe quelle trace : on ne traite que la
210
- # trace des 32 poses (curveNumber 6 : 4 cercles + sujet + labels).
211
- idx = evt.index
212
- if idx is None or not isinstance(idx, int):
213
- return gr.update(), gr.update(), gr.update(), gr.update()
214
- # On accepte uniquement les index 0..31 venant de la trace "poses".
215
- # evt.value[2] contient le hovertext si on veut filtrer plus finement,
216
- # mais l'index suffit dans la trace cliquée.
217
- n = len(AZIMUTHS) * len(ELEVATIONS)
218
- if idx < 0 or idx >= n:
219
- return gr.update(), gr.update(), gr.update(), gr.update()
220
- az = AZIMUTHS[idx // len(ELEVATIONS)]
221
- el = ELEVATIONS[idx % len(ELEVATIONS)]
222
- return az, el, build_viewer(az, el, di), build_prompt(az, el, di)
223
-
224
- viewer.select(
225
- fn=on_pick,
226
- inputs=[di_state],
227
- outputs=[az_state, el_state, viewer, prompt_preview],
228
- )
229
 
230
- # ── Boutons distance ───────────────────────────────────────────��──────────
231
- def set_distance(d):
232
  def _fn(az, el):
233
  return d, build_viewer(az, el, d), build_prompt(az, el, d)
234
  return _fn
235
 
236
- btn_close.click(fn=set_distance(0.6), inputs=[az_state, el_state],
237
- outputs=[di_state, viewer, prompt_preview])
238
- btn_medium.click(fn=set_distance(1.0), inputs=[az_state, el_state],
239
- outputs=[di_state, viewer, prompt_preview])
240
- btn_wide.click(fn=set_distance(1.8), inputs=[az_state, el_state],
241
- outputs=[di_state, viewer, prompt_preview])
 
 
 
242
 
243
- # ── Génération ────────────────────────────────────────────────────────────
244
  def run_and_append(image, az, el, di, seed, rand, history):
245
  result, used_seed, _ = infer(image, az, el, di, seed, rand)
246
  history = history + [result]
@@ -252,4 +257,4 @@ with gr.Blocks(title="Angle Studio", theme=gr.themes.Base()) as demo:
252
  outputs=[output_image, output_seed, session_images, gallery],
253
  )
254
 
255
- demo.launch()
 
164
 
165
  # ── UI Gradio ─────────────────────────────────────────────────────────────────
166
 
167
+ AZ_LABELS = {0: " Front", 45: "↗ Front-R", 90: "➡ Right", 135: "↘ Back-R",
168
+ 180: "⬇ Back", 225: "↙ Back-L", 270: "⬅ Left", 315: "↖ Front-L"}
169
+ EL_LABELS = {-30: "⬇ Low (-30°)", 0: "➡ Eye (0°)", 30: "⬈ Elev (+30°)", 60: "⬆ High (+60°)"}
170
+ DI_LABELS = {0.6: "🔍 Close-up", 1.0: "📷 Medium", 1.8: "🌄 Wide"}
171
+
172
+ with gr.Blocks(title="Angle Studio") as demo:
173
  gr.Markdown("""
174
  # 🎥 Angle Studio
175
+ **Cliquez 1 azimut, 1 élévation, 1 distance puis générez.**
176
+ *Pick one azimuth, one elevation, one distance then generate.*
177
  """)
178
 
 
179
  az_state = gr.State(0)
180
  el_state = gr.State(0)
181
  di_state = gr.State(1.0)
 
184
  with gr.Column(scale=1):
185
  input_image = gr.Image(label="Image source / Source image", type="pil")
186
 
187
+ gr.Markdown("### 🧭 Azimut")
188
+ with gr.Row():
189
+ az_buttons = [gr.Button(AZ_LABELS[a], size="sm",
190
+ variant=("primary" if a == 0 else "secondary"))
191
+ for a in AZIMUTHS]
192
+
193
+ gr.Markdown("### 📐 Élévation")
194
+ with gr.Row():
195
+ el_buttons = [gr.Button(EL_LABELS[e], size="sm",
196
+ variant=("primary" if e == 0 else "secondary"))
197
+ for e in ELEVATIONS]
198
+
199
+ gr.Markdown("### 🔭 Distance")
200
  with gr.Row():
201
+ di_buttons = [gr.Button(DI_LABELS[d], size="sm",
202
+ variant=("primary" if d == 1.0 else "secondary"))
203
+ for d in DISTANCES]
204
 
205
  prompt_preview = gr.Textbox(
206
  label="Prompt", interactive=False,
 
212
  generate_btn = gr.Button("▶ Générer / Generate", variant="primary", size="lg")
213
 
214
  with gr.Column(scale=1):
215
+ viewer = gr.Plot(value=build_viewer(0, 0, 1.0), show_label=False)
216
  output_image = gr.Image(label="Résultat / Result", type="pil")
217
  output_seed = gr.Number(label="Seed utilisé", interactive=False)
218
 
 
220
  gallery = gr.Gallery(columns=4, height=260)
221
  session_images = gr.State([])
222
 
223
+ # ── Handlers : chaque bouton met à jour son état + viewer + prompt ───────
224
+ def make_az_handler(a):
225
+ def _fn(el, di):
226
+ return a, build_viewer(a, el, di), build_prompt(a, el, di)
227
+ return _fn
228
+
229
+ def make_el_handler(e):
230
+ def _fn(az, di):
231
+ return e, build_viewer(az, e, di), build_prompt(az, e, di)
232
+ return _fn
 
 
 
 
 
 
 
 
 
 
 
 
233
 
234
+ def make_di_handler(d):
 
235
  def _fn(az, el):
236
  return d, build_viewer(az, el, d), build_prompt(az, el, d)
237
  return _fn
238
 
239
+ for a, btn in zip(AZIMUTHS, az_buttons):
240
+ btn.click(fn=make_az_handler(a), inputs=[el_state, di_state],
241
+ outputs=[az_state, viewer, prompt_preview])
242
+ for e, btn in zip(ELEVATIONS, el_buttons):
243
+ btn.click(fn=make_el_handler(e), inputs=[az_state, di_state],
244
+ outputs=[el_state, viewer, prompt_preview])
245
+ for d, btn in zip(DISTANCES, di_buttons):
246
+ btn.click(fn=make_di_handler(d), inputs=[az_state, el_state],
247
+ outputs=[di_state, viewer, prompt_preview])
248
 
 
249
  def run_and_append(image, az, el, di, seed, rand, history):
250
  result, used_seed, _ = infer(image, az, el, di, seed, rand)
251
  history = history + [result]
 
257
  outputs=[output_image, output_seed, session_images, gallery],
258
  )
259
 
260
+ demo.launch(theme=gr.themes.Base())