From 551ed9a4ce12b3a8e749003391c42bc3e1a63a52 Mon Sep 17 00:00:00 2001 From: david-ajax Date: Fri, 4 Apr 2025 16:06:26 +0800 Subject: [PATCH] changes --- pulsar/numerator.py | 0 pulsar/src/dock/angle_limit.png | Bin 0 -> 435 bytes pulsar/src/dock/drop_indicator.png | Bin 0 -> 400 bytes pulsar/src/dock/extremis.png | Bin 0 -> 426 bytes pulsar/src/dock/landing_mode.png | Bin 0 -> 422 bytes pulsar/src/dock/recording_indicator.png | Bin 0 -> 332 bytes pulsar/src/dock/sync_indicator.png | Bin 0 -> 399 bytes testfield/vgl/aux.py | 113 ----------- testfield/vgl/default.vgld | 31 --- testfield/vgl/elements/ basic.py | 51 +++++ testfield/vgl/test.py | 26 --- testfield/vgl/vgllib old.py | 189 ++++++++++++++++++ testfield/vgl/vgllib.py | 242 +++++++----------------- 13 files changed, 311 insertions(+), 341 deletions(-) create mode 100644 pulsar/numerator.py create mode 100644 pulsar/src/dock/angle_limit.png create mode 100644 pulsar/src/dock/drop_indicator.png create mode 100644 pulsar/src/dock/extremis.png create mode 100644 pulsar/src/dock/landing_mode.png create mode 100644 pulsar/src/dock/recording_indicator.png create mode 100644 pulsar/src/dock/sync_indicator.png delete mode 100644 testfield/vgl/aux.py delete mode 100644 testfield/vgl/default.vgld create mode 100644 testfield/vgl/elements/ basic.py create mode 100644 testfield/vgl/vgllib old.py diff --git a/pulsar/numerator.py b/pulsar/numerator.py new file mode 100644 index 0000000..e69de29 diff --git a/pulsar/src/dock/angle_limit.png b/pulsar/src/dock/angle_limit.png new file mode 100644 index 0000000000000000000000000000000000000000..31a0224a5f4c4fea2bffa2b5a33bb650e526296d GIT binary patch literal 435 zcmV;k0ZjghP)xv27^b`;xfAkfjEUs=wkMVYvY#X`n36jAaIlY~t6(Ypo_WggOMn8Ze{q)dH)S z1CY$`3J9S_z#^sqBSiQ04wcFAH69Aq*?A#^H2v}L54j@wdKp+DE8w*qc zL~9=iW&ogXff|67?Q23%0T5CBmT)7`qGf>?K;-s;zy<(17Ki{uZyyi<@UnTS1))bk zBU1ppwBI7JU>gHwAq)fX*1j}D0K9L0#)54|U^d+Vytm&nYJux7M`trqQkMZy+Mmhs zXF%5o?AUzE@dg|Zplbw}zvb1)zY$IYdR~-=;KoS+>;#%@n}Vq`Lt6j<002ovPDHLkV1nH;t5W~~ literal 0 HcmV?d00001 diff --git a/pulsar/src/dock/drop_indicator.png b/pulsar/src/dock/drop_indicator.png new file mode 100644 index 0000000000000000000000000000000000000000..b704d50e0d08ca10ce07445ba7467e7bc3b58819 GIT binary patch literal 400 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5M?jcysy3fA0|TRz zr;B4q#hkaZ1NoZ`I9d`v{{R2>wdvtymvE95024fWP_RV<(Si4R%T zgE+S8JG#^MobQb>d)d%2J<9z=G>7Yy$4_Mg;uaZef$fg00(rF8qCd=9KwNTAx4uxXNLZ8$6|bv9YtcYyY&ZwX;{{ zty_D4?$)_S6I%HkN_NSsrqp?gAIN^0VZpk|>eWpdOV$?+FZlMHPBVjA`M@{Jr^%ts z>cH$XGg#^wxElBvcv&6T81c$aFhC?ipk<;a_c<^Pti*u$*BV8vh}!XV2a1yXkQ gd&M5Dr?MZ|DyAeaTO`=K1{lN)p00i_>zopr0EG0T*Z=?k literal 0 HcmV?d00001 diff --git a/pulsar/src/dock/extremis.png b/pulsar/src/dock/extremis.png new file mode 100644 index 0000000000000000000000000000000000000000..110627252a759d0e99b3a00b0ebe83509a82f4b8 GIT binary patch literal 426 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5M?jcysy3fA0|R4> zr;B4q#hkadZu2!62(&z0`SEYO!f^QQ~+qcct_PxRrAI`YY<5tOIn-@$a^L{ty z?!K-tB}nBdi;4r&1=bfT46zMFEjaPuU&Bo8%fCbKU5xNK@WSm(-ky>f46pt* zJa+q1B2gRvx2}e%@2PuON!h~!hL!S(^}a{0L@{`Lo@^i`&9IVJvFNL+F~iGWo*S4a zoD*CW9&f}t;hyx)s_!}63bpfEG6b?4v_FY6tPYF+CEQ>&v6{WQq3Y}R=YbsG7)lrQ z3$I~3x9|5vj%y6}g<2E1FMK*J-w32;MY4D|-23~Fr%CmIhnwIVhP1w4ZUR8+a(4o& zKjg+XnKt7lw{YudC6q6W!RdP5JH z{_C7KxuvsX)up#u52jq&we6$BCQF75rg9P-GiHX&h>+&jsB%!@G4yW58uyCDB;wLet1IY&N-$)RhxNiroBJ! zR^1cwvlPvGA=h5bTPY;sduY<*f+Y_(tdSFNJ#?wbgN5_7w$pO&8$m+1H4pxp^G@r5 zWYzUo3AKH{jVylczpS!j+ELRta(v31w^hkfYbtrdgeD&UkKkP`qn)3ja2hVy@4Nm@oL8K5BDa ztL0jhkhTLO*8-rxar>QpsShm|J#V@b>QMBj=)c!4uIPrU58v&5=Q^)xc)F9(Z);UWz=Rk-C3b4Yx)EpTlAXD~4XC7YrsKb3p>Z zaR;6mlw7@H_K0CiTDg>sblsMV-^HIsJ1~|oNU>gE%s9n;<1X9$4ZU-pUMoHztZ|mdKI;Vst06Xu6q5uE@ literal 0 HcmV?d00001 diff --git a/pulsar/src/dock/sync_indicator.png b/pulsar/src/dock/sync_indicator.png new file mode 100644 index 0000000000000000000000000000000000000000..da155c58996b06a1548bf73f5aa124409f41f35c GIT binary patch literal 399 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5M?jcysy3fA0|TR@ zr;B4q#hkaZ4)QfC2)Lw6|NlSzSl(47(Z3KtgAY7zGRS9Hta7h4EY}i_>NGbNI%v z_3=`XlkIv_STuZ@{Tt78Z~wUdO7c_@3&xwwU&QQ|iY(y__)(->!IcuTW&4lX#YVhy z8rE?4-}$P!Bw-gr*^>26^O@d=%*k(07u!&Dxp;eC71IqCyZ-`-`JwK0R_Sv-*S`D4 zIYF?X)Ns$`zhaV%I&zu`Vc!`I8GEXkG#Qo8ys=ZzNGRoc!ty7n>^oy1qjs=@<^p%O z?~Ux7C!E3@ta&%>;^*LwXx-9qPkQN1ng8~ORI6v}&212c`wGpYx4A9u^S(RvjkAJz YGfQmyZmC`?U 0: + i['start'] = time.time() + i['duration'] -= (time.time() - i['start']) + rest.append(i) + self.draw_all() + self.motion_queue = rest + time.sleep(0.1) + + + def show(self, window, position: tuple): + if not self.is_hide: + window.blit(self.surface, position) + + def set_visible(self, newstat=True): + self.is_hide = newstat + + def set_position(self, newposition): + self.position = newposition + + def register(self, subname="", attr=None): + if subname == "": + subname = uuid.uuid4() + # use percent of frame size instead of pixels :) + attr['pos'] = list(attr['pos']) + attr['pos'][0] = round(attr['pos'][0] / 100 * self.size[0]) + attr['pos'][1] = round(attr['pos'][1] / 100 * self.size[1]) + attr['size'] = list(attr['size']) + attr['size'][0] = round(attr['size'][0] / 100 * self.size[0]) + attr['size'][1] = round(attr['size'][1] / 100 * self.size[1]) + self.components[subname] = attr + self.components_stat[subname] = 1 # by default, not hiding + + def draw(self, attr): + Graph.call(self, **attr) + + def set_component_visible(self, subname, newstat): + self.components_stat[subname] = newstat + + def draw_all(self): + for i in self.components.keys(): + if self.components_stat[i]: + self.draw(self.components[i]) + + def refresh(self, color=(0,0,0)): + self.surface.fill(color) + + def clear(self): + components = dict() + components_stat = dict() + + def loads(self, grap_str): + # TODO: 将会重写 以替代不安全的 eval + self.register(subname="", attr=(eval(grap_str))) + + def load(self, file="default.vgld", mode="a"): + # a: 增量加载 (默认) + # w: 覆盖式加载 + # 文件扩展名: vgld (矢量图形层描述文件) + if mode == 'w': + self.clear() + with open(file=file, mode="r+", encoding="UTF-8") as f: + for i in f.readlines(): + #print(i) + self.loads(i) + + +# 示例 +if __name__ == "__main__": + frame = None + def grap(): + global frame + pygame.init() + window = pygame.display.set_mode((1200, 900)) + frame = Frame("Test", (1200, 900)) + #frame.load() + frame.register(subname="test", attr={'method': 'rect', 'pos': (33, 33), 'size': (50, 50), 'color': (255, 255, 255)}) + #frame.move(subname='test', direction=0, length=90, duration=1, effect="linear") + running = True + while running: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + running = False + + window.fill((0, 0, 0)) + frame.show(window, (0, 0)) + pygame.display.flip() + pygame.time.delay(10) + pygame.quit() + def debug(): + global frame + while 1: + try: + e = input(">>>") + if e == "f": + e = "frame.move(subname='test', direction=0, length=3, duration=1, effect='linear')" + if e == "g": + e = "frame.move(subname='test', direction=180, length=3, duration=1, effect='linear')" + exec(e) + except: + print("ER") + grap_thd = threading.Thread(target=grap) + debug_thd = threading.Thread(target=debug) + grap_thd.start() + debug_thd.start() \ No newline at end of file diff --git a/testfield/vgl/vgllib.py b/testfield/vgl/vgllib.py index 46b1317..3edc89e 100644 --- a/testfield/vgl/vgllib.py +++ b/testfield/vgl/vgllib.py @@ -5,185 +5,85 @@ import uuid import time import threading import math +import copy -class Graph: - @staticmethod - def rect(frame, pos: tuple = (0, 0), size: tuple = (1, 1), color: tuple = (255, 255, 255), width: int = 0): - pygame.draw.rect(frame.surface, color=color, rect=(pos[0], pos[1], size[0], size[1]), width=width) - - @staticmethod - def line(frame, start_pos: tuple, end_pos: tuple, color: tuple = (255, 255, 255)): - pygame.draw.aaline(frame.surface, color, start_pos, end_pos) - - @staticmethod - def circle(frame, center: tuple, radius: int, color: tuple = (255, 255, 255), width: int = 0): - pygame.draw.circle(frame.surface, color, center, radius, width) - - @staticmethod - def ellipse(frame, pos: tuple = (0, 0), size: tuple = (1, 1), color: tuple = (255, 255, 255), width: int = 0): - rect=(pos[0], pos[1], size[0], size[1]) - pygame.draw.ellipse(frame.surface, color, rect, width) - - @staticmethod - def polygon(frame, pointlist: list, color: tuple = (255, 255, 255), width: int = 0): - pygame.draw.polygon(frame.surface, color, pointlist, width) - - @staticmethod - def arc(frame, pos: tuple = (0, 0), size: tuple = (1, 1), color: tuple = (255, 255, 255), start_angle: float = 0, stop_angle: float = 3.14, width: int = 1): - rect=(pos[0], pos[1], size[0], size[1]) - pygame.draw.arc(frame.surface, color, rect, start_angle, stop_angle, width) - - @staticmethod - def point(frame, pos: tuple, color: tuple = (255, 255, 255)): - pygame.draw.point(frame.surface, color, pos) - - @staticmethod - def lines(frame, pointlist: list, color: tuple = (255, 255, 255)): - pygame.draw.aalines(frame.surface, color, closed=False, points=pointlist) - - @staticmethod - def call(frame, method, **kwargs): - if hasattr(Graph, method): - getattr(Graph, method)(frame, **kwargs) - else: - print(f"方法 {method} 不存在") +class Aux(): + def gettime(): + return round(time.time(), 1) + def getprogress(task): + return (Aux.gettime() - task["start"] / task["duration"]) + def tuple_scale(tup, mul): + return (tup[0]*mul, tup[1]*mul) +class Element(object): + poscale: tuple = (0, 0) + is_hide = False + is_template = True + attached = None + tasks = dict() + def __init__(self, name="Element"): + self.name = name + def attach(self, clone_name, frame_object, poscale): + if clone_name == "": + clone_name = str(uuid.uuid4()) + clone = copy.deepcopy(self) + clone.poscale = poscale + clone.is_template = False + frame_object.elements[clone_name] = clone + def teleport(self, delta: tuple): + if not self.is_template: + self.poscale[0] += delta[0] + self.poscale[1] += delta[1] + def add_task(self, group, start_time, duration, **kwargs): + if group not in self.tasks(): + self.tasks[group] = list() + self.tasks[group].append({"start": start_time, "duration":duration, "para":kwargs}) + def update(): + pass class Frame(object): - components = dict() - components_stat = dict() - render_thread = None - motion_queue = list() - def __init__(self, name: str, size: tuple): + elements = dict() + is_hide = False + is_template = True + poscale: tuple = (0, 0) # 左上角, 对于每个实例的位置矢量 + def __init__(self, name="Frame", scale: tuple=(1, 1)): self.name = name + self.scale = scale + def attach(self, clone_name, window_object, poscale): + if clone_name == "": + clone_name = str(uuid.uuid4()) + clone = copy.deepcopy(self) + clone.poscale = poscale + clone.is_template = False + window_object.frames[clone_name] = clone + def render(): + pass + +class Window(object): + frames = list() + def __init__(self, title="Vector Graphic Layer Window", size: tuple=(1024,768)): + self.title = title self.size = size - self.surface = pygame.Surface(size, flags=pygame.HWSURFACE) - self.is_hide = False - print("初始化子模块") - self.render_thread = threading.Thread(target=self.render) - print("启动图形渲染子线程") - self.render_thread.start() - - def move(self, subname, direction, length, duration = 0, effect="linear"): # our powerful move! - # direction: 使用角度制, 以直角笛卡尔坐标系的x正半轴方向为0度, 逆时针为加, 接受负数 - # length: 百分数 - # duration: "动画"时间, 为0则即时 - # effect: "动画"效果, linear为线性移动, 或许会在未来增加贝塞尔曲线 - # TODO: 增加 bezier 曲线 - if duration == 0: - self.components[subname]["pos"][0] += math.cos(math.radians(direction)) * length / 100 * self.size[0] - self.components[subname]["pos"][1] += math.sin(math.radians(direction)) * length / 100 * self.size[1] - return - self.motion_queue.append({"subname":subname, "direction":direction, "length":length, "start":round(time.time(), 1), "duration":duration, "effect":"linear"}) - - def render(self): - while 1: - rest = list() - while self.motion_queue: - i = self.motion_queue.pop(0) # 从队列的开头移除元素 - self.move(subname=i['subname'], direction=i['direction'], - length=((time.time() - i['start']) / i['duration']) * i['length'], - duration=0) - if ((time.time() - i['start']) / i['duration']) > 0: - i['start'] = time.time() - i['duration'] -= (time.time() - i['start']) - rest.append(i) - self.draw_all() - self.motion_queue = rest - time.sleep(0.1) - - - def show(self, window, position: tuple): - if not self.is_hide: - window.blit(self.surface, position) - - def set_visible(self, newstat=True): - self.is_hide = newstat - - def set_position(self, newposition): - self.position = newposition - - def register(self, subname="", attr=None): - if subname == "": - subname = uuid.uuid4() - # use percent of frame size instead of pixels :) - attr['pos'] = list(attr['pos']) - attr['pos'][0] = round(attr['pos'][0] / 100 * self.size[0]) - attr['pos'][1] = round(attr['pos'][1] / 100 * self.size[1]) - attr['size'] = list(attr['size']) - attr['size'][0] = round(attr['size'][0] / 100 * self.size[0]) - attr['size'][1] = round(attr['size'][1] / 100 * self.size[1]) - self.components[subname] = attr - self.components_stat[subname] = 1 # by default, not hiding - - def draw(self, attr): - Graph.call(self, **attr) - - def set_component_visible(self, subname, newstat): - self.components_stat[subname] = newstat - - def draw_all(self): - for i in self.components.keys(): - if self.components_stat[i]: - self.draw(self.components[i]) - - def refresh(self, color=(0,0,0)): - self.surface.fill(color) - - def clear(self): - components = dict() - components_stat = dict() - - def loads(self, grap_str): - # TODO: 将会重写 以替代不安全的 eval - self.register(subname="", attr=(eval(grap_str))) - - def load(self, file="default.vgld", mode="a"): - # a: 增量加载 (默认) - # w: 覆盖式加载 - # 文件扩展名: vgld (矢量图形层描述文件) - if mode == 'w': - self.clear() - with open(file=file, mode="r+", encoding="UTF-8") as f: - for i in f.readlines(): - #print(i) - self.loads(i) - - -# 示例 -if __name__ == "__main__": - frame = None - def grap(): - global frame + self.running = 1 pygame.init() - window = pygame.display.set_mode((1200, 900)) - frame = Frame("Test", (1200, 900)) - #frame.load() - frame.register(subname="test", attr={'method': 'rect', 'pos': (33, 33), 'size': (50, 50), 'color': (255, 255, 255)}) - #frame.move(subname='test', direction=0, length=90, duration=1, effect="linear") - running = True - while running: + self.window = pygame.display.set_mode(size) + pygame.display.set_caption(title) + def set_title(self, title): + self.title = title + pygame.display.set_caption(title) + def start(self): + self.thr = threading.Thread(target=self.main_loop, name="main_loop") + self.thr.start() + def kill(self): + self.running = 0 + def main_loop(self): + while self.running: for event in pygame.event.get(): if event.type == pygame.QUIT: - running = False - - window.fill((0, 0, 0)) - frame.show(window, (0, 0)) + self.running = 0 + self.window.fill((0, 0, 0)) pygame.display.flip() pygame.time.delay(10) pygame.quit() - def debug(): - global frame - while 1: - try: - e = input(">>>") - if e == "f": - e = "frame.move(subname='test', direction=0, length=3, duration=1, effect='linear')" - if e == "g": - e = "frame.move(subname='test', direction=180, length=3, duration=1, effect='linear')" - exec(e) - except: - print("ER") - grap_thd = threading.Thread(target=grap) - debug_thd = threading.Thread(target=debug) - grap_thd.start() - debug_thd.start() \ No newline at end of file + +if __name__ == "__main__": + pass \ No newline at end of file