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()
|
shutdown_event = threading.Event()
|
||||||
|
|
||||||
# ========================= CONFIG =========================
|
# ========================= 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 paths (used if not in debug mode)
|
||||||
DEFAULT_WIN_GAME_EXE = r"./qgame.dll"
|
DEFAULT_WIN_GAME_EXE = r"./qgame.dll"
|
||||||
|
|
@ -588,7 +588,7 @@ def main():
|
||||||
# bufsize=0, # unbuffered
|
# bufsize=0, # unbuffered
|
||||||
# universal_newlines=False)
|
# 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(
|
menu = TextMenu(
|
||||||
items,
|
items,
|
||||||
width=30,
|
width=30,
|
||||||
|
|
|
||||||
84
textmenu.py
84
textmenu.py
|
|
@ -83,13 +83,52 @@ class TextMenu:
|
||||||
self._timeout_alarm = None
|
self._timeout_alarm = None
|
||||||
|
|
||||||
self.last_click_time = 0
|
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 = []
|
self.menu_widgets = []
|
||||||
for c in choices:
|
for i, c in enumerate(choices):
|
||||||
btn = urwid.Button(c)
|
btn = SelectableButton(c)
|
||||||
urwid.connect_signal(btn, 'click', self._double_click, 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'))
|
self.menu_widgets.append(urwid.AttrMap(btn, None, focus_map='selected'))
|
||||||
|
|
||||||
# Scrollable ListBox
|
# Scrollable ListBox
|
||||||
|
|
@ -132,27 +171,32 @@ class TextMenu:
|
||||||
self._timeout_alarm = None
|
self._timeout_alarm = None
|
||||||
self.linebox.set_title(self.title) # restore original title
|
self.linebox.set_title(self.title) # restore original title
|
||||||
|
|
||||||
# Mouse double-click
|
# Keyboard or mouse input - handle ALL input types
|
||||||
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
|
|
||||||
def _unhandled_input(self, key):
|
def _unhandled_input(self, key):
|
||||||
# Cancel timeout on any input
|
# Cancel timeout on ANY input
|
||||||
self._cancel_timeout()
|
self._cancel_timeout()
|
||||||
|
|
||||||
if key == 'enter':
|
# Handle Enter key immediately (like double-click behavior)
|
||||||
|
if key in ('enter', ' '):
|
||||||
focus_widget, _ = self.listbox.get_focus()
|
focus_widget, _ = self.listbox.get_focus()
|
||||||
if focus_widget:
|
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()
|
raise urwid.ExitMainLoop()
|
||||||
# Scroll events also count: 'up', 'down', 'page up', 'page down', 'mouse press', 'mouse drag', 'mouse wheel'
|
elif key == 'esc':
|
||||||
# urwid passes these to unhandled_input automatically, so we cancel timeout above
|
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
|
# Timeout exit
|
||||||
def _timeout_exit(self, loop, user_data=None):
|
def _timeout_exit(self, loop, user_data=None):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue