mirror of
https://github.com/bendtherules/pyFun.git
synced 2026-08-18 13:52:46 +00:00
summer update
This commit is contained in:
@@ -0,0 +1,517 @@
|
||||
import pygame
|
||||
import pygame.locals as pygame_consts
|
||||
from UncasedDict import UncasedDict
|
||||
|
||||
DICT_EVENT_IB = {
|
||||
"QUIT": pygame_consts.QUIT,
|
||||
"ACTIVE_EVENT": pygame_consts.ACTIVEEVENT,
|
||||
"KEY_DOWN": pygame_consts.KEYDOWN,
|
||||
"KEY_UP": pygame_consts.KEYUP,
|
||||
"MOUSE_MOTION": pygame_consts.MOUSEMOTION,
|
||||
"MOUSE_BUTTON_UP": pygame_consts.MOUSEBUTTONUP,
|
||||
"MOUSE_BUTTON_DOWN": pygame_consts.MOUSEBUTTONDOWN,
|
||||
"JOY_AXIS_MOTION": pygame_consts.JOYAXISMOTION,
|
||||
"JOY_BALL_MOTION": pygame_consts.JOYBALLMOTION,
|
||||
"JOY_HAT_MOTION": pygame_consts.JOYHATMOTION,
|
||||
"JOY_BUTTON_UP": pygame_consts.JOYBUTTONUP,
|
||||
"JOY_BUTTOND_OWN": pygame_consts.JOYBUTTONDOWN,
|
||||
"VIDEO_RESIZE": pygame_consts.VIDEORESIZE,
|
||||
"VIDEO_EXPOSE": pygame_consts.VIDEOEXPOSE,
|
||||
# "USER_EVENT": pygame_consts.USEREVENT,
|
||||
# think of begin_step, step and end_step
|
||||
}
|
||||
|
||||
|
||||
DICT_KEYS = {
|
||||
r"BACKSPACE": pygame_consts.K_BACKSPACE,
|
||||
r"TAB": pygame_consts.K_TAB,
|
||||
r"CLEAR": pygame_consts.K_CLEAR,
|
||||
r"RETURN": pygame_consts.K_RETURN,
|
||||
r"PAUSE": pygame_consts.K_PAUSE,
|
||||
r"ESCAPE": pygame_consts.K_ESCAPE,
|
||||
r"SPACE": pygame_consts.K_SPACE,
|
||||
r"EXCLAIM": pygame_consts.K_EXCLAIM,
|
||||
r"QUOTEDBL": pygame_consts.K_QUOTEDBL,
|
||||
r"HASH": pygame_consts.K_HASH,
|
||||
r"DOLLAR": pygame_consts.K_DOLLAR,
|
||||
r"AMPERSAND": pygame_consts.K_AMPERSAND,
|
||||
r"QUOTE": pygame_consts.K_QUOTE,
|
||||
r"LEFTPAREN": pygame_consts.K_LEFTPAREN,
|
||||
r"RIGHTPAREN": pygame_consts.K_RIGHTPAREN,
|
||||
r"ASTERISK": pygame_consts.K_ASTERISK,
|
||||
r"PLUS": pygame_consts.K_PLUS,
|
||||
r"COMMA": pygame_consts.K_COMMA,
|
||||
r"MINUS": pygame_consts.K_MINUS,
|
||||
r"PERIOD": pygame_consts.K_PERIOD,
|
||||
r"SLASH": pygame_consts.K_SLASH,
|
||||
r"0": pygame_consts.K_0,
|
||||
r"1": pygame_consts.K_1,
|
||||
r"2": pygame_consts.K_2,
|
||||
r"3": pygame_consts.K_3,
|
||||
r"4": pygame_consts.K_4,
|
||||
r"5": pygame_consts.K_5,
|
||||
r"6": pygame_consts.K_6,
|
||||
r"7": pygame_consts.K_7,
|
||||
r"8": pygame_consts.K_8,
|
||||
r"9": pygame_consts.K_9,
|
||||
r"COLON": pygame_consts.K_COLON,
|
||||
r"SEMICOLON": pygame_consts.K_SEMICOLON,
|
||||
r"LESS": pygame_consts.K_LESS,
|
||||
r"EQUALS": pygame_consts.K_EQUALS,
|
||||
r"GREATER": pygame_consts.K_GREATER,
|
||||
r"QUESTION": pygame_consts.K_QUESTION,
|
||||
r"AT": pygame_consts.K_AT,
|
||||
r"LEFTBRACKET": pygame_consts.K_LEFTBRACKET,
|
||||
r"BACKSLASH": pygame_consts.K_BACKSLASH,
|
||||
r"RIGHTBRACKET": pygame_consts.K_RIGHTBRACKET,
|
||||
r"CARET": pygame_consts.K_CARET,
|
||||
r"UNDERSCORE": pygame_consts.K_UNDERSCORE,
|
||||
r"BACKQUOTE": pygame_consts.K_BACKQUOTE,
|
||||
r"a": pygame_consts.K_a,
|
||||
r"b": pygame_consts.K_b,
|
||||
r"c": pygame_consts.K_c,
|
||||
r"d": pygame_consts.K_d,
|
||||
r"e": pygame_consts.K_e,
|
||||
r"f": pygame_consts.K_f,
|
||||
r"g": pygame_consts.K_g,
|
||||
r"h": pygame_consts.K_h,
|
||||
r"i": pygame_consts.K_i,
|
||||
r"j": pygame_consts.K_j,
|
||||
r"k": pygame_consts.K_k,
|
||||
r"l": pygame_consts.K_l,
|
||||
r"m": pygame_consts.K_m,
|
||||
r"n": pygame_consts.K_n,
|
||||
r"o": pygame_consts.K_o,
|
||||
r"p": pygame_consts.K_p,
|
||||
r"q": pygame_consts.K_q,
|
||||
r"r": pygame_consts.K_r,
|
||||
r"s": pygame_consts.K_s,
|
||||
r"t": pygame_consts.K_t,
|
||||
r"u": pygame_consts.K_u,
|
||||
r"v": pygame_consts.K_v,
|
||||
r"w": pygame_consts.K_w,
|
||||
r"x": pygame_consts.K_x,
|
||||
r"y": pygame_consts.K_y,
|
||||
r"z": pygame_consts.K_z,
|
||||
r"DELETE": pygame_consts.K_DELETE,
|
||||
r"KP0": pygame_consts.K_KP0,
|
||||
r"KP1": pygame_consts.K_KP1,
|
||||
r"KP2": pygame_consts.K_KP2,
|
||||
r"KP3": pygame_consts.K_KP3,
|
||||
r"KP4": pygame_consts.K_KP4,
|
||||
r"KP5": pygame_consts.K_KP5,
|
||||
r"KP6": pygame_consts.K_KP6,
|
||||
r"KP7": pygame_consts.K_KP7,
|
||||
r"KP8": pygame_consts.K_KP8,
|
||||
r"KP9": pygame_consts.K_KP9,
|
||||
r"KP_PERIOD": pygame_consts.K_KP_PERIOD,
|
||||
r"KP_DIVIDE": pygame_consts.K_KP_DIVIDE,
|
||||
r"KP_MULTIPLY": pygame_consts.K_KP_MULTIPLY,
|
||||
r"KP_MINUS": pygame_consts.K_KP_MINUS,
|
||||
r"KP_PLUS": pygame_consts.K_KP_PLUS,
|
||||
r"KP_ENTER": pygame_consts.K_KP_ENTER,
|
||||
r"KP_EQUALS": pygame_consts.K_KP_EQUALS,
|
||||
r"UP": pygame_consts.K_UP,
|
||||
r"DOWN": pygame_consts.K_DOWN,
|
||||
r"RIGHT": pygame_consts.K_RIGHT,
|
||||
r"LEFT": pygame_consts.K_LEFT,
|
||||
r"INSERT": pygame_consts.K_INSERT,
|
||||
r"HOME": pygame_consts.K_HOME,
|
||||
r"END": pygame_consts.K_END,
|
||||
r"PAGEUP": pygame_consts.K_PAGEUP,
|
||||
r"PAGEDOWN": pygame_consts.K_PAGEDOWN,
|
||||
r"F1": pygame_consts.K_F1,
|
||||
r"F2": pygame_consts.K_F2,
|
||||
r"F3": pygame_consts.K_F3,
|
||||
r"F4": pygame_consts.K_F4,
|
||||
r"F5": pygame_consts.K_F5,
|
||||
r"F6": pygame_consts.K_F6,
|
||||
r"F7": pygame_consts.K_F7,
|
||||
r"F8": pygame_consts.K_F8,
|
||||
r"F9": pygame_consts.K_F9,
|
||||
r"F10": pygame_consts.K_F10,
|
||||
r"F11": pygame_consts.K_F11,
|
||||
r"F12": pygame_consts.K_F12,
|
||||
r"F13": pygame_consts.K_F13,
|
||||
r"F14": pygame_consts.K_F14,
|
||||
r"F15": pygame_consts.K_F15,
|
||||
r"NUMLOCK": pygame_consts.K_NUMLOCK,
|
||||
r"CAPSLOCK": pygame_consts.K_CAPSLOCK,
|
||||
r"SCROLLOCK": pygame_consts.K_SCROLLOCK,
|
||||
r"RSHIFT": pygame_consts.K_RSHIFT,
|
||||
r"LSHIFT": pygame_consts.K_LSHIFT,
|
||||
r"RCTRL": pygame_consts.K_RCTRL,
|
||||
r"LCTRL": pygame_consts.K_LCTRL,
|
||||
r"RALT": pygame_consts.K_RALT,
|
||||
r"LALT": pygame_consts.K_LALT,
|
||||
r"RMETA": pygame_consts.K_RMETA,
|
||||
r"LMETA": pygame_consts.K_LMETA,
|
||||
r"LSUPER": pygame_consts.K_LSUPER,
|
||||
r"RSUPER": pygame_consts.K_RSUPER,
|
||||
r"MODE": pygame_consts.K_MODE,
|
||||
r"HELP": pygame_consts.K_HELP,
|
||||
r"PRINT": pygame_consts.K_PRINT,
|
||||
r"SYSREQ": pygame_consts.K_SYSREQ,
|
||||
r"BREAK": pygame_consts.K_BREAK,
|
||||
r"MENU": pygame_consts.K_MENU,
|
||||
r"POWER": pygame_consts.K_POWER,
|
||||
r"EURO": pygame_consts.K_EURO,
|
||||
}
|
||||
|
||||
LIST_EVENTS_GAME_PRE = ["BEGIN_STEP"]
|
||||
# Custom events to be registered here
|
||||
LIST_EVENTS_GAME_POST = ["STEP", "DRAW", "END_STEP"]
|
||||
LIST_EVENTS_CUSTOM = [
|
||||
"KEY_PRESS", "MOUSE_PRESS", "Instance_Create", "Instance_Destroy"]
|
||||
|
||||
|
||||
dict_event_name = UncasedDict()
|
||||
list_event = []
|
||||
list_event_old = []
|
||||
list_state_key = []
|
||||
list_state_key_old = []
|
||||
list_state_mouse, list_state_mouse_old = [], []
|
||||
|
||||
|
||||
def register_event_name(ev_name, ev_id=None):
|
||||
if (ev_name in dict_event_name):
|
||||
raise TypeError(
|
||||
"ev_name={0} is already registered".format(ev_name))
|
||||
if (ev_id is None):
|
||||
ev_id = max(
|
||||
pygame_consts.USEREVENT + 1, max(dict_event_name.values()) + 1)
|
||||
dict_event_name[ev_name] = ev_id
|
||||
|
||||
|
||||
def add_each_event(ev):
|
||||
if not (ev.ev_name in dict_event_name):
|
||||
return TypeError("ev_name not registered")
|
||||
else:
|
||||
# make list_event_accessible
|
||||
list_event.append(ev)
|
||||
|
||||
|
||||
def add_returned_events(ev_or_ev_list):
|
||||
# fix below cond
|
||||
if hasattr(ev_or_ev_list, "__iter__"):
|
||||
# list of events
|
||||
for each_ev in ev_or_ev_list:
|
||||
add_each_event(each_ev)
|
||||
else:
|
||||
# single event
|
||||
add_each_event(ev_or_ev_list)
|
||||
|
||||
|
||||
def get_event_name(ev_id):
|
||||
for ev_name in dict_event_name:
|
||||
if dict_event_name[ev_name] == ev_id:
|
||||
return ev_name
|
||||
|
||||
|
||||
def get_event_id(ev_name):
|
||||
return dict_event_name.get(ev_name)
|
||||
|
||||
|
||||
def get_key_name(key_id):
|
||||
for key_name in DICT_KEYS:
|
||||
if DICT_KEYS[key_name] == key_id:
|
||||
return key_name
|
||||
|
||||
|
||||
def get_key_id(key_name):
|
||||
return DICT_KEYS.get(key_name)
|
||||
|
||||
|
||||
def get_mouse_btn_name(btn_id):
|
||||
# btn_id can be 0, 1 or 2
|
||||
if btn_id == 0:
|
||||
return "left"
|
||||
elif btn_id == 1:
|
||||
return "middle"
|
||||
elif btn_id == 2:
|
||||
return "right"
|
||||
else:
|
||||
raise ValueError("btn_id must be 0, 1 or 2")
|
||||
|
||||
# No sort_events, event_generators should be pushed in correct order
|
||||
|
||||
|
||||
def fuzzy_match_event_name(string_, event_or_action):
|
||||
str_upper = string_.upper()
|
||||
if not (str_upper in dict_event_name):
|
||||
event_or_action = event_or_action.lower()
|
||||
if event_or_action == "event" or event_or_action == "action":
|
||||
# STR_STARTER becomes event_ or action_
|
||||
STR_STARTER = event_or_action.upper() + "_"
|
||||
else:
|
||||
raise TypeError(
|
||||
"event_or_action arg must be 'event' or 'action'.")
|
||||
str_normalized = str_upper[
|
||||
str_upper.find(STR_STARTER) + len(STR_STARTER):]
|
||||
for tmp_event_name in dict_event_name:
|
||||
# tmp event is the event_name, keys of KW_EVENTS
|
||||
tmp_event_name_normalized = tmp_event_name.upper().replace("_", "")
|
||||
if str_normalized.startswith(tmp_event_name) or str_normalized.startswith(tmp_event_name_normalized):
|
||||
return tmp_event_name
|
||||
else:
|
||||
return str_upper
|
||||
|
||||
|
||||
def add_ev_name_GAME_PRE():
|
||||
for ev_name in LIST_EVENTS_GAME_PRE:
|
||||
register_event_name(ev_name)
|
||||
|
||||
|
||||
def add_ev_name_IB():
|
||||
for ev_name in DICT_EVENT_IB:
|
||||
register_event_name(ev_name, DICT_EVENT_IB[ev_name])
|
||||
|
||||
|
||||
def add_ev_name_GAME_POST():
|
||||
for ev_name in LIST_EVENTS_GAME_POST:
|
||||
register_event_name(ev_name)
|
||||
|
||||
|
||||
def add_ev_name_CUSTOM():
|
||||
for ev_name in LIST_EVENTS_CUSTOM:
|
||||
register_event_name(ev_name)
|
||||
|
||||
# event_generators
|
||||
|
||||
|
||||
def gen_event_GAME_PRE():
|
||||
return [Event(ev_name) for ev_name in LIST_EVENTS_GAME_PRE]
|
||||
|
||||
|
||||
def gen_event_IB():
|
||||
# move current list to old list
|
||||
list_event_IB = pygame.event.get()
|
||||
# Above list contains pygame_events, cant be modified
|
||||
# But need to replace type with ev_name
|
||||
new_list_ev = []
|
||||
for each_ev in list_event_IB:
|
||||
ev_name = get_event_name(each_ev.type)
|
||||
tmp_ev = Event(ev_name, each_ev.dict)
|
||||
new_list_ev.append(tmp_ev)
|
||||
|
||||
return new_list_ev
|
||||
|
||||
|
||||
def gen_event_GAME_POST():
|
||||
return [Event(ev_name) for ev_name in LIST_EVENTS_GAME_POST]
|
||||
|
||||
|
||||
def gen_event_KEY_PRESS():
|
||||
global list_state_key, list_state_key_old
|
||||
list_state_key_old = list_state_key
|
||||
list_state_key = pygame.key.get_pressed()
|
||||
list_key_press_event = []
|
||||
for tmp_key_id, bool_pressed in enumerate(list_state_key):
|
||||
if bool_pressed:
|
||||
tmp_key_name = get_key_name(tmp_key_id)
|
||||
list_key_press_event.append(
|
||||
Event("KEY_PRESS", {"key_name": tmp_key_name.lower(), "key_id": tmp_key_id}))
|
||||
return list_key_press_event
|
||||
|
||||
|
||||
def gen_event_MOUSE_PRESS():
|
||||
global list_state_mouse, list_state_mouse_old
|
||||
list_state_mouse_old = list_state_mouse
|
||||
list_state_mouse = pygame.mouse.get_pressed()
|
||||
list_mouse_press_event = []
|
||||
for tmp_mouse_btn_id, bool_pressed in enumerate(list_state_mouse):
|
||||
if bool_pressed:
|
||||
tmp_btn_name = get_mouse_btn_name(tmp_mouse_btn_id)
|
||||
list_mouse_press_event.append(
|
||||
Event("MOUSE_PRESS", {"btn_name": tmp_btn_name.lower(), "btn_id": tmp_mouse_btn_id}))
|
||||
return list_mouse_press_event
|
||||
|
||||
# pygame.mouse.get_pressed
|
||||
|
||||
# add ev_names
|
||||
# Ordered list of name adders
|
||||
LIST_ADDER_EV_NAME = [
|
||||
add_ev_name_IB, add_ev_name_GAME_PRE, add_ev_name_GAME_POST, add_ev_name_CUSTOM]
|
||||
for each_adder_func in LIST_ADDER_EV_NAME:
|
||||
each_adder_func()
|
||||
|
||||
|
||||
# add event generators
|
||||
# Ordered list of generators
|
||||
list_ordered_custom_generator = [gen_event_KEY_PRESS, gen_event_MOUSE_PRESS]
|
||||
|
||||
list_ordered_generators = [
|
||||
gen_event_GAME_PRE, gen_event_IB, list_ordered_custom_generator, gen_event_GAME_POST]
|
||||
|
||||
|
||||
def register_custom_event_generator(ev_func):
|
||||
''' ev_func will be run in each step before step event and after begin step event and should return a / a list of dicts
|
||||
each with ev_name (to be registered beforehand) and other props'''
|
||||
global list_ordered_custom_generator
|
||||
list_ordered_custom_generator.append(ev_func)
|
||||
|
||||
|
||||
def get_event_generators():
|
||||
return_list = []
|
||||
for gen_or_list in list_ordered_generators:
|
||||
if hasattr(gen_or_list, "__iter__"):
|
||||
return_list.extend(gen_or_list)
|
||||
else:
|
||||
return_list.append(gen_or_list)
|
||||
return return_list
|
||||
|
||||
|
||||
# Todo: Howto programatically register at the right position of generator list
|
||||
# Event collector
|
||||
|
||||
|
||||
def collect_events():
|
||||
# First, clear the old ev list
|
||||
global list_event, list_event_old
|
||||
list_event_old = list_event
|
||||
list_event = []
|
||||
for each_gen in get_event_generators():
|
||||
add_returned_events(each_gen())
|
||||
|
||||
# Event dispatcher
|
||||
# To be used by appr. classes
|
||||
|
||||
|
||||
def dispatch_events_class(cls):
|
||||
# cls.list_class must be available
|
||||
for each_class in cls.list_class:
|
||||
each_class.dispatch_events_instance(list_event)
|
||||
|
||||
|
||||
def dispatch_events_instance(cls, list_event):
|
||||
for each_instance in cls.list_instance:
|
||||
each_instance.dispatch_events_self(list_event)
|
||||
|
||||
|
||||
def dispatch_events_self(self, list_event):
|
||||
for each_ev in list_event:
|
||||
if each_ev.ev_name.upper() in self.dict_action_func:
|
||||
self.dispatch_events_local()
|
||||
for each_action in self.dict_action_func[each_ev.ev_name]:
|
||||
# similar as self.action_step(each_ev)
|
||||
each_action(self, each_ev)
|
||||
|
||||
|
||||
def dispatch_events_local(self):
|
||||
for each_ev in self.list_event_local:
|
||||
if each_ev.ev_name.upper() in self.dict_action_func:
|
||||
for each_action in self.dict_action_func[each_ev.ev_name]:
|
||||
# similar as self.action_step(each_ev)
|
||||
each_action(self, each_ev)
|
||||
self.clear_event_local()
|
||||
|
||||
|
||||
def push_event_local(self, ev_or_ev_list):
|
||||
if hasattr(ev_or_ev_list, "__iter__"):
|
||||
# list of events
|
||||
for each_ev in ev_or_ev_list:
|
||||
self._push_event_local_single(each_ev)
|
||||
else:
|
||||
# single event
|
||||
self._push_event_local_single(ev_or_ev_list)
|
||||
|
||||
|
||||
def clear_event_local(self):
|
||||
self.list_event_local = []
|
||||
|
||||
|
||||
def _push_event_local_single(self, ev):
|
||||
self.list_event_local.append(ev)
|
||||
|
||||
|
||||
class Event(object):
|
||||
|
||||
def __init__(self, ev_name, dict_=None):
|
||||
super(Event, self).__init__()
|
||||
self.ev_name = ev_name
|
||||
self.dict = dict_
|
||||
|
||||
|
||||
def _check_event(ev_name, new_or_old):
|
||||
''' ev_name_or_type => name_or_type(numb)_of_event
|
||||
new_or_old => current_event_list or old_event_list '''
|
||||
global list_event, list_event_old
|
||||
matched_events = []
|
||||
if new_or_old == "new":
|
||||
list_to_check = list_event
|
||||
elif new_or_old == "old":
|
||||
list_to_check = list_event_old
|
||||
else:
|
||||
raise AttributeError("new_or_old must be 'new' or 'old'.")
|
||||
|
||||
ev_name = fuzzy_match_event_name(ev_name, "event")
|
||||
|
||||
for ev in list_to_check:
|
||||
if ev.ev_name == ev_name:
|
||||
matched_events.append(ev)
|
||||
return matched_events
|
||||
|
||||
|
||||
def check_event(ev_name):
|
||||
return _check_event(ev_name, "new")
|
||||
|
||||
|
||||
def check_event_old(ev_name):
|
||||
return _check_event(ev_name, "old")
|
||||
|
||||
|
||||
def _get_key_press(key_name=None, new_or_old=None):
|
||||
''' Returns list of dict with key_name and key_id, if key_name matches.
|
||||
If key_name is None, all key preeses are allowed.'''
|
||||
global list_state_key, list_state_key_old
|
||||
if new_or_old == "new":
|
||||
list_to_check = list_state_key
|
||||
elif new_or_old == "old":
|
||||
list_to_check = list_state_key_old
|
||||
else:
|
||||
raise TypeError("new_or_old must be 'new' or 'old', CANT be None")
|
||||
list_key_press_event = []
|
||||
for tmp_key_id, bool_pressed in enumerate(list_to_check):
|
||||
if bool_pressed:
|
||||
tmp_key_name = get_key_name(tmp_key_id)
|
||||
if (key_name is None) or (tmp_key_name.lower() == key_name.lower()):
|
||||
# Todo: Cant match event_name directly, need a fuzzy key name
|
||||
# search func
|
||||
list_key_press_event.append(
|
||||
{"key_name": tmp_key_name.lower(), "key_id": tmp_key_id})
|
||||
return list_key_press_event
|
||||
|
||||
|
||||
def _get_mouse_press(btn_name=None, new_or_old=None):
|
||||
global list_state_mouse, list_state_mouse_old
|
||||
if new_or_old == "new":
|
||||
list_to_check = list_state_mouse
|
||||
elif new_or_old == "old":
|
||||
list_to_check = list_state_mouse_old
|
||||
else:
|
||||
raise TypeError("new_or_old must be 'new' or 'old', CANT be None")
|
||||
|
||||
list_mouse_press_event = []
|
||||
for tmp_mouse_btn_id, bool_pressed in enumerate(list_to_check):
|
||||
if bool_pressed:
|
||||
tmp_btn_name = get_mouse_btn_name(tmp_mouse_btn_id)
|
||||
if (btn_name is None) or (btn_name.lower() == tmp_btn_name.lower()):
|
||||
list_mouse_press_event.append(
|
||||
{"btn_name": tmp_btn_name.lower(), "btn_id": tmp_mouse_btn_id})
|
||||
return list_mouse_press_event
|
||||
|
||||
|
||||
def get_key_press(key_name=None):
|
||||
return _get_key_press(key_name, "new")
|
||||
|
||||
|
||||
def get_key_press_old(key_name=None):
|
||||
return _get_key_press(key_name, "old")
|
||||
|
||||
|
||||
def get_mouse_press(btn_name=None):
|
||||
return _get_mouse_press(btn_name, "new")
|
||||
|
||||
|
||||
def get_mouse_press_old(btn_name=None):
|
||||
return _get_mouse_press(btn_name, "old")
|
||||
Reference in New Issue
Block a user