def __init__(self): self._commands: List[network.Request] = [] self._last_state: PhysicsState canvas = vpython.canvas(width=1, height=1) common.include_vpython_footer_file( Path('orbitx', 'graphics', 'simple_css.css')) # Hide vpython wtexts, except for the table. canvas.append_to_caption("""<style> span { /* Hide any wtexts we generate. */ display: none; } span.nohide { /* Make sure wtexts we make are not hidden. */ display: initial; } div.flex-box { display: flex; justify-content: space-between; } input { flex: 1; margin: 5px; } </style>""") canvas.append_to_caption("<title>OrbitX Physics Server</title>") canvas.append_to_caption("<h1>OrbitX Physics Server</h1>") canvas.append_to_caption(f"<h3>Running on {socket.getfqdn()}</h3>") canvas.append_to_caption("<div class='flex-box'></div>") vpython_widgets.Input(bind=self._load_hook, placeholder='Load savefile') vpython_widgets.Input(bind=self._load_hook, placeholder='Save savefile') vpython_widgets.stuff_widgets_into_flex_box( [vpython_widgets.last_div_id - 1, vpython_widgets.last_div_id]) canvas.append_to_caption("<hr />") self._clients_table = vpython.wtext(text='') vpython_widgets.last_div_id += 1 # We hide all other vpython-made wtexts, except for this one. canvas.append_to_caption(f"""<script> document.querySelector( 'span[id="{vpython_widgets.last_div_id}"]').className = 'nohide'; </script>""") self._last_contact_wtexts: List[vpython.wtext] = [] self._previous_number_of_clients: int = 0 # This is needed to launch vpython. vpython.sphere() canvas.delete() common.remove_vpython_css()
def __init__(self, flight_gui: FlightGui, running_as_mirror: bool): """Create the sidebar caption.""" self._parent = flight_gui self._create_wtexts() self.trails_checkbox = Checkbox( self._parent.trail_checkbox_hook, DEFAULT_TRAILS, 'Trails', "Graphically intensive") self.orbits_checkbox = Checkbox( self._parent._orbits_checkbox_hook, False, 'Orbit', "Simple projection of hab around reference.") vpython.canvas.get_selected().append_to_caption("<br/>") self._create_menus() # If you change the order of these, note that the placeholder text # is set in flight_gui_footer.html self._save_box = vpython.winput( bind=self._parent._save_hook, type='string') self._save_box.disabled = True vpython.canvas.get_selected().append_to_caption("\n") self._load_box = vpython.winput( bind=self._parent._load_hook, type='string') self._load_box.disabled = True vpython.canvas.get_selected().append_to_caption("\n") vpython.canvas.get_selected().append_to_caption( "<span class='helptext'>" "Filename to save/load under data/saves/</span>") vpython.canvas.get_selected().append_to_caption("\n") vpython.canvas.get_selected().append_to_caption("<br/>") self.follow_lead_checkbox: Optional[Checkbox] if running_as_mirror: start_off_following = True self.follow_lead_checkbox = Checkbox( lambda checkbox: self._disable_inputs(checkbox.checked), start_off_following, 'Follow physics server', "Check to keep this mirror program in sync with the " "mirror://[host]:[port] OrbitX physics server specified at " "startup" ) self._disable_inputs(start_off_following) else: self.follow_lead_checkbox = None common.remove_vpython_css() common.include_vpython_footer_file( Path('orbitx', 'graphics', 'flight_gui_footer.html'))
def __init__(self, server_name: str, error: grpc.RpcError): canvas = vpython.canvas(width=1, height=1) common.include_vpython_footer_file( Path('orbitx', 'graphics', 'simple_css.css')) # TODO: failed connec canvas.append_to_caption("<title>OrbitX Error</title>") canvas.append_to_caption( f"<h3>Tried connecting to Physics Server at {server_name}</h3>") canvas.append_to_caption(f"""<div class='error'> But the network connection failed to start (<span class='mono'>{error.code()}</span>). {"The Physics Server might be not running, or it might be running " "on a different host." if error.code() == grpc.StatusCode.UNAVAILABLE else ""} </div>""") # This is needed to launch vpython. vpython.sphere() canvas.delete() common.remove_vpython_css()
def __init__(self, server_name: str, intermediary: OrbitVIntermediary): self._orbitsse_path = intermediary.orbitsse canvas = vpython.canvas(width=1, height=1) common.include_vpython_footer_file( Path('orbitx', 'graphics', 'simple_css.css')) canvas.append_to_caption("<title>OrbitX Compat Client</title>") canvas.append_to_caption("<h1>OrbitX ↔ OrbitV Piloting Compatibility") canvas.append_to_caption( f"<h3>Connected to Physics Server at {server_name}</h3>") self._error_field = vpython.wtext(text='') vpython_widgets.last_div_id += 1 canvas.append_to_caption( f"<div id={vpython_widgets.last_div_id}></div>") canvas.append_to_caption("<h3>OrbitX → OrbitV</h3>") canvas.append_to_caption( "<div>" f"Writing to <span class='mono'>{intermediary.osbackup}</span>" "</div>") self._osbackup_write_time_field = vpython.wtext(text='') vpython_widgets.last_div_id += 1 canvas.append_to_caption( "<div>" "<span>Last update written at</span> " f"<span class='mono' id='{vpython_widgets.last_div_id}'></span>" "</div>") self._orbitv_entities = set(intermediary.orbitv_names) self._last_missing_entities_set: Set[str] = set() self._missing_entities_warning = vpython.wtext(text='') vpython_widgets.last_div_id += 1 canvas.append_to_caption( f"<div id='{vpython_widgets.last_div_id}'></div>") canvas.append_to_caption("<h3>OrbitX ← OrbitV</h3>") canvas.append_to_caption( "<div>" f"Reading from <span class='mono'>{intermediary.orbitsse}</span>" "</div>") self._orbitsse_read_time_field = vpython.wtext(text='') vpython_widgets.last_div_id += 1 canvas.append_to_caption( "<div>" "<span>Last update detected and read at</span> " f"<span class='mono' id='{vpython_widgets.last_div_id}'></span>" "</div>") canvas.append_to_caption("<table>\n") canvas.append_to_caption( "<caption>Contents of last OrbitV Engineering update</caption>") canvas.append_to_caption("<tr>") canvas.append_to_caption("<th scope='col'>Field name</th>") canvas.append_to_caption("<th scope='col'>Field value</th>") canvas.append_to_caption("</tr>") def row_text_setter( eng_update: network.Request.OrbitVEngineeringUpdate, field_name: str) -> str: return getattr(eng_update, field_name) fields_list = orbitx_pb2.Command.OrbitVEngineeringUpdate.DESCRIPTOR.fields self._eng_fields: List[vpython_widgets.TableText] = [] for descriptor in fields_list: self._eng_fields.append( vpython_widgets.TableText( descriptor.name.replace('_', ' ').title(), functools.partial(row_text_setter, field_name=descriptor.name), None, new_section=False)) canvas.append_to_caption("</table>") # This is needed to launch vpython. vpython.sphere() canvas.delete() common.remove_vpython_css()
def __init__(self): # When the user clicks a button, this will be set. self._user_args: Optional[List[str]] = None self._program: Optional[programs.Program] = None canvas = vpython.canvas(width=1, height=1) # Some basic but nice styling. common.include_vpython_footer_file( Path('orbitx', 'graphics', 'simple_css.css')) canvas.append_to_caption("""<style> .argname { font-weight: bold; } </style>""") # Set up some buttons asking what program the user wants to run. canvas.append_to_caption("<h1>OrbitX Launcher</h1>") canvas.append_to_caption("<h2>Select a program to launch</h2>") canvas.append_to_caption( "<input type='checkbox' id='description_checkbox'>" "Show descriptions" "</input>") for program in programs.LISTING: text_fields: List[vpython.winput] = [] canvas.append_to_caption("<hr />") canvas.append_to_caption(f"<h3>{program.name}</h3>") vpython.button(text=f'Launch {program.name}!', bind=functools.partial(self._set_args, program, text_fields)) canvas.append_to_caption(f"<p>{program.description}</p>") for arg in program.argparser._actions: if '--help' in arg.option_strings: # This is the default help action, ignore it. continue canvas.append_to_caption( f"<span class='argname'>{arg.dest}:</span>") canvas.append_to_caption( f"<span class='description'> {arg.help}</span> ") arg_field = vpython.winput( # The bind is a no-op, we'll poll the .text attribute. type='string', bind=lambda _: None, text=arg.default) canvas.append_to_caption("<br />") # Monkey-patch this attribute so that we can build CLI args # properly. arg_field.arg = arg text_fields.append(arg_field) vpython_widgets.last_div_id += 1 common.remove_vpython_css() # Make clicking the per-program launch button also submit all the args # that the user has entered. canvas.append_to_caption("""<script> buttons = document.querySelectorAll("button"); for (const element of buttons) { element.addEventListener('mousedown', function(ev) { // Send an 'enter' keypress so that python code gets the // current value of each text input. inputs = document.querySelectorAll('input'); for (const input of inputs) { var ev = document.createEvent('Event'); ev.initEvent('keypress'); ev.keyCode = 13; input.dispatchEvent(ev); } }); } description_checkbox = document.querySelector( '#description_checkbox'); description_checkbox.addEventListener('change', function(event) { console.log(event); descriptions = document.getElementsByClassName("description"); for (const element of descriptions) { element.style.display = (event.target.checked ? "initial" : "none" ); } }) </script>""") # This is needed to launch vpython. vpython.sphere() vpython.canvas.get_selected().delete()