better
This commit is contained in:
parent
aa782f3080
commit
d32b83f790
2 changed files with 67 additions and 23 deletions
|
|
@ -22,7 +22,7 @@ import pygame
|
|||
shutdown_event = threading.Event()
|
||||
|
||||
# ========================= CONFIG =========================
|
||||
DEBUG = False # Set True to enable debug overrides
|
||||
DEBUG = True # Set True to enable debug overrides
|
||||
|
||||
# Default paths (used if not in debug mode)
|
||||
DEFAULT_WIN_GAME_EXE = r"./qgame.dll"
|
||||
|
|
@ -588,7 +588,7 @@ def main():
|
|||
# bufsize=0, # unbuffered
|
||||
# universal_newlines=False)
|
||||
|
||||
items = ["Pee pee","Poo poo","Stinky caca peepee poopoo pants.","a","b","c","d"]
|
||||
items = ["choice1","choice2","choice 3.","a","b","c","d"]
|
||||
menu = TextMenu(
|
||||
items,
|
||||
width=30,
|
||||
|
|
|
|||
84
textmenu.py
84
textmenu.py
|
|
@ -83,13 +83,52 @@ class TextMenu:
|
|||
self._timeout_alarm = None
|
||||
|
||||
self.last_click_time = 0
|
||||
self.double_click_threshold = 0.5 # seconds
|
||||
self.double_click_threshold = 0.3 # seconds
|
||||
|
||||
# Buttons with double-click support
|
||||
# Custom button class that handles enter/space differently
|
||||
class SelectableButton(urwid.Button):
|
||||
signals = urwid.Button.signals + ['activate'] # Add our custom signal
|
||||
|
||||
def keypress(self, size, key):
|
||||
if key in ('enter', ' '):
|
||||
# For enter/space, trigger activation without generating click signal
|
||||
self._emit('activate')
|
||||
return None
|
||||
return super().keypress(size, key)
|
||||
|
||||
# Buttons with proper click handling
|
||||
self.menu_widgets = []
|
||||
for c in choices:
|
||||
btn = urwid.Button(c)
|
||||
urwid.connect_signal(btn, 'click', self._double_click, c)
|
||||
for i, c in enumerate(choices):
|
||||
btn = SelectableButton(c)
|
||||
|
||||
def make_click_handler(choice_text, index):
|
||||
def click_handler(button):
|
||||
# Handle mouse clicks with double-click detection
|
||||
now = time.time()
|
||||
|
||||
# Check if this is a double-click
|
||||
if now - self.last_click_time < self.double_click_threshold:
|
||||
# Double-click detected - return the selection
|
||||
self._cancel_timeout()
|
||||
self.selected = choice_text
|
||||
raise urwid.ExitMainLoop()
|
||||
else:
|
||||
# Single click - just focus the item (like keyboard navigation)
|
||||
self.list_walker.set_focus(index)
|
||||
|
||||
self.last_click_time = now
|
||||
return click_handler
|
||||
|
||||
def make_activate_handler(choice_text):
|
||||
def activate_handler(button):
|
||||
# Handle enter/space activation
|
||||
self._cancel_timeout()
|
||||
self.selected = choice_text
|
||||
raise urwid.ExitMainLoop()
|
||||
return activate_handler
|
||||
|
||||
urwid.connect_signal(btn, 'click', make_click_handler(c, i))
|
||||
urwid.connect_signal(btn, 'activate', make_activate_handler(c))
|
||||
self.menu_widgets.append(urwid.AttrMap(btn, None, focus_map='selected'))
|
||||
|
||||
# Scrollable ListBox
|
||||
|
|
@ -132,27 +171,32 @@ class TextMenu:
|
|||
self._timeout_alarm = None
|
||||
self.linebox.set_title(self.title) # restore original title
|
||||
|
||||
# Mouse double-click
|
||||
def _double_click(self, button, choice_text):
|
||||
self._cancel_timeout()
|
||||
now = time.time()
|
||||
if now - self.last_click_time < self.double_click_threshold:
|
||||
self.selected = choice_text
|
||||
raise urwid.ExitMainLoop()
|
||||
self.last_click_time = now
|
||||
|
||||
# Keyboard or mouse input
|
||||
# Keyboard or mouse input - handle ALL input types
|
||||
def _unhandled_input(self, key):
|
||||
# Cancel timeout on any input
|
||||
# Cancel timeout on ANY input
|
||||
self._cancel_timeout()
|
||||
|
||||
if key == 'enter':
|
||||
# Handle Enter key immediately (like double-click behavior)
|
||||
if key in ('enter', ' '):
|
||||
focus_widget, _ = self.listbox.get_focus()
|
||||
if focus_widget:
|
||||
self.selected = focus_widget.base_widget.get_label()
|
||||
# Get the button text from the nested widgets
|
||||
btn_text = focus_widget.original_widget.base_widget.get_label()
|
||||
self.selected = btn_text
|
||||
raise urwid.ExitMainLoop()
|
||||
# Scroll events also count: 'up', 'down', 'page up', 'page down', 'mouse press', 'mouse drag', 'mouse wheel'
|
||||
# urwid passes these to unhandled_input automatically, so we cancel timeout above
|
||||
elif key == 'esc':
|
||||
self.selected = None
|
||||
raise urwid.ExitMainLoop()
|
||||
# Handle navigation keys that should stop timer but not select
|
||||
elif key in ('up', 'down', 'page up', 'page down'):
|
||||
# Timer already cancelled above, just continue
|
||||
# Navigation already changes focus automatically
|
||||
pass
|
||||
# Handle mouse events that should stop timer
|
||||
elif isinstance(key, tuple) and len(key) >= 3 and key[0].startswith('mouse'):
|
||||
# This catches mouse events like ('mouse press', 1, x, y)
|
||||
# Timer already cancelled above, continue with normal processing
|
||||
pass
|
||||
|
||||
# Timeout exit
|
||||
def _timeout_exit(self, loop, user_data=None):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue