From fdf2e1a3ffb5830908c8a3d0968da12265677a16 Mon Sep 17 00:00:00 2001 From: david-ajax Date: Sat, 5 Apr 2025 19:29:23 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20"=E6=B3=A8=E5=86=8C?= =?UTF-8?q?=E4=B8=BA=E8=A7=82=E5=AF=9F=E8=80=85(=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E9=A9=B1=E5=8A=A8)"=20=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pulsar/main.py | 10 +++- vgl/__init__.py | 2 +- vgl/__pycache__/main.cpython-312.pyc | Bin 7396 -> 12115 bytes vgl/main.py | 80 +++++++++++++++++---------- 4 files changed, 59 insertions(+), 33 deletions(-) diff --git a/pulsar/main.py b/pulsar/main.py index 72b7056..56f29ce 100644 --- a/pulsar/main.py +++ b/pulsar/main.py @@ -1,13 +1,19 @@ import vgl import time -window = None + +window = vgl.Window(title="Pulsar", size=(1024, 768)) + def horizontal_indicator(): global window frame = vgl.Frame().attach(window_object=window, poscale=(0, 0), clone_name="Horizontal Indicator") vgl.elements.Line(ends=[(0.4, 0.5), (0.6, 0.5)], color="green").attach(frame_object=frame) pass +@window.observerize +def observer(info): + print(info) def marking_lines(): + print("实例") global window frame = vgl.Frame().attach(window_object=window, poscale=(0,0), clone_name="Marking Line") for i in range(0, 24): @@ -25,10 +31,10 @@ def console(): if __name__ == '__main__': print("Welcome to AiraPulsar Client") - window = vgl.Window(title="Pulsar", size=(1024, 768)) window.start() horizontal_indicator() marking_lines() + observer() #console() input("任意键以退出") window.kill() diff --git a/vgl/__init__.py b/vgl/__init__.py index d1e7c50..779214e 100644 --- a/vgl/__init__.py +++ b/vgl/__init__.py @@ -3,5 +3,5 @@ os.environ["PYGAME_HIDE_SUPPORT_PROMPT"] = "True" from .main import * from . import basic_elements as elements -version = '0.1.0' +version = '0.2.0' print(f"Powered by Vector Graphic Layer, version {version}") \ No newline at end of file diff --git a/vgl/__pycache__/main.cpython-312.pyc b/vgl/__pycache__/main.cpython-312.pyc index e59807b66dde6880bef9ff9a0eb78029bc0e9ead..71ff01b8cca1d539d5c18a7e2b112ddd4ca720a4 100644 GIT binary patch literal 12115 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 EUkWH(ssI20 delta 1936 zcmZ8i-ES0C6u)~&ekenho892pKZw9Jt zP_Qbn!DVbnupwZ>%h>P))gphOVt?LO_mNgVmfB%)jaVdi^2f1p3p z8h%~6MQaz11&&HI!MXA%(60sg<+`38d;p6g)F8;uAPfs92{20*C8~5R%2YW>5jQT$ zVP%SPwf@_LCl`%z>xSgXj#U_DUHpE17hQj=!J;(Fhu6MA+xgdPM}wYXS_RkOEySp3VT>`wFp>qO`Va8RnX)eiz1Fj?Ejz_pun-7ea$t{*_j%?tlF9iW-5u-0O1 zJ5oCkb|UOTK;L+3d13@~`A|#p)CpwK+5R)tVLa7A@1kVvf?YIA7xdEUGZs8w2=7DT zUI5|aRvf-r=#t4A-z?vQhZcTmaj7ms8e%3B~y_#U-icsu&|*(D6}z+!Ll8?A%WgQ#~L_2Mgn>mNCQ`)C1s2jTgP{WoDCy|}I$ z#bU`dT)R|sbbVQ%MPygRRNRPwNy0C-9i)R8Ru#U;(tiH1t!Zn>q?R%)L9r`2)eOv% zT+oCf&xK3{Fl<6;=OPn9E$pc$grgU}TA!pe$M2+@`wTe8i#nF8=Z!L&qy_wP7=;an zS>|A)cv()9rWCA^BCp>w~E)*uCRjcsB z;FS&OC|ZucrSB;}`%+3`clrLzKAPbdGkfbDI@e~>DWZdbKjt)D3glPW%O308~K2?GfwC3x@dtIXHqE2 zztL9jsAb|I=q69G&Ra#-3yfHugt2RsLV+ zp*3+5Uo&60Qm7-(H7k46Fmec3 zAP%O?EcrFI>dN3u-xEnyI`4EW5ttThB>+`Y8W&ZnG%nfD?Hl}m2vpW0Ok|koJ7FN0 zgRlz$|2#ak+Dk-B6g4C+ezCZ`(BAQqd9GmfvQIz>6UupwKi$;0`)@fxr|1)cSZQyj gu}i}h0#l{8fgYik`YHtH%9a#uxHR||fl1i*KU-?4cK`qY diff --git a/vgl/main.py b/vgl/main.py index 0da4852..f224e26 100644 --- a/vgl/main.py +++ b/vgl/main.py @@ -5,6 +5,7 @@ import uuid import time import threading import copy +import queue class Aux(): def gettime(): @@ -23,7 +24,7 @@ class Aux(): return (round(arg[0] * base[0]), round(arg[1] * base[1])) if len(arg) == 4: return (round(arg[0] * base[0]), round(arg[1] * base[1]), round(arg[2] * base[0]), round(arg[3] * base[1])) - def eventproc(events_dict, event): + def eventproc(events_dict, event, window_size): """events = { "cursor": { "position": (15,12), @@ -33,31 +34,31 @@ class Aux(): }, "wheel": 1, # 远离用户为 1, 靠近为 -1, 无动作为 0 "click": [1, 2], # 被按下的按钮 - "focus": 1, # 或 0 - "key": ["ctrl", "k"] + #"focus": 1, # 或 0 + "key": ["ctrl", "k"], + "delta": "" }""" if event.type == pygame.MOUSEMOTION: - events_dict.setdefault("cursor", {})["position"] = event.pos - events_dict.setdefault("cursor", {})["relative"] = event.rel - events_dict.setdefault("cursor", {})["poscale"] = (event.pos[0] / screen_width, event.pos[1] / screen_height) - events_dict.setdefault("cursor", {})["relscale"] = (event.rel[0] / screen_width, event.rel[1] / screen_height) + events_dict["cursor"]["position"] = event.pos + events_dict["cursor"]["relative"] = event.rel + events_dict["cursor"]["poscale"] = (round(event.pos[0] / window_size[0], 3), round(event.pos[1] / window_size[1],3)) + events_dict["cursor"]["relscale"] = (round(event.rel[0] / window_size[0], 3), round(event.rel[1] / window_size[1], 3)) + events_dict["delta"] = "cursor" elif event.type == pygame.MOUSEWHEEL: - if "wheel" not in events_dict: - events_dict["wheel"] = 0 - events_dict["wheel"] += event.y # 远离用户为正,靠近为负 + events_dict["wheel"] = event.y # 远离用户为正,靠近为负 + events_dict["delta"] = "wheel" elif event.type == pygame.MOUSEBUTTONDOWN: - events_dict.setdefault("click", []).append(event.button) + if event.button not in events_dict["click"]: + events_dict.setdefault("click", []).append(event.button) + events_dict["delta"] = "click" elif event.type == pygame.MOUSEBUTTONUP: - if "click" in events_dict and event.button in events_dict["click"]: + if event.button in events_dict["click"]: events_dict["click"].remove(event.button) - elif event.type == pygame.WINDOWEVENT and hasattr(pygame, 'WINDOWEVENT_FOCUS_GAINED') and event.event == pygame.WINDOWEVENT_FOCUS_GAINED: - events_dict["focus"] = 1 - elif event.type == pygame.WINDOWEVENT and hasattr(pygame, 'WINDOWEVENT_FOCUS_LOST') and event.event == pygame.WINDOWEVENT_FOCUS_LOST: - events_dict["focus"] = 0 + events_dict["delta"] = "click" elif event.type == pygame.KEYDOWN: keys = events_dict.setdefault("key", []) key_name = pygame.key.name(event.key).lower() - # 简单的修饰键处理,可以根据需要扩展 + # 简单的修饰键处理, 为兼容部分精简键盘 故合并左右功能键 if key_name in ["left ctrl", "right ctrl"]: if "ctrl" not in keys: keys.append("ctrl") @@ -69,7 +70,9 @@ class Aux(): keys.append("alt") elif len(key_name) == 1: # 处理字母和数字 keys.append(key_name) + events_dict["delta"] = "key" elif event.type == pygame.KEYUP: + events_dict["delta"] = "key" if "key" in events_dict: key_name = pygame.key.name(event.key).lower() if key_name in ["left ctrl", "right ctrl"] and "ctrl" in events_dict["key"]: @@ -81,7 +84,7 @@ class Aux(): elif len(key_name) == 1 and key_name in events_dict["key"]: events_dict["key"].remove(key_name) else: - print("不重要事件") + #print("不重要事件") return 0 return 1 class Element(object): @@ -142,6 +145,19 @@ class Frame(object): class Window(object): frames = dict() events = { + "cursor": { + "position": (0,0), + "relative": (0,0), + "poscale": (0,0), + "relscale": (0,0), + }, + "wheel": 0, # 远离用户为 1, 靠近为 -1, 无动作为 0 + "click": [], # 被按下的按钮 + "focus": 1, # 或 0 + "key": [], + "delta": [] # 变化的键值, 避免多次调用 + } + """{ "cursor": { "position": (15,12), "relative": (13,11), @@ -151,8 +167,10 @@ class Window(object): "wheel": 1, # 远离用户为 1, 靠近为 -1, 无动作为 0 "click": [1, 2], # 被按下的按钮 "focus": 1, # 或 0 - "key": ["ctrl", "k"] - } + "key": ["ctrl", "k"], + "delta": ["key"] + }""" + observers = list() def __init__(self, title="Vector Graphic Layer Window", size: tuple=(1024,768)): self.title = title self.size = size @@ -173,19 +191,21 @@ class Window(object): for event in pygame.event.get(): if event.type == pygame.QUIT: self.running = 0 - if_matters = Aux.eventproc(self.events, event.type) + if_matters = Aux.eventproc(self.events, event, self.size) if if_matters: - pass # 消息式调用 + print(self.observers) + for i in self.observers: + i(self.events) + #print(self.events) + for i in self.frames.values(): i.render() pygame.display.flip() pygame.time.delay(10) pygame.quit() - def observer(self): - def decorator(func): - def wrapper(*args, **kwargs): - print("注册观察者") - result = func(info=self.event, *args, **kwargs) # 调用原始函数 - return result - return wrapper - return decorator \ No newline at end of file + def observerize(self, func): + def wrapper(): + self.observers.append(func) + return wrapper + def remove_observer(self, func): + self.observers.remove(func) \ No newline at end of file