diff --git a/Difficult_Rocket/gui/widget/button.py b/Difficult_Rocket/gui/widget/button.py index 0239570..b02adc9 100644 --- a/Difficult_Rocket/gui/widget/button.py +++ b/Difficult_Rocket/gui/widget/button.py @@ -26,25 +26,21 @@ from Difficult_Rocket.api.types import Options, FontData RGBA = Tuple[int, int, int, int] -class ButtonDrawTheme: +class BaseButtonTheme: """ - 直接绘制按钮的风格 + 按钮的风格 """ + name = "BaseButtonTheme" - name = "ButtonDrawTheme" - - def __init__(self, batch: Batch, group: Group): + def __init__(self, x: int, y: int, + width: int, height: int, + batch: Batch, group: Group): self.batch = batch self.group = group - a = (72, 73, 74) - b = (109, 109, 110) - c = (88, 91, 92) - d = (124, 124, 125) - e = (49, 50, 51) - touch_a = (49, 50, 51) - touch_b = (90, 91, 92) - touch_c = (71, 72, 72) - touch_d = (106, 107, 108) + self.x = x + self.y = y + self.width = width + self.height = height def on_touch(self, x, y) -> None: """ @@ -75,6 +71,93 @@ class ButtonDrawTheme: """ +class MinecraftWikiButtonTheme(BaseButtonTheme): + """ + 直接绘制按钮的风格 + """ + + name = "MinecraftWikiButtonTheme" + + def __init__(self, x: int, y: int, + width: int, height: int, + batch: Batch, group: Group): + super().__init__(x, y, width, height, batch, group) + self.batch = batch + self.group = group + a = (72, 73, 74, 255) + b = (109, 109, 110, 255) + c = (88, 91, 92, 255) + d = (124, 124, 125, 255) # 左下和右上两个重叠点的颜色.... 画吗? + e = (49, 50, 51, 255) + touch_a = (49, 50, 51, 255) + touch_b = (90, 91, 92, 255) + touch_c = (71, 72, 72, 255) + touch_d = (106, 107, 108, 255) # 同上 + pad = 2 # 边框宽度 2 px + list_pad = 4 # 下巴 4px + # 主背景 + self.back_ground = Rectangle(x=x, y=y, + width=width, height=height, + color=a, batch=batch, group=Group(order=0, parent=group)) + # 左上方向的覆盖 + self.cover_back = Rectangle(x=x, y=y + pad + list_pad, + width=width - pad, height=height - pad - list_pad, + color=b, batch=batch, group=Group(order=1, parent=group)) + # 右下方向的覆盖 + self.cover_back2 = Rectangle(x=x + pad, y=y + pad + list_pad, + width=width - (pad * 2), height=height - (pad * 2) - list_pad, + color=c, batch=batch, group=Group(order=2, parent=group)) + # 下巴的框 + self.list_back = Rectangle(x=x, y=y, + width=width, height=list_pad, + color=e, batch=batch, group=Group(order=1, parent=group)) + self.a = a + self.b = b + self.c = c + self.d = d + self.e = e + self.touch_a = touch_a + self.touch_b = touch_b + self.touch_c = touch_c + self.touch_d = touch_d + self.pad = pad + self.list_pad = list_pad + + def on_touch(self, x, y) -> None: + """ + 当鼠标在按钮上的时候 + :param x: 鼠标绝对位置 + :param y: 鼠标绝对位置 + :return: + """ + + def on_move_away(self) -> None: + """ + 当鼠标移出按钮的时候 + :return: + """ + + def on_hit(self, x: int, y: int) -> None: + """ + 当鼠标点击按钮的时候 + :param x: 鼠标绝对位置 + :param y: 鼠标绝对位置 + :return: + """ + self.back_ground.color = self.touch_a + self.cover_back.color = self.touch_b + self.cover_back2.color = self.touch_c + + def on_release(self) -> None: + """ + 当鼠标松开按钮的时候 + :return: + """ + self.back_ground.color = self.a + self.cover_back.color = self.b + self.cover_back2.color = self.c + + class ButtonThemeOptions(Options): """基于 Options 写的 ButtonTheme""" @@ -103,6 +186,7 @@ class PressTextButton(widgets.WidgetBase): batch: Optional[Batch] = None, group: Optional[Group] = None, theme: Optional[ButtonThemeOptions] = None, + draw_theme: Optional[type(BaseButtonTheme)] = None, ): super().__init__(x, y, width, height) self.main_batch = batch or Batch() @@ -125,7 +209,7 @@ class PressTextButton(widgets.WidgetBase): batch=self.main_batch, group=self.front_group, x=self._x, - y=self._y, + y=self._y + 4, width=self._width, height=self._height, ) @@ -137,15 +221,26 @@ class PressTextButton(widgets.WidgetBase): stretch=self.theme.font_theme.stretch, ) self.font_height = self.font.ascent - self.font.descent - self.back_rec = Rectangle( - x=self._x, - y=self._y, - width=self._width, - height=self._height, - color=self.untouched_color, # ImGui color - batch=self.main_batch, - group=self.back_ground_group, - ) + if draw_theme is None: + self.back_rec = Rectangle( + x=self._x, + y=self._y, + width=self._width, + height=self._height, + color=self.untouched_color, # ImGui color + batch=self.main_batch, + group=self.back_ground_group, + ) + self.draw_theme = False + else: + self.draw_theme = draw_theme( + x=self._x, + y=self._y, + width=self._width, + height=self._height, + batch=self.main_batch, + group=self.back_ground_group, + ) self.value = text # 重新分配一下高度和宽度的位置 @@ -160,34 +255,70 @@ class PressTextButton(widgets.WidgetBase): text_width = self.text_label.content_width self.text_label.x = self._x + (self.width - text_width) // 2 self.text_label.y = ( - self._y + (self.height - self.font_height) // 2 + (self.font_height * 0.2) + self._y + (self.height - self.font_height) // 2 + (self.font_height * 0.2) + 4 ) # 修正一下位置 - def __contains__(self, item): - return item in self.back_rec + @property + def batch(self) -> Batch: + return self.main_batch + + @batch.setter + def batch(self, value: Batch): + assert isinstance(value, Batch), "batch must be a pyglet.graphics.Batch" + self.main_batch = value + self.text_label.batch = value + self.back_rec.batch = value + self.user_batch = True + + def __contains__(self, point): + if self.draw_theme: + x, y = self.x, self.y + return x < point[0] < x + self._width and y < point[1] < y + self._height + return point in self.back_rec def on_draw(self): if not self.user_batch: self.main_batch.draw() def on_mouse_motion(self, x, y, dx, dy): - if (x, y) in self.back_rec: - self.back_rec.color = self.touched_color + if (x, y) in self: + if self.draw_theme: + ... + else: + self.back_rec.color = self.touched_color else: self.pressed = False - self.back_rec.color = self.untouched_color + if self.draw_theme: + self.draw_theme.on_move_away() + self.draw_theme.on_release() + else: + self.back_rec.color = self.untouched_color def on_mouse_press(self, x, y, buttons, modifiers) -> bool: - if (x, y) in self and buttons == mouse.LEFT: - self.back_rec.color = self.hit_color - self.dispatch_event("on_press", x, y) - self.pressed = True - return True + if (x, y) in self: + if buttons == mouse.LEFT: + if self.draw_theme: + self.draw_theme.on_hit(x, y) + else: + self.back_rec.color = self.hit_color + self.dispatch_event("on_press", x, y) + self.pressed = True + return True + else: + self.pressed = False + if self.draw_theme: + self.draw_theme.on_release() + else: + self.back_rec.color = self.untouched_color + self.dispatch_event("on_release", x, y) return False def on_mouse_release(self, x, y, buttons, modifiers): if self.pressed and (x, y) in self: - self.back_rec.color = self.touched_color + if self.draw_theme: + self.draw_theme.on_release() + else: + self.back_rec.color = self.touched_color self.pressed = False def _update_position(self): @@ -198,3 +329,4 @@ class PressTextButton(widgets.WidgetBase): PressTextButton.register_event_type("on_press") +PressTextButton.register_event_type("on_release") diff --git a/config/main.toml b/config/main.toml index 606d31c..e8496bc 100644 --- a/config/main.toml +++ b/config/main.toml @@ -7,8 +7,8 @@ fonts_folder = "assets/fonts" [window] style = "None" -width = 1569 -height = 1298 +width = 1003 +height = 632 visible = true gui_scale = 1 caption = "Difficult Rocket v{DR_version}" diff --git a/mods/dr_game/__init__.py b/mods/dr_game/__init__.py index d1c4841..6579003 100644 --- a/mods/dr_game/__init__.py +++ b/mods/dr_game/__init__.py @@ -93,9 +93,13 @@ class DR_mod(ModInfo): # NOQA def on_client_start(self, game: Game, client: ClientWindow): from .sr1_ship import SR1ShipRender + from .menu import Menu + + client.add_sub_screen("DR_game_menu", Menu) + logger.info("added dr_game_menu screen", tag="dr_game") client.add_sub_screen("SR1_ship", SR1ShipRender) - logger.info("on_client_start added sub screen") + logger.info("added SR1_ship screen", tag="dr_game") def on_unload(self, game: Game): game.client.window.screen_list.pop("SR1_ship") diff --git a/mods/dr_game/menu.py b/mods/dr_game/menu.py index b7914cf..0ed1272 100644 --- a/mods/dr_game/menu.py +++ b/mods/dr_game/menu.py @@ -9,6 +9,8 @@ from pyglet.graphics import Batch, Group from Difficult_Rocket.client import ClientWindow from Difficult_Rocket.api.screen import BaseScreen +from Difficult_Rocket.gui.widget.button import PressTextButton, MinecraftWikiButtonTheme + # from . import DR_mod_runtime @@ -26,3 +28,30 @@ class Menu(BaseScreen): # 占位, 高二看看能不能咕出来点啥 (20230911) # 欸呀, 正好是 911 纪念日哦 + # 好, 高二 第一学期 期末都考完了, 我过来做测试了 (20240119) + + self.main_button = PressTextButton( + x=200, + y=300, + width=150, + height=30, + text="test button", + batch=self.main_batch, + group=self.main_group, + draw_theme=MinecraftWikiButtonTheme, + ) + self.button2 = PressTextButton( + x=200, + y=200, + width=150, + height=30, + text="test button", + batch=self.main_batch, + group=self.main_group, + ) + main_window.push_handlers(self.main_button) + main_window.push_handlers(self.button2) + + def on_draw(self, dt: float, window: ClientWindow): + self.main_batch.draw() + diff --git a/mods/dr_game/sr1_ship.py b/mods/dr_game/sr1_ship.py index 389a2aa..64a1f78 100644 --- a/mods/dr_game/sr1_ship.py +++ b/mods/dr_game/sr1_ship.py @@ -126,18 +126,6 @@ class SR1ShipRender(BaseScreen): ) self.render_d_label.visible = self.status.draw_d_pos - self.test_button = PressTextButton( - x=100, - y=100, - width=150, - height=30, - text="test button", - batch=self.main_batch, - group=Group(5, parent=main_window.main_group), - ) - # self.test_button.push_handlers(main_window) - main_window.push_handlers(self.test_button) - # Optional data self.textures: SR1Textures = SR1Textures() self.gen_draw: Optional[Generator] = None @@ -442,7 +430,6 @@ class SR1ShipRender(BaseScreen): return self.render_d_line.x2 = width // 2 self.render_d_line.y2 = height // 2 - self.test_button._update_position() def on_mouse_scroll( self, x: int, y: int, scroll_x: int, scroll_y: int, window: ClientWindow