Instantly share code, notes, and snippets.
Created
January 5, 2021 14:57
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save MaxBarraclough/1d2a17f5683b6449d29ba4ea464ff946 to your computer and use it in GitHub Desktop.
asciimatics_button_bug_demo.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
## This simple application demonstrates a bug in | |
## the mouse-click handling for buttons, in asciimatics: | |
## mouse-clicks on the right side of buttons, fail to register. | |
## It seems especially evident in buttons with short label strings. | |
## Dependency: | |
## pip install asciimatics | |
## Loosely based on the quick_model.py example script. | |
## See also the similar contact_list.py example script (which uses sqlite). | |
## asciimatics toolkit tutorial: | |
## https://asciimatics.readthedocs.io/en/stable/widgets.html | |
from asciimatics.widgets import Frame, ListBox, Layout, Divider, Text, \ | |
Button, TextBox, Widget | |
from asciimatics.scene import Scene | |
from asciimatics.screen import Screen | |
from asciimatics.exceptions import ResizeScreenError, NextScene, StopApplication | |
from asciimatics.event import KeyboardEvent | |
import sys | |
## We don't use a proper model, just a placeholder | |
class DemoModel(object): | |
def __init__(self): | |
pass | |
class DemoView(Frame): | |
def __init__(self, screen, model): | |
super(DemoView, self).__init__(screen, | |
screen.height * 2 // 3, | |
screen.width * 2 // 3, | |
hover_focus=True, | |
can_scroll=False, | |
title="Demo Application") | |
# reduce_cpu=True) | |
self._model = model ## Placeholder model object | |
## Create the form | |
layout = Layout([100], fill_frame=True) # single column occupying 100% of available width | |
self.add_layout(layout) | |
layout.add_widget(Button("Overwrite text in text box (1)", self._button1_clicked)) | |
layout.add_widget(Button("Overwrite text in text box (2)", self._button2_clicked)) | |
## Clicking on the right side of this button doesn't work | |
layout.add_widget(Button("Short one", self._shortButton_clicked)) | |
layout.add_widget(Button("Overwrite text in text box (3)", self._button3_clicked)) | |
layout.add_widget(Button("Overwrite text in text box (4)", self._button4_clicked)) | |
layout.add_widget(Button("Click here to exit", self._quit)) | |
self.text_widget = Text(label="Status", name="status_text", readonly=True) | |
self.text_widget.value = "[ Ready ]" | |
layout.add_widget(self.text_widget) | |
self.fix() | |
def _button1_clicked(self): | |
self.text_widget.value = "BUTTON 1 CLICKED" | |
return | |
def _button2_clicked(self): | |
self.text_widget.value = "BUTTON 2 CLICKED" | |
return | |
def _shortButton_clicked(self): | |
self.text_widget.value = "SHORT BUTTON CLICKED" | |
return | |
def _button3_clicked(self): | |
self.text_widget.value = "BUTTON 3 CLICKED" | |
return | |
def _button4_clicked(self): | |
self.text_widget.value = "BUTTON 4 CLICKED" | |
return | |
@staticmethod | |
def _quit(): | |
exit(0) | |
# raise StopApplication("User pressed quit") | |
def process_event(self, event): | |
# Allow standard event processing first | |
if super(DemoView, self).process_event(event) is None: | |
return | |
# If that didn't handle it, check for a key that this demo understands. | |
if isinstance(event, KeyboardEvent): | |
c = event.key_code | |
if c in (ord("q"), ord("Q")): | |
raise StopApplication("User exit") | |
else: | |
# Not a recognised key - pass on to other handlers. | |
return event | |
else: | |
# Ignore other types of events. | |
return event | |
the_model = DemoModel() | |
def demo(screen, scene): | |
scenes = [ | |
Scene([DemoView(screen, the_model)], -1, name="Demo") | |
] | |
screen.play(scenes, stop_on_resize=True, start_scene=scene, allow_int=True) | |
last_scene = None | |
while True: | |
try: | |
Screen.wrapper(demo, catch_interrupt=True, arguments=[last_scene]) | |
sys.exit(0) | |
except ResizeScreenError as e: | |
last_scene = e.scene | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment