def test_disabled_text(self): """ Check disabled TextBox can be used for pre-formatted output. """ # Create a dummy screen. screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) scene = MagicMock(spec=Scene) canvas = Canvas(screen, 10, 40, 0, 0) # Create the form we want to test. form = Frame(canvas, canvas.height, canvas.width, has_border=False) layout = Layout([100], fill_frame=True) form.add_layout(layout) text_box = TextBox(1, as_string=True) text_box.disabled = True layout.add_widget(text_box) form.fix() form.register_scene(scene) form.reset() # Check that input has no effect on the programmed value. text_box.value = "A test" self.process_keys(form, ["A"]) form.save() self.assertEqual(text_box.value, "A test") # Check that we can provide a custom colour. Since the default palette has no "custom" # key, this will throw an exception. self.assertEqual(text_box._pick_colours("blah"), form.palette["disabled"]) with self.assertRaises(KeyError) as cm: text_box.custom_colour = "custom" text_box._pick_colours("blah") self.assertIn("custom", str(cm.exception))
def test_cjk_forms(self): """ Check form widgets work with CJK characters. """ # Create a dummy screen. screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) scene = MagicMock(spec=Scene) canvas = Canvas(screen, 10, 40, 0, 0) # Create the form we want to test. form = Frame(canvas, canvas.height, canvas.width, has_border=False) layout = Layout([100], fill_frame=True) mc_list = MultiColumnListBox(4, [3, 5, 0], [ (["1", "2", "3"], 1), ([u"你", u"確", u"定"], 2), ], titles=[u"你確定嗎?", u"你確定嗎?", u"你確定嗎?"]) text = Text() text_box = TextBox(3) form.add_layout(layout) layout.add_widget(mc_list) layout.add_widget(text) layout.add_widget(text_box) form.fix() form.register_scene(scene) form.reset() # Set some interesting values... text.value = u"你確定嗎? 你確定嗎? 你確定嗎?" text_box.value = [u"你確定嗎", u"?"] # Check that the CJK characters render correctly - no really this is correctly aligned! self.maxDiff = None form.update(0) self.assert_canvas_equals( canvas, u"你你 你你確確 你你確確定定嗎嗎?? \n" + u"1 2 3 \n" + u"你你 確確 定定 \n" + u" \n" + u"你你確確定定嗎嗎?? 你你確確定定嗎嗎?? 你你確確定定嗎嗎?? \n" + u"你你確確定定嗎嗎 \n" + u"?? \n" + u" \n" + u" \n" + u" \n") # Check that mouse input takes into account the glyph width self.process_mouse(form, [(5, 4, MouseEvent.LEFT_CLICK)]) self.process_keys(form, ["b"]) self.process_mouse(form, [(2, 4, MouseEvent.LEFT_CLICK)]) self.process_keys(form, ["p"]) form.save() self.assertEqual(text.value, u"你p確b定嗎? 你確定嗎? 你確定嗎?") self.process_mouse(form, [(2, 5, MouseEvent.LEFT_CLICK)]) self.process_keys(form, ["p"]) self.process_mouse(form, [(1, 6, MouseEvent.LEFT_CLICK)]) self.process_keys(form, ["b"]) form.save() self.assertEqual(text_box.value, [u"你p確定嗎", u"b?"])
def __init__(self): self.loop = asyncio.get_event_loop() self.screen = Screen.open() self.effects = [] frame = Frame(self.screen, 80, 20, has_border=False) layout = Layout([1, 1, 1, 1]) frame.add_layout(layout) end_time = self.loop.time() + 5.0 self.loop.call_soon(self.update_screen, end_time, self.loop, self.screen) self.screen.set_scenes([Scene(frame,500)]) self.screen.set_title()
def DeathMenu(game, screen, debug, oldpalette): None def endgame(): screen.close() quit() sys.exit(0) None def Restart(): game = GameState.GameState() MainMenu(game, screen, debug, oldpalette) None Dmenu = Frame(screen, screen.height * 2 // 3, screen.width * 2 // 3, hover_focus=True, has_border=True, title="YOU HAVE DIED", reduce_cpu=False) mapping = Layout([100], fill_frame=True) for entry in Dmenu.palette: if entry != "focus_button": Dmenu.palette[entry] = (1, 1, 1) else: Dmenu.palette[entry] = (0, 1, 5) Dmenu.add_layout(mapping) mapping.add_widget( Label(str("Your Final Score Is: " + str(game.score)), 1)) bottomrow = Layout([1, 1, 1, 1]) Dmenu.add_layout(bottomrow) bottomrow.add_widget(Button("Exit", endgame), 1) bottomrow.add_widget(Button("Restart", Restart), 3) Dmenu.fix() #return Mmenu #Mmenu._on_pic Scenes = [Scene([Dmenu], -1)] screen.play(Scenes) return Dmenu.data
def demo(screen): scenes = [] frame = Frame(screen, 20, 80, can_scroll=False, title="Sender") layout = Layout([40, 10, 40, 10], fill_frame=True) frame.add_layout(layout) optionen = [("Erster", 1), ("Zweiter", 2)] sender = ["Erster hihihihihihi", "Zweiter", "Dritter"] for s in sender: layout.add_widget(Label(s, align=u'^')) layout.add_widget(Label("<<<<", align='<'), 1) layout.add_widget(Button("hihi!", None)) frame.fix() effects = [frame] scenes.append(Scene(effects, -1)) screen.play(scenes)
def demo(screen, scene): frame = Frame(screen, screen.height // 3, screen.width // 3, hover_focus=True, has_border=False, title="Main Menu") frame.palette = palette layout3 = Layout([100]) frame.add_layout(layout3) layout3.add_widget(Label("Test"), 0) layout3.add_widget(Divider(draw_line=False)) layout1 = Layout([100], fill_frame=True) frame.add_layout(layout1) layout1.add_widget( ListBox(Widget.FILL_FRAME, [("One", 1), ("Two", 3), ("Three", 2), ("Four", 4), ("Five", 5), ("Six", 6), ("Seven", 7), ("Eight", 8), ("Nine", 9), ("Ten", 10), ("Eleven", 11), ("Twelve", 12), ("Thirteen", 13), ("Fourteen", 14), ("Fifteen", 15), ("Sixteen", 16), ("Seventeen", 17), ("Eighteen", 18), ("Nineteen", 19), ("Twenty", 20), ("Loop", 1)], name="List Thing")) layout1.add_widget(Divider(draw_line=False)) layout2 = Layout([1, 1, 1, 1]) frame.add_layout(layout2) layout2.add_widget(Button("OK", leave), 1) layout2.add_widget(Button("Cancel", leave), 2) frame.fix() scenes = [Scene([frame], -1, name="Test")] screen.play(scenes, stop_on_resize=True, start_scene=scene)
class TextUi(MpfController): """Handles the text-based UI.""" config_name = "text_ui" __slots__ = [ "start_time", "machine", "_tick_task", "screen", "mpf_process", "ball_devices", "switches", "config", "_pending_bcp_connection", "_asset_percent", "_player_widgets", "_machine_widgets", "_bcp_status", "frame", "layout", "scene", "footer_memory", "switch_widgets", "mode_widgets", "ball_device_widgets", "footer_cpu", "footer_mc_cpu", "footer_uptime", "delay", "_layout_change" ] def __init__(self, machine: "MachineController") -> None: """Initialize TextUi.""" super().__init__(machine) self.delay = DelayManager(machine) self.config = machine.config.get('text_ui', {}) self.screen = None if not machine.options['text_ui'] or not Scene: return # hack to add themes until https://github.com/peterbrittain/asciimatics/issues/207 is implemented THEMES["mpf_theme"] = defaultdict( lambda: (Screen.COLOUR_WHITE, Screen.A_NORMAL, Screen.COLOUR_BLACK), { "active_switch": (Screen.COLOUR_BLACK, Screen.A_NORMAL, Screen.COLOUR_GREEN), "pf_active": (Screen.COLOUR_GREEN, Screen.A_NORMAL, Screen.COLOUR_BLACK), "pf_inactive": (Screen.COLOUR_WHITE, Screen.A_NORMAL, Screen.COLOUR_BLACK), "label": (Screen.COLOUR_WHITE, Screen.A_NORMAL, Screen.COLOUR_BLACK), "title": (Screen.COLOUR_WHITE, Screen.A_NORMAL, Screen.COLOUR_RED), "title_exit": (Screen.COLOUR_BLACK, Screen.A_NORMAL, Screen.COLOUR_RED), "footer_cpu": (Screen.COLOUR_CYAN, Screen.A_NORMAL, Screen.COLOUR_BLACK), "footer_path": (Screen.COLOUR_YELLOW, Screen.A_NORMAL, Screen.COLOUR_BLACK), "footer_memory": (Screen.COLOUR_GREEN, Screen.A_NORMAL, Screen.COLOUR_BLACK), "footer_mc_cpu": (Screen.COLOUR_MAGENTA, Screen.A_NORMAL, Screen.COLOUR_BLACK), }) self.start_time = datetime.now() self.machine = machine self.mpf_process = Process() self.ball_devices = list() # type: List[BallDevice] self.switches = {} # type: Dict[str, Switch] self.machine.events.add_handler('init_phase_2', self._init) # self.machine.events.add_handler('init_phase_3', self._init2) self.machine.events.add_handler('loading_assets', self._asset_load_change) self.machine.events.add_handler('bcp_connection_attempt', self._bcp_connection_attempt) self.machine.events.add_handler('asset_loading_complete', self._asset_load_complete) self.machine.events.add_handler('bcp_clients_connected', self._bcp_connected) self.machine.events.add_handler('shutdown', self.stop) self.machine.add_crash_handler(self.stop) self.machine.events.add_handler('player_number', self._update_player) self.machine.events.add_handler('player_ball', self._update_player) self.machine.events.add_handler('player_score', self._update_player) self.machine.events.add_handler('ball_ended', self._update_player) self._pending_bcp_connection = False self._asset_percent = 0 self._bcp_status = (0, 0, 0) # type: Tuple[float, int, int] self.switch_widgets = [] # type: List[Widget] self.mode_widgets = [] # type: List[Widget] self.ball_device_widgets = [] # type: List[Widget] self._machine_widgets = [] # type: List[Widget] self._player_widgets = [] # type: List[Widget] self.footer_memory = None self.footer_cpu = None self.footer_mc_cpu = None self.footer_uptime = None self._layout_change = True self._tick_task = self.machine.clock.schedule_interval(self._tick, 1) self._create_window() self._draw_screen() def _init(self, **kwargs): del kwargs for mode in self.machine.modes.values(): self.machine.events.add_handler( "mode_{}_started".format(mode.name), self._mode_change) self.machine.events.add_handler( "mode_{}_stopped".format(mode.name), self._mode_change) self.machine.switch_controller.add_monitor(self._update_switches) self.machine.register_monitor("machine_vars", self._update_machine_vars) self.machine.variables.machine_var_monitor = True self.machine.bcp.interface.register_command_callback( "status_report", self._bcp_status_report) for bd in [ x for x in self.machine.ball_devices.values() if not x.is_playfield() ]: self.ball_devices.append(bd) self.ball_devices.sort() self._update_switch_layout() self._schedule_draw_screen() async def _bcp_status_report(self, client, cpu, rss, vms): del client self._bcp_status = cpu, rss, vms def _update_stats(self): # Runtime rt = (datetime.now() - self.start_time) mins, sec = divmod(rt.seconds + rt.days * 86400, 60) hours, mins = divmod(mins, 60) self.footer_uptime.text = 'RUNNING {:d}:{:02d}:{:02d}'.format( hours, mins, sec) # System Stats self.footer_memory.text = 'Free Memory (MB): {} CPU:{:3d}%'.format( round(virtual_memory().available / 1048576), round(cpu_percent(interval=None, percpu=False))) # MPF process stats self.footer_cpu.text = 'MPF (CPU RSS/VMS): {}% {}/{} MB '.format( round(self.mpf_process.cpu_percent()), round(self.mpf_process.memory_info().rss / 1048576), round(self.mpf_process.memory_info().vms / 1048576)) # MC process stats if self._bcp_status != (0, 0, 0): self.footer_mc_cpu.text = 'MC (CPU RSS/VMS) {}% {}/{} MB '.format( round(self._bcp_status[0]), round(self._bcp_status[1] / 1048576), round(self._bcp_status[2] / 1048576)) else: self.footer_mc_cpu.text = "" def _update_switch_layout(self): num = 0 self.switch_widgets = [] self.switches = {} self.switch_widgets.append((Label("SWITCHES"), 1)) self.switch_widgets.append((Divider(), 1)) self.switch_widgets.append((Label(""), 2)) self.switch_widgets.append((Divider(), 2)) for sw in sorted(self.machine.switches.values()): if sw.invert: name = sw.name + '*' else: name = sw.name col = 1 if num <= int(len(self.machine.switches) / 2) else 2 switch_widget = Label(name) if sw.state: switch_widget.custom_colour = "active_switch" self.switch_widgets.append((switch_widget, col)) self.switches[sw.name] = (sw, switch_widget) num += 1 self._schedule_draw_screen() def _update_switches(self, change, *args, **kwargs): del args del kwargs try: sw, switch_widget = self.switches[change.name] except KeyError: return if sw.state: switch_widget.custom_colour = "active_switch" else: switch_widget.custom_colour = "label" self._schedule_draw_screen() def _draw_switches(self): """Draw all switches.""" for widget, column in self.switch_widgets: self.layout.add_widget(widget, column) def _mode_change(self, *args, **kwargs): # Have to call this on the next frame since the mode controller's # active list isn't updated yet del args del kwargs self.mode_widgets = [] self.mode_widgets.append(Label("ACTIVE MODES")) self.mode_widgets.append(Divider()) try: modes = self.machine.mode_controller.active_modes except AttributeError: modes = None if modes: for mode in modes: self.mode_widgets.append( Label('{} ({})'.format(mode.name, mode.priority))) else: self.mode_widgets.append(Label("No active modes")) # empty line at the end self.mode_widgets.append(Label("")) self._layout_change = True self._schedule_draw_screen() def _draw_modes(self): for widget in self.mode_widgets: self.layout.add_widget(widget, 0) def _draw_ball_devices(self): for widget in self.ball_device_widgets: self.layout.add_widget(widget, 3) def _update_ball_devices(self, **kwargs): del kwargs # TODO: do not create widgets. just update contents self.ball_device_widgets = [] self.ball_device_widgets.append(Label("BALL COUNTS")) self.ball_device_widgets.append(Divider()) try: for pf in self.machine.playfields.values(): widget = Label('{}: {} '.format(pf.name, pf.balls)) if pf.balls: widget.custom_colour = "pf_active" else: widget.custom_colour = "pf_inactive" self.ball_device_widgets.append(widget) except AttributeError: pass for bd in self.ball_devices: widget = Label('{}: {} ({})'.format(bd.name, bd.balls, bd.state)) if bd.balls: widget.custom_colour = "pf_active" else: widget.custom_colour = "pf_inactive" self.ball_device_widgets.append(widget) self.ball_device_widgets.append(Label("")) self._layout_change = True self._schedule_draw_screen() def _update_player(self, **kwargs): del kwargs self._player_widgets = [] self._player_widgets.append(Label("CURRENT PLAYER")) self._player_widgets.append(Divider()) try: player = self.machine.game.player self._player_widgets.append( Label('PLAYER: {}'.format(player.number))) self._player_widgets.append(Label('BALL: {}'.format(player.ball))) self._player_widgets.append( Label('SCORE: {:,}'.format(player.score))) except AttributeError: self._player_widgets.append(Label("NO GAME IN PROGRESS")) return player_vars = player.vars.copy() player_vars.pop('score', None) player_vars.pop('number', None) player_vars.pop('ball', None) names = self.config.get('player_vars', player_vars.keys()) for name in names: self._player_widgets.append( Label("{}: {}".format(name, player_vars[name]))) self._layout_change = True self._schedule_draw_screen() def _draw_player(self, **kwargs): del kwargs for widget in self._player_widgets: self.layout.add_widget(widget, 3) def _update_machine_vars(self, **kwargs): """Update machine vars.""" del kwargs self._machine_widgets = [] self._machine_widgets.append(Label("MACHINE VARIABLES")) self._machine_widgets.append(Divider()) machine_vars = self.machine.variables.machine_vars # If config defines explict vars to show, only show those. Otherwise, all names = self.config.get('machine_vars', machine_vars.keys()) for name in names: self._machine_widgets.append( Label("{}: {}".format(name, machine_vars[name]['value']))) self._layout_change = True self._schedule_draw_screen() def _draw_machine_variables(self): """Draw machine vars.""" for widget in self._machine_widgets: self.layout.add_widget(widget, 0) def _create_window(self): self.screen = Screen.open() self.frame = Frame(self.screen, self.screen.height, self.screen.width, has_border=False, title="Test") self.frame.set_theme("mpf_theme") title_layout = Layout([1, 5, 1]) self.frame.add_layout(title_layout) title_left = Label("") title_left.custom_colour = "title" title_layout.add_widget(title_left, 0) title = 'Mission Pinball Framework v{}'.format( mpf._version.__version__) # noqa title_text = Label(title, align="^") title_text.custom_colour = "title" title_layout.add_widget(title_text, 1) exit_label = Label("< CTRL + C > TO EXIT", align=">") exit_label.custom_colour = "title_exit" title_layout.add_widget(exit_label, 2) self.layout = MpfLayout([1, 1, 1, 1], fill_frame=True) self.frame.add_layout(self.layout) footer_layout = Layout([1, 1, 1]) self.frame.add_layout(footer_layout) self.footer_memory = Label("", align=">") self.footer_memory.custom_colour = "footer_memory" self.footer_uptime = Label("", align=">") self.footer_uptime.custom_colour = "footer_memory" self.footer_mc_cpu = Label("") self.footer_mc_cpu.custom_colour = "footer_mc_cpu" self.footer_cpu = Label("") self.footer_cpu.custom_colour = "footer_cpu" footer_path = Label(self.machine.machine_path) footer_path.custom_colour = "footer_path" footer_empty = Label("") footer_empty.custom_colour = "footer_memory" footer_layout.add_widget(footer_path, 0) footer_layout.add_widget(self.footer_cpu, 0) footer_layout.add_widget(footer_empty, 1) footer_layout.add_widget(self.footer_mc_cpu, 1) footer_layout.add_widget(self.footer_uptime, 2) footer_layout.add_widget(self.footer_memory, 2) self.scene = Scene([self.frame], -1) self.screen.set_scenes([self.scene], start_scene=self.scene) # prevent main from scrolling out the footer self.layout.set_max_height(self.screen.height - 2) def _schedule_draw_screen(self): # schedule the draw in 10ms if it is not scheduled self.delay.add_if_doesnt_exist(10, self._draw_screen, "draw_screen") def _draw_screen(self): if not self.screen: # probably drawing during game end return if self._layout_change: self.layout.clear_columns() self._draw_modes() self._draw_machine_variables() self._draw_switches() self._draw_ball_devices() self._draw_player() self.frame.fix() self._layout_change = False self.screen.force_update() self.screen.draw_next_frame() def _tick(self): if self.screen.has_resized(): self._create_window() self._update_ball_devices() self._update_stats() self._schedule_draw_screen() self.machine.bcp.transport.send_to_clients_with_handler( handler="_status_request", bcp_command="status_request") def _bcp_connection_attempt(self, name, host, port, **kwargs): del name del kwargs self._pending_bcp_connection = PopUpDialog( self.screen, 'WAITING FOR MEDIA CONTROLLER {}:{}'.format(host, port), []) self.scene.add_effect(self._pending_bcp_connection) self._schedule_draw_screen() def _bcp_connected(self, **kwargs): del kwargs self.scene.remove_effect(self._pending_bcp_connection) self._schedule_draw_screen() def _asset_load_change(self, percent, **kwargs): del kwargs if self._asset_percent: self.scene.remove_effect(self._asset_percent) self._asset_percent = PopUpDialog( self.screen, 'LOADING ASSETS: {}%'.format(percent), []) self.scene.add_effect(self._asset_percent) self._schedule_draw_screen() def _asset_load_complete(self, **kwargs): del kwargs self.scene.remove_effect(self._asset_percent) self._schedule_draw_screen() def stop(self, **kwargs): """Stop the Text UI and restore the original console screen.""" del kwargs if self.screen: self.machine.clock.unschedule(self._tick_task) self.screen.close(True) self.screen = None
def MainMenu(game, screen, debug, oldpalette): def endgame(): screen.close() quit() sys.exit(0) None def endmenu(): debug[0] = False game = GameState.GameState() game.hero.inventory = [] Mmenu.save() looksy = Mmenu.data if looksy['seedval'] != "": converted = 0 if str.isnumeric(looksy['seedval']): game.seed = int(looksy['seedval']) else: for char in looksy['seedval']: converted += ord(char) game.seed = int(converted) random.seed(game.seed) if looksy['nameval'] != "": if len(looksy["nameval"]) >= 20: game.name = str(looksy['nameval'])[:21] else: game.name = str(looksy['nameval']) debug[0] = looksy['Debug'] #visual.blackout(screen) main(game, debug, looksy, screen) test1.deadscreen(game, screen) DeathMenu(game, screen, debug, oldpalette) return Mmenu.data endval = True Mmenu = Frame(screen, screen.height * 2 // 3, screen.width * 2 // 3, hover_focus=True, has_border=True, title="Game Settings", reduce_cpu=False) #Mmenu.palette['background'] = (0,0,1) Mmenu.palette = oldpalette mapping = Layout([100], fill_frame=True) Mmenu.add_layout(mapping) mapping.add_widget(Text("Seed:", "seedval")) mapping.add_widget(Text("Adventurer Name:", "nameval")) mapping.add_widget(CheckBox("Debug Mode:", "Debug", "Debug")) bottomrow = Layout([1, 1, 1, 1]) Mmenu.add_layout(bottomrow) bottomrow.add_widget(Button("Exit Game", endgame), 0) bottomrow.add_widget(Button("Start Level", endmenu), 3) Mmenu.fix() #Mmenu._on_pic Scenes = [Scene([Mmenu], -1)] screen.play(Scenes) return Mmenu.data
def test_multi_column_list_box(self): """ Check MultiColumnListBox works as expected. """ # Create a dummy screen. screen = MagicMock(spec=Screen, colours=8, unicode_aware=False) scene = MagicMock(spec=Scene) canvas = Canvas(screen, 10, 40, 0, 0) # Create the form we want to test. form = Frame(canvas, canvas.height, canvas.width, has_border=False) layout = Layout([100], fill_frame=True) mc_list = MultiColumnListBox( Widget.FILL_FRAME, [3, "4", ">4", "<4", ">10%", "100%"], [ (["1", "2", "3", "4", "5", "6"], 1), (["11", "222", "333", "444", "555", "6"], 2), (["111", "2", "3", "4", "5", "6"], 3), (["1", "2", "33333", "4", "5", "6"], 4), (["1", "2", "3", "4", "5", "6666666666666666666666"], 5), ], titles=["A", "B", "C", "D", "E", "F"], name="mc_list") form.add_layout(layout) layout.add_widget(mc_list) form.fix() form.register_scene(scene) form.reset() # Check we have a default value for our list. form.save() self.assertEqual(form.data, {"mc_list": 1}) # Check that UP/DOWN change selection. self.process_keys(form, [Screen.KEY_DOWN]) form.save() self.assertEqual(form.data, {"mc_list": 2}) self.process_keys(form, [Screen.KEY_UP]) form.save() self.assertEqual(form.data, {"mc_list": 1}) # Check that PGUP/PGDN change selection. self.process_keys(form, [Screen.KEY_PAGE_DOWN]) form.save() self.assertEqual(form.data, {"mc_list": 5}) self.process_keys(form, [Screen.KEY_PAGE_UP]) form.save() self.assertEqual(form.data, {"mc_list": 1}) # Check that the widget is rendered correctly. form.update(0) self.assert_canvas_equals( canvas, "A B C D E F \n" + "1 2 3 4 5 6 \n" + "11 222 333 444 555 6 \n" + "...2 3 4 5 6 \n" + "1 2 3... 4 5 6 \n" + "1 2 3 4 5 6666666666666666666\n" + " \n" + " \n" + " \n" + " \n") # Check that mouse input changes selection. self.process_mouse(form, [(2, 2, MouseEvent.LEFT_CLICK)]) form.save() self.assertEqual(form.data, {"mc_list": 2}) self.process_mouse(form, [(2, 1, MouseEvent.LEFT_CLICK)]) form.save() self.assertEqual(form.data, {"mc_list": 1}) # Check that the start_line can be read and set - and enforces good behaviour mc_list.start_line = 0 self.assertEqual(mc_list.start_line, 0) mc_list.start_line = len(mc_list.options) - 1 self.assertEqual(mc_list.start_line, len(mc_list.options) - 1) mc_list.start_line = 10000000 self.assertEqual(mc_list.start_line, len(mc_list.options) - 1) # Check that options can be read and set. mc_list.options = [(["a", "b", "c", "d", "e", "f"], 0)] self.assertEqual(mc_list.options, [(["a", "b", "c", "d", "e", "f"], 0)]) mc_list.options = [] self.assertEqual(mc_list.options, []) # Check that the form re-renders correctly afterwards. form.update(1) self.assert_canvas_equals( canvas, "A B C D E F \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n") # Check that the current focus ignores unknown events. event = object() self.assertEqual(event, form.process_event(event))
class ASCII(): def __init__(self): self.screen = Screen.open() self.scenes = [] self.akt_sender_str = "Deutschlandradio" self.akt_sender_nr = 0 self.volume = 25 self.number_of_stations = 0 # Prepare frame for the presets self.preset_frame = Frame(self.screen, 7, 29, can_scroll=False, title="Tastenbelegung", x=0, y=10, reduce_cpu=True) self.pr_layout = Layout([10, 90], fill_frame=True) self.preset_frame.add_layout(self.pr_layout) # Prepare frame for the sender list self.sender_frame = Frame(self.screen, 17, 50, can_scroll=False, title="Senderliste", x=30, y=0, reduce_cpu=True) self.sender_layout0 = Layout([10, 80, 10], fill_frame=True) self.sender_frame.add_layout(self.sender_layout0) # Load the json config-file self.cfg = self.load_config() # Prepare the layouts, add spaces etc self.format_sl_layout(self.sender_layout0) # Nicht mehr nötig nach aktuellem Stand # format_pr_layout(pr_layout) # Create the sender-labels and fill them initially. Return them for # later changing self.sender_labels = self.gen_and_add_sender_labels( self.sender_layout0, self.parse_sender()) self.preset_labels = self.gen_and_add_preset_labels( self.pr_layout, self.parse_presets()) self.preset_frame.fix() self.sender_frame.fix() def load_config(self): if STANDARD_CONFIG.exists(): with STANDARD_CONFIG.open() as f: konfig = json.load(f) print("Nutzer-Config geladen.") elif NOTFALL_CONFIG.exists(): with NOTFALL_CONFIG.open() as f: konfig = json.load(f) print("Notfall-Config geladen") else: print("Katastrophaler Fehler: Keine Config-Dateien. Beende...") sys.exit(1) self.number_of_stations = len(konfig["senderliste"]) return konfig # Krall Dir anhand des aktuellen Senderindizes die 6 Sendernamen vor und nach # dem gewählten Sender def parse_sender(self): namen = [] j = 1 for i in range(1, DISPLAY_SENDER_SYMM + 1): if self.akt_sender_nr - i >= 0: namen.append(self.cfg["senderliste"][self.akt_sender_nr - i]["sendername"]) else: index = self.number_of_stations - j namen.append(self.cfg["senderliste"][index]["sendername"]) j += 1 namen.reverse() for i in range(0, DISPLAY_SENDER_SYMM + 1): namen.append( self.cfg["senderliste"][(self.akt_sender_nr + i) % self.number_of_stations]["sendername"]) for d in namen: debug.write(d) return namen # Hole die fünf Presets aus der Config. Setze Presets mit -1 auf den der # unbelegten Taste entsprechenden Index in der Senderliste def parse_presets(self): namen = [] for n, i in zip(self.cfg["presetliste"], range(0, 5)): if n >= 0: namen.append(self.cfg["senderliste"][n]["sendername"]) else: namen.append(self.cfg["senderliste"][i]["sendername"]) debug.write(str(i)) return namen def format_sl_layout(self, layout): layout.add_widget(Divider(False, 7), 0) layout.add_widget(Label('>>>', 1, align='<'), 0) layout.add_widget(Divider(False, 7), 2) layout.add_widget(Label('<<<', 1, align='>'), 2) # Fülle die Senderliste initial und gib die Label für die spätere Verarbeitung # zurück. Die Divider bleiben als Abstandshalter dauerhaft im Layout. def gen_and_add_sender_labels(self, layout, namen): labs = [] for name in namen: labs.append(Label(name, 1)) # Add first 6 stations for l in labs[:DISPLAY_SENDER_SYMM]: layout.add_widget(l, 1) # Add spaces and the central station (hehe, got it?) layout.add_widget(Divider(False, 1), 1) layout.add_widget(labs[DISPLAY_SENDER_SYMM], 1) layout.add_widget(Divider(False, 1), 1) # Add the rest of the stations for l in labs[DISPLAY_SENDER_SYMM + 1:]: layout.add_widget(l, 1) return labs # Füge die Spaltennummern der Presets hinzu, außerdem fülle die Presets initial # und gib die Liste mit den Presetlabels für die spätere Verarbeitung zurück def gen_and_add_preset_labels(self, layout, namen): preset_labs = [] # Presetnamen einfügen in Spalte 1 for name in namen: preset_labs.append(Label(name, 1)) debug.write(name) for l in preset_labs: layout.add_widget(l, 1) # Spaltennummern der Presets einfügen in Spalte 0 for i in range(1, 6): layout.add_widget(Label(str(i), 1), 0) return preset_labs def update_sender_labels(self): namen = self.parse_sender() for l, n in zip(self.sender_labels, namen): l.text = n def update_preset_labels(self): namen = parse_presets() for l, n in zip(self.sender_labels, namen): l.text = n def get_vol(self): return self.volume # muhahahahhahahahahaaaa! def asciisierer(self, s): tabelle = { ord('ä'): 'ae', ord('ö'): 'oe', ord('ü'): 'ue', ord('ß'): 'ss', ord('Ä'): 'AE', ord('Ö'): 'OE', ord('Ü'): 'UE', ord('ẞ'): 'SS', } return s.translate(tabelle) # Fill the display with the desired effects and draw the first frame def prepare_display(self): # Effects are all the stuff which will be shown on the display # Speed 0 means: Redraw only when draw_next_frame is executed effects = [ self.preset_frame, self.sender_frame, Print(self.screen, Box(80, 8, True), x=0, y=17, speed=0), Print(self.screen, ColourImageFile(self.screen, LOGO, 9, bg=7), x=0, y=0, speed=0), Print(self.screen, FigletText(self.asciisierer(self.akt_sender_str)), x=1, y=18, speed=0), Print(self.screen, BarChart(4, 80, [self.get_vol], colour=2, char=' ', bg=7, scale=100, axes=BarChart.X_AXIS, intervals=25, labels=True, border=False), x=0, y=26, transparent=False, speed=0) ] # Start displaying self.scenes.append(Scene(effects, -1)) self.screen.set_scenes(self.scenes) # Update the screen for the first time self.screen.draw_next_frame()
def demo(screen): scenes = [] preset_frame = Frame(screen, 11, 26, can_scroll=False, title="Tastenbelegung", x=SF_X, y=SF_Y, reduce_cpu=True) pr_layout = Layout([10, 90], fill_frame=True) preset_frame.add_layout(pr_layout) sender_frame = Frame(screen, 11, 26, can_scroll=False, title="Senderliste", x=27, y=6, reduce_cpu=True) sender_layout0 = Layout([10, 90, 10], fill_frame=True) sender_frame.add_layout(sender_layout0) optionen = [(" ", 1), ("Zweiter", 2), ("Dritter", 3), ("Vierter", 4), ("Deutschlandradio", 5), ("Absolut Relax", 6), ("Siebter", 7), ("hmm", 8)] sender = [ "123456789012345678901", "Erster", "Zweiter", "Dritter", "Vierter", "Fünfter", "Sechster" ] Senderkiste = ListBox(8, optionen, False) sender_layout0.add_widget(Senderkiste, 1) Senderkiste.blur() Senderkiste.start_line = 1 format_sl_layout(sender_layout0) # format_pr_layout(pr_layout) for i, s in zip(range(1, 6), sender): pr_layout.add_widget(Label(str(i), 1, align=u'^')) pr_layout.add_widget(Label(s, 1, align='^'), 1) preset_frame.fix() sender_frame.fix() effects = [ preset_frame, sender_frame, Print(screen, Box(26, 15, True), x=UHR_K_X, y=UHR_K_Y), Print(screen, Box(80, 8, True), x=0, y=17), Clock(screen, 67, 7, 6), Print(screen, FigletText("Retroradio!"), x=0, y=0), # Print(screen, BarChart(4, 80, [get_vol], colour=2, scale=100, # axes=BarChart.X_AXIS, intervals=25, labels=True, border=False), x=0, y=26, # transparent=False), # Print(screen, SpeechBubble("Lautstärke"), x=0, y=23), Print(screen, FigletText("Deutschlandradio"), x=1, y=18), Print(screen, BarChart(4, 80, [get_vol], colour=2, char=' ', bg=7, scale=100, axes=BarChart.X_AXIS, intervals=25, labels=True, border=False), x=0, y=26, transparent=False, speed=2) ] scenes.append(Scene(effects, -1)) screen.play(scenes)
def run_display(screen): scenes = [] AKT_SENDER = "Retro rockt!" # Prepare frame for the presets preset_frame = Frame(screen, 7, 29, can_scroll=False, title="Tastenbelegung", x=0, y=10, reduce_cpu=True) pr_layout = Layout([10, 90], fill_frame=True) preset_frame.add_layout(pr_layout) # Prepare frame for the sender list sender_frame = Frame(screen, 17, 50, can_scroll=False, title="Senderliste", x=30, y=0, reduce_cpu=True) sender_layout0 = Layout([10, 80, 10], fill_frame=True) sender_frame.add_layout(sender_layout0) # Load the json config-file cfg = load_config() # Prepare the layouts, add spaces etc format_sl_layout(sender_layout0) # Nicht mehr nötig nach aktuellem Stand # format_pr_layout(pr_layout) # Create the sender-labels and fill them initially. Return them for # later changing sender_labels = gen_and_add_sender_labels(sender_layout0, parse_sender(cfg, 0)) preset_labels = gen_and_add_preset_labels(pr_layout, parse_presets(cfg)) preset_frame.fix() sender_frame.fix() # Effects are all the stuff which will be shown on the display effects = [ preset_frame, sender_frame, # Print(screen, Box(26, 15, True), x=54, y=0), Print(screen, Box(80, 8, True), x=0, y=17, speed=2), # Clock(screen, 68, 7, 5), Print(screen, ColourImageFile(screen, LOGO, 9, bg=7), x=0, y=0, speed=2), Print(screen, FigletText(asciisierer(AKT_SENDER)), x=1, y=18), Print(screen, BarChart(4, 80, [get_vol], colour=2, char=' ', bg=7, scale=100, axes=BarChart.X_AXIS, intervals=25, labels=True, border=False), x=0, y=26, transparent=False, speed=2) ] # Start displaying scenes.append(Scene(effects, -1)) screen.play(scenes)
def compose_on_frame(cls, frame: Frame, *args, **kwargs): layouts = cls.build_layouts() for layout in layouts: frame.add_layout(layout) cls.compose_on_layouts(layouts, *args, **kwargs)