Skip to content

Commit bca742f

Browse files
Movable Input Field with auto-scroll (projectmesa#2710)
* movable input field with auto-scroll * added CommandConsole to wolf-sheep * move the tips below the column * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent b60f75e commit bca742f

File tree

2 files changed

+60
-26
lines changed

2 files changed

+60
-26
lines changed

mesa/examples/advanced/wolf_sheep/app.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from mesa.examples.advanced.wolf_sheep.model import WolfSheep
33
from mesa.experimental.devs import ABMSimulator
44
from mesa.visualization import (
5+
CommandConsole,
56
Slider,
67
SolaraViz,
78
make_plot_component,
@@ -87,7 +88,7 @@ def post_process_lines(ax):
8788

8889
page = SolaraViz(
8990
model,
90-
components=[space_component, lineplot_component],
91+
components=[space_component, lineplot_component, CommandConsole],
9192
model_params=model_params,
9293
name="Wolf Sheep",
9394
simulator=simulator,

mesa/visualization/command_console.py

+58-25
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,41 @@ def format_output_html(entry):
337337
"""
338338

339339

340+
@solara.component
341+
def ConsoleInput(on_submit):
342+
"""A solara component for handling console input."""
343+
input_text, set_input_text = solara.use_state("")
344+
345+
def handle_submit(*ignore_args):
346+
on_submit(input_text)
347+
set_input_text("")
348+
349+
input_elem = solara.v.TextField(
350+
v_model=input_text,
351+
on_v_model=set_input_text,
352+
flat=True,
353+
hide_details=True,
354+
dense=True,
355+
height="auto",
356+
background_color="transparent",
357+
style_="font-family: monospace; border: none; box-shadow: none; padding: 0; margin: 0; background-color: transparent; color: #000; flex-grow: 1;",
358+
placeholder="",
359+
solo=False,
360+
filled=False,
361+
outlined=False,
362+
id="console-input",
363+
attributes={
364+
"spellcheck": "false",
365+
"autocomplete": "off",
366+
},
367+
)
368+
369+
# Handle Enter key press
370+
use_change(input_elem, handle_submit, update_events=["keyup.enter"])
371+
372+
return input_elem
373+
374+
340375
@solara.component
341376
def CommandConsole(model=None, additional_imports=None):
342377
"""A solara component for executing Python code interactively in the browser."""
@@ -347,10 +382,14 @@ def CommandConsole(model=None, additional_imports=None):
347382
model=model, additional_imports=additional_imports
348383
)
349384

350-
input_text, set_input_text = solara.use_state("")
351-
_, set_refresh = solara.use_state(0)
385+
# State to trigger re-renders
386+
refresh, set_refresh = solara.use_state(0)
352387

353-
with solara.lab.ChatBox(
388+
def handle_code_execution(code):
389+
console_ref.current.execute_code(code, lambda _: None)
390+
set_refresh(refresh + 1)
391+
392+
with solara.Column(
354393
style={
355394
"height": "300px",
356395
"overflow-y": "auto",
@@ -361,30 +400,24 @@ def CommandConsole(model=None, additional_imports=None):
361400
"padding": "8px",
362401
}
363402
):
364-
for entry in console_ref.current.get_entries():
365-
command_html = format_command_html(entry)
366-
output_html = format_output_html(entry)
367-
solara.Markdown(command_html + output_html)
403+
console_entries = console_ref.current.get_entries()
404+
405+
# Display history entries with auto-scrolling
406+
with solara.v.ScrollYTransition(group=True):
407+
for entry in console_entries:
408+
with solara.Div():
409+
command_html = format_command_html(entry)
410+
output_html = format_output_html(entry)
411+
solara.Markdown(command_html + output_html)
412+
413+
# Input row that adapts to content above it
414+
with solara.Row(
415+
style={"align-items": "center", "margin": "0", "width": "94.5%"}
416+
):
417+
solara.Text(">>> ", style={"color": "#0066cc"})
418+
ConsoleInput(on_submit=handle_code_execution)
368419

369420
solara.Markdown(
370421
"*Type 'tips' for usage instructions.*",
371422
style="font-size: 0.8em; color: #666;",
372423
)
373-
374-
input_elem = solara.v.TextField(
375-
v_model=input_text,
376-
on_v_model=set_input_text,
377-
flat=True,
378-
style_="font-family: monospace;",
379-
label=">>>",
380-
outlined=True,
381-
placeholder="Enter Python code...",
382-
attributes={"spellcheck": "false"},
383-
)
384-
385-
def on_enter(*ignore_args):
386-
console_ref.current.execute_code(input_text, set_input_text)
387-
set_refresh(lambda x: x + 1)
388-
389-
# Bind the enter key to execute the code
390-
use_change(input_elem, on_enter, update_events=["keyup.enter"])

0 commit comments

Comments
 (0)