ya2 · news · projects · code · about

housekeeping: ya2.utils.gui
[pmachines.git] / ya2 / utils / gui / cursor.py
1 from dataclasses import dataclass
2 from panda3d.core import WindowProperties, Texture
3 from direct.gui.OnscreenImage import OnscreenImage
4 from ya2.utils.logics import LogicsTools
5
6
7 @dataclass
8 class MouseCursorArgs:
9 image_path: ...
10 functional_test: ...
11 scale: ... = 1
12 color: ... = (1, 1, 1, 1)
13 hotspot_position: ... = (0, 0)
14
15
16 class MouseCursor:
17
18 def __init__(self, info):
19 self.__functional_test = info.functional_test
20 if not info.image_path: return
21 self.__hide_system_cursor()
22 self.__set_image(info.image_path, info.scale, info.color)
23 self.__set_hotspot(info.hotspot_position, info.scale)
24 self._tsk = taskMgr.add(self.__on_frame, 'on_frame_cursor')
25
26 def __hide_system_cursor(self):
27 p = WindowProperties()
28 p.set_cursor_hidden(True)
29 if LogicsTools.windowed: base.win.request_properties(p)
30
31 def __set_image(self, image_path, scale, color):
32 self.__image = OnscreenImage(image_path, scale=scale)
33 self.__image.set_color(color)
34 self.__image.set_bin('gui-popup', 50)
35 alpha_formats = [Texture.FRgba]
36 if self.__image.get_texture().get_format() in alpha_formats:
37 self.__image.set_transparency(True)
38
39 def __set_hotspot(self, hotspot_position, scale):
40 self.__hotspot_dx = scale[0] * (1 - 2 * hotspot_position[0])
41 self.__hotspot_dy = scale[2] * (1 - 2 * hotspot_position[1])
42
43 def __on_frame(self, task):
44 m = base.mouseWatcherNode
45 if not m or not m.hasMouse(): return task.again
46 mouse = m.get_mouse_x(), m.get_mouse_y()
47 h_x = mouse[0] * base.get_aspect_ratio() + self.__hotspot_dx
48 self.__image.set_pos((h_x, 1, mouse[1] - self.__hotspot_dy))
49 return task.again
50
51 def set_image(self, image):
52 self.__image.set_texture(loader.load_texture(image), 1)
53
54 def set_color(self, color):
55 self.__image.set_color(color)
56
57 def show(self):
58 if not self.__functional_test: return self.__image.show()
59
60 def hide(self):
61 return self.__image.hide()
62
63 def destroy(self):
64 taskMgr.remove(self._tsk)
65 self.__image.destroy()