sverpykit 0.1.14__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sverpykit-0.1.14/PKG-INFO +4 -0
- sverpykit-0.1.14/README.md +10 -0
- sverpykit-0.1.14/pyproject.toml +10 -0
- sverpykit-0.1.14/setup.cfg +4 -0
- sverpykit-0.1.14/sverpykit/Collide/Collide.py +13 -0
- sverpykit-0.1.14/sverpykit/Draw/Draw.py +123 -0
- sverpykit-0.1.14/sverpykit/Ui/Button.py +134 -0
- sverpykit-0.1.14/sverpykit/Ui/DropDown.py +144 -0
- sverpykit-0.1.14/sverpykit/Ui/SearchBar.py +110 -0
- sverpykit-0.1.14/sverpykit/Ui/TextBlock.py +22 -0
- sverpykit-0.1.14/sverpykit/Ui/Window.py +138 -0
- sverpykit-0.1.14/sverpykit/__init__.py +25 -0
- sverpykit-0.1.14/sverpykit/core/Config.py +40 -0
- sverpykit-0.1.14/sverpykit/core/Runtime.py +62 -0
- sverpykit-0.1.14/sverpykit/core/initialize.py +82 -0
- sverpykit-0.1.14/sverpykit.egg-info/PKG-INFO +4 -0
- sverpykit-0.1.14/sverpykit.egg-info/SOURCES.txt +18 -0
- sverpykit-0.1.14/sverpykit.egg-info/dependency_links.txt +1 -0
- sverpykit-0.1.14/sverpykit.egg-info/requires.txt +1 -0
- sverpykit-0.1.14/sverpykit.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Sverrys PygameTools
|
|
2
|
+
Sverrys PygameTools is a wrapper for the library "pygame" that adds a basic runtime and UI logic.
|
|
3
|
+
|
|
4
|
+
How to use:<br>
|
|
5
|
+
To use Sverrys PygameTools you must install it from github by executing this command
|
|
6
|
+
in your terminal:<br>
|
|
7
|
+
`python3 -m pip install git+https://github.com/Sverryboiii/PygameTools.git`.<br>
|
|
8
|
+
This will install all the files from the directory `sverpykit`.
|
|
9
|
+
|
|
10
|
+
Huge thank you to the developers of pygame and python. Without you all this wouldn't be possible!
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
from sverpykit.core import Config
|
|
2
|
+
import pygame
|
|
3
|
+
|
|
4
|
+
def draw_rect(
|
|
5
|
+
display: pygame.Surface,
|
|
6
|
+
color: tuple[int, int, int] | pygame.color.Color,
|
|
7
|
+
rectangle: pygame.Rect,
|
|
8
|
+
width: int = 0,
|
|
9
|
+
border_radius: int = 0,
|
|
10
|
+
border_top_left_radius: int = 0,
|
|
11
|
+
border_top_right_radius: int = 0,
|
|
12
|
+
border_bottom_left_radius: int = 0,
|
|
13
|
+
border_bottom_right_radius: int = 0
|
|
14
|
+
) -> None:
|
|
15
|
+
"""
|
|
16
|
+
:param display: The output surface.
|
|
17
|
+
:param color: The color of the rectangle.
|
|
18
|
+
:param rectangle: The dimensions of the rectangle.
|
|
19
|
+
:param width: The width of the rectangle border (Turns the rectangle itself into the border).
|
|
20
|
+
:param border_radius: The rounding of all corners.
|
|
21
|
+
:param border_top_left_radius: The rounding of the top-left corner.
|
|
22
|
+
:param border_top_right_radius: The rounding of the top-right corner.
|
|
23
|
+
:param border_bottom_left_radius: The rounding of the bottom-left corner.
|
|
24
|
+
:param border_bottom_right_radius: The rounding of the bottom-right corner.
|
|
25
|
+
"""
|
|
26
|
+
if any([border_top_left_radius, border_top_right_radius, border_bottom_left_radius, border_bottom_right_radius]):
|
|
27
|
+
pygame.draw.rect(
|
|
28
|
+
surface=display,
|
|
29
|
+
color=color,
|
|
30
|
+
rect=rectangle,
|
|
31
|
+
width=width,
|
|
32
|
+
border_radius=border_radius,
|
|
33
|
+
border_top_left_radius=border_top_left_radius,
|
|
34
|
+
border_top_right_radius=border_top_right_radius,
|
|
35
|
+
border_bottom_left_radius=border_bottom_left_radius,
|
|
36
|
+
border_bottom_right_radius=border_bottom_right_radius
|
|
37
|
+
)
|
|
38
|
+
return
|
|
39
|
+
pygame.draw.rect(
|
|
40
|
+
surface=display,
|
|
41
|
+
color=color,
|
|
42
|
+
rect=rectangle,
|
|
43
|
+
width=width,
|
|
44
|
+
border_radius=border_radius
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
def draw_circle(
|
|
48
|
+
display: pygame.Surface,
|
|
49
|
+
color: pygame.Color | tuple[int, int, int],
|
|
50
|
+
center: tuple[int, int],
|
|
51
|
+
radius: float | int,
|
|
52
|
+
width: int,
|
|
53
|
+
draw_top_left: bool = False,
|
|
54
|
+
draw_top_right: bool = False,
|
|
55
|
+
draw_bottom_left: bool = False,
|
|
56
|
+
draw_bottom_right: bool = False,
|
|
57
|
+
):
|
|
58
|
+
"""
|
|
59
|
+
:param display: The surface the circle gets drawn on.
|
|
60
|
+
:param color: The color of the circle.
|
|
61
|
+
:param center: The center position of the circle.
|
|
62
|
+
:param radius: The radius of the circle.
|
|
63
|
+
:param width: How thick the edges of the circle are (0 is full circle).
|
|
64
|
+
|
|
65
|
+
:param draw_top_left: Decides if pygame draws the top left segment. (If this and the next 3 are False the whole circle gets drawn.
|
|
66
|
+
:param draw_top_right: Decides if pygame draws the top right segment.
|
|
67
|
+
:param draw_bottom_left: Decides if pygame draws the bottom left segment.
|
|
68
|
+
:param draw_bottom_right: Decides if pygame draws the bottom right segment.
|
|
69
|
+
:return:
|
|
70
|
+
"""
|
|
71
|
+
pygame.draw.circle(
|
|
72
|
+
surface=display,
|
|
73
|
+
color=color,
|
|
74
|
+
center=center,
|
|
75
|
+
radius=radius,
|
|
76
|
+
width=width,
|
|
77
|
+
draw_top_left=draw_top_left,
|
|
78
|
+
draw_top_right=draw_top_right,
|
|
79
|
+
draw_bottom_left=draw_bottom_left,
|
|
80
|
+
draw_bottom_right=draw_bottom_right
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
def draw_surface(
|
|
84
|
+
surface: pygame.Surface,
|
|
85
|
+
destination: tuple[float | int, float | int],
|
|
86
|
+
area: pygame.Rect | None = None,
|
|
87
|
+
special_flags: int = 0,
|
|
88
|
+
display=None
|
|
89
|
+
) -> None:
|
|
90
|
+
"""
|
|
91
|
+
:param surface: The surface to draw the surface on.
|
|
92
|
+
:param destination: The x and y coordinate of the surface.
|
|
93
|
+
:param area: Where the surface gets cut off.
|
|
94
|
+
:param special_flags: How the colors are shown.
|
|
95
|
+
:param display: The surface that will be used to draw on.
|
|
96
|
+
"""
|
|
97
|
+
if not display:
|
|
98
|
+
display = Config.screen
|
|
99
|
+
display.blit(
|
|
100
|
+
source=surface,
|
|
101
|
+
dest=destination,
|
|
102
|
+
area=area,
|
|
103
|
+
special_flags=special_flags
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
def render_text(
|
|
107
|
+
text: str,
|
|
108
|
+
antialias: bool = True,
|
|
109
|
+
color: pygame.Color | tuple[int, int, int] = Config.BEIGE,
|
|
110
|
+
name: str = "default"
|
|
111
|
+
) -> pygame.Surface:
|
|
112
|
+
"""
|
|
113
|
+
:param text: The text displayed.
|
|
114
|
+
:param antialias: Blends outer edges of the text, so it looks smoother.
|
|
115
|
+
:param color: The color of the text.
|
|
116
|
+
:param name: Choose what font you want to use. (Must be initialized as font)
|
|
117
|
+
:return: Returns the surface so you can use it in Draw.draw_surface().
|
|
118
|
+
"""
|
|
119
|
+
return Config.fonts[name].render(
|
|
120
|
+
text,
|
|
121
|
+
antialias,
|
|
122
|
+
color
|
|
123
|
+
)
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
from sverpykit.Draw import Draw
|
|
2
|
+
from sverpykit.core import Config
|
|
3
|
+
from typing import Any, Callable
|
|
4
|
+
import pygame
|
|
5
|
+
|
|
6
|
+
button_border_width = 3
|
|
7
|
+
color_change_when_pressed = 30
|
|
8
|
+
|
|
9
|
+
class Button:
|
|
10
|
+
def __init__(
|
|
11
|
+
self,
|
|
12
|
+
*args,
|
|
13
|
+
rect: pygame.Rect,
|
|
14
|
+
button_color: tuple[int, int, int] | pygame.Color,
|
|
15
|
+
|
|
16
|
+
surface: pygame.Surface,
|
|
17
|
+
|
|
18
|
+
display: pygame.Surface,
|
|
19
|
+
|
|
20
|
+
function: Callable = lambda : None,
|
|
21
|
+
rounding: int = 0,
|
|
22
|
+
resize_surface: bool = False,
|
|
23
|
+
alpha_surface: bool = True,
|
|
24
|
+
center_surface: bool = True,
|
|
25
|
+
**kwargs
|
|
26
|
+
):
|
|
27
|
+
"""
|
|
28
|
+
:param rect: A rectangle made with pygame.Rect.
|
|
29
|
+
:param button_color: The background color of the button.
|
|
30
|
+
:param display: The surface where the button gets placed on (Most of the time just the base display).
|
|
31
|
+
:param surface: A surface of any kind (Text, Image, Even a surface with a rectangle).
|
|
32
|
+
:param rounding: How much the corners of the button is rounded.
|
|
33
|
+
:param resize_surface: Resize the screen to the highest resolution possible for the button (Could mess up the surface).
|
|
34
|
+
:param alpha_surface: If the background of the surface is invisible (Not needed if the surface is already alpha or
|
|
35
|
+
if you rendered a text).
|
|
36
|
+
:param center_surface: If the surface should be centered or just be at the 0,0 coordinate of the button.
|
|
37
|
+
:param function: This function gets executed when you release the button.
|
|
38
|
+
:param args: Used as arguments for the function of the button.
|
|
39
|
+
:param kwargs: Used as key-word arguments for the function of the button.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
self.display = display
|
|
43
|
+
|
|
44
|
+
self.button_color = button_color
|
|
45
|
+
|
|
46
|
+
self.rect = rect
|
|
47
|
+
self.hitbox_offset = (0, 0)
|
|
48
|
+
self.rounding = rounding
|
|
49
|
+
|
|
50
|
+
self.function = function
|
|
51
|
+
self.args = args
|
|
52
|
+
self.kwargs = kwargs
|
|
53
|
+
|
|
54
|
+
self.surf = surface
|
|
55
|
+
self.resize_surf = resize_surface
|
|
56
|
+
self.alpha_surface = alpha_surface
|
|
57
|
+
self.center_surf = center_surface
|
|
58
|
+
|
|
59
|
+
self.pressed = False
|
|
60
|
+
|
|
61
|
+
def draw(self, display=None) -> None:
|
|
62
|
+
if not display:
|
|
63
|
+
display = self.display
|
|
64
|
+
|
|
65
|
+
# Background
|
|
66
|
+
Draw.draw_rect(
|
|
67
|
+
display=display,
|
|
68
|
+
color=self.button_color if not self.pressed else (
|
|
69
|
+
max(0, self.button_color[0] - 30),
|
|
70
|
+
max(0, self.button_color[1] - 30),
|
|
71
|
+
max(0, self.button_color[2] - 30)
|
|
72
|
+
),
|
|
73
|
+
rectangle=self.rect,
|
|
74
|
+
border_radius=self.rounding
|
|
75
|
+
)
|
|
76
|
+
Draw.draw_rect(
|
|
77
|
+
display=display,
|
|
78
|
+
color=(
|
|
79
|
+
max(0, self.button_color[0] + color_change_when_pressed),
|
|
80
|
+
max(0, self.button_color[1] + color_change_when_pressed),
|
|
81
|
+
max(0, self.button_color[2] + color_change_when_pressed)
|
|
82
|
+
),
|
|
83
|
+
rectangle=self.rect,
|
|
84
|
+
width=button_border_width,
|
|
85
|
+
border_radius=self.rounding
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
# Text
|
|
89
|
+
Draw.draw_surface(
|
|
90
|
+
surface=self.surf,
|
|
91
|
+
destination=(0,0) if not self.center_surf else (
|
|
92
|
+
self.rect.x + self.rect.w/2 - self.surf.get_width()/2,
|
|
93
|
+
self.rect.y + self.rect.h/2 - self.surf.get_height()/2
|
|
94
|
+
),
|
|
95
|
+
display=display
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
def events(self) -> Any | None:
|
|
99
|
+
"""
|
|
100
|
+
:return: Will return None unless pressed and released (In that case it will return the returned value of the function)
|
|
101
|
+
"""
|
|
102
|
+
mp = pygame.mouse.get_pos()
|
|
103
|
+
click = False
|
|
104
|
+
for event in Config.events:
|
|
105
|
+
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
|
|
106
|
+
click = True
|
|
107
|
+
|
|
108
|
+
if self.pressed:
|
|
109
|
+
if not click or not pygame.Rect(
|
|
110
|
+
self.rect.x + self.hitbox_offset[0],
|
|
111
|
+
self.rect.y + self.hitbox_offset[1],
|
|
112
|
+
self.rect.w,
|
|
113
|
+
self.rect.h
|
|
114
|
+
).collidepoint(mp):
|
|
115
|
+
self.pressed = False
|
|
116
|
+
return self.function(*self.args, **self.kwargs)
|
|
117
|
+
return None
|
|
118
|
+
|
|
119
|
+
if not click:
|
|
120
|
+
return None
|
|
121
|
+
|
|
122
|
+
if pygame.Rect(
|
|
123
|
+
self.rect.x + self.hitbox_offset[0],
|
|
124
|
+
self.rect.y + self.hitbox_offset[1],
|
|
125
|
+
self.rect.w,
|
|
126
|
+
self.rect.h
|
|
127
|
+
).collidepoint(mp):
|
|
128
|
+
self.pressed = True
|
|
129
|
+
return None
|
|
130
|
+
|
|
131
|
+
def update(self) -> Any | None:
|
|
132
|
+
value = self.events()
|
|
133
|
+
self.draw()
|
|
134
|
+
return value
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
from sverpykit.Collide import Collide
|
|
2
|
+
from sverpykit.Draw import Draw
|
|
3
|
+
from sverpykit.core import Config
|
|
4
|
+
from typing import Any
|
|
5
|
+
import pygame
|
|
6
|
+
|
|
7
|
+
class DropDown:
|
|
8
|
+
def __init__(
|
|
9
|
+
self,
|
|
10
|
+
rect: pygame.Rect,
|
|
11
|
+
display: pygame.Surface,
|
|
12
|
+
choices: list[Any],
|
|
13
|
+
color: pygame.Color | tuple[int, int, int] = (50, 50, 50),
|
|
14
|
+
font: str = "default"
|
|
15
|
+
):
|
|
16
|
+
self.rect = rect
|
|
17
|
+
self.hitbox_offset = (0, 0)
|
|
18
|
+
self.font = font
|
|
19
|
+
|
|
20
|
+
self.display = display
|
|
21
|
+
self.color = color
|
|
22
|
+
self.choices = choices
|
|
23
|
+
self.choice_rects = []
|
|
24
|
+
for i in range(len(self.choices)):
|
|
25
|
+
self.choice_rects.append(pygame.Rect(
|
|
26
|
+
self.rect.x,
|
|
27
|
+
self.rect.y + i*self.rect.h + self.rect.h,
|
|
28
|
+
self.rect.w,
|
|
29
|
+
self.rect.h
|
|
30
|
+
))
|
|
31
|
+
|
|
32
|
+
self.selected: Any = ""
|
|
33
|
+
self.opened: bool = False
|
|
34
|
+
self.pressed: bool = False
|
|
35
|
+
|
|
36
|
+
def draw(self, display=None) -> None:
|
|
37
|
+
if not display:
|
|
38
|
+
display = self.display
|
|
39
|
+
|
|
40
|
+
Draw.draw_rect(
|
|
41
|
+
display=display,
|
|
42
|
+
color=self.color,
|
|
43
|
+
rectangle=self.rect,
|
|
44
|
+
border_radius=10,
|
|
45
|
+
)
|
|
46
|
+
Draw.draw_rect(
|
|
47
|
+
display=display,
|
|
48
|
+
color=(
|
|
49
|
+
self.color[0] + 30,
|
|
50
|
+
self.color[1] + 30,
|
|
51
|
+
self.color[2] + 30
|
|
52
|
+
),
|
|
53
|
+
rectangle=self.rect,
|
|
54
|
+
border_radius=10,
|
|
55
|
+
width=3
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
Draw.draw_surface(
|
|
59
|
+
Draw.render_text(
|
|
60
|
+
str(self.selected),
|
|
61
|
+
True,
|
|
62
|
+
Config.BEIGE,
|
|
63
|
+
self.font
|
|
64
|
+
), (
|
|
65
|
+
self.rect.x+10, self.rect.y-3
|
|
66
|
+
),
|
|
67
|
+
display=display
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
if not self.opened:
|
|
71
|
+
return
|
|
72
|
+
|
|
73
|
+
for c, rect in enumerate(self.choice_rects):
|
|
74
|
+
Draw.draw_rect(
|
|
75
|
+
display=display,
|
|
76
|
+
color=(
|
|
77
|
+
min(255, self.color[0] + 30),
|
|
78
|
+
min(255, self.color[1] + 30),
|
|
79
|
+
min(255, self.color[2] + 30)
|
|
80
|
+
),
|
|
81
|
+
rectangle=rect,
|
|
82
|
+
border_radius=10
|
|
83
|
+
)
|
|
84
|
+
Draw.draw_rect(
|
|
85
|
+
display=display,
|
|
86
|
+
color=(
|
|
87
|
+
min(255, self.color[0] + 60),
|
|
88
|
+
min(255, self.color[1] + 60),
|
|
89
|
+
min(255, self.color[2] + 60)
|
|
90
|
+
),
|
|
91
|
+
rectangle=rect,
|
|
92
|
+
border_radius=10,
|
|
93
|
+
width=3
|
|
94
|
+
)
|
|
95
|
+
text = Draw.render_text(
|
|
96
|
+
text=str(self.choices[c]),
|
|
97
|
+
antialias=True,
|
|
98
|
+
color=Config.BEIGE,
|
|
99
|
+
name=self.font
|
|
100
|
+
)
|
|
101
|
+
Draw.draw_surface(text, (rect.x+10, rect.y-3), display=display)
|
|
102
|
+
|
|
103
|
+
def events(self) -> Any | None:
|
|
104
|
+
mp = pygame.mouse.get_pos()
|
|
105
|
+
click = False
|
|
106
|
+
for event in Config.events:
|
|
107
|
+
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
|
|
108
|
+
click = True
|
|
109
|
+
|
|
110
|
+
if not click:
|
|
111
|
+
self.pressed = False
|
|
112
|
+
|
|
113
|
+
if self.opened and click:
|
|
114
|
+
for count, rect in enumerate(self.choice_rects):
|
|
115
|
+
if not Collide.rect_point(pygame.Rect(
|
|
116
|
+
self.rect.x + self.hitbox_offset[0],
|
|
117
|
+
self.rect.y + self.hitbox_offset[1],
|
|
118
|
+
self.rect.w,
|
|
119
|
+
self.rect.h
|
|
120
|
+
), mp):
|
|
121
|
+
continue
|
|
122
|
+
self.selected = self.choices[count]
|
|
123
|
+
self.opened = False
|
|
124
|
+
|
|
125
|
+
if Collide.rect_point(pygame.Rect(
|
|
126
|
+
self.rect.x + self.hitbox_offset[0],
|
|
127
|
+
self.rect.y + self.hitbox_offset[1],
|
|
128
|
+
self.rect.w,
|
|
129
|
+
self.rect.h
|
|
130
|
+
), mp) and click:
|
|
131
|
+
if self.pressed:
|
|
132
|
+
return False
|
|
133
|
+
self.opened = not self.opened
|
|
134
|
+
self.pressed = True
|
|
135
|
+
elif click:
|
|
136
|
+
self.opened = False
|
|
137
|
+
|
|
138
|
+
return None
|
|
139
|
+
|
|
140
|
+
def update(self, check_events: bool = True) -> Any | None:
|
|
141
|
+
value = None
|
|
142
|
+
if check_events: value = self.events()
|
|
143
|
+
self.draw()
|
|
144
|
+
return value
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
from sverpykit.Collide import Collide
|
|
2
|
+
from sverpykit.Draw import Draw
|
|
3
|
+
from sverpykit.core import Config
|
|
4
|
+
import pygame
|
|
5
|
+
from typing import Any, Callable
|
|
6
|
+
|
|
7
|
+
class SearchBar:
|
|
8
|
+
def __init__(
|
|
9
|
+
self,
|
|
10
|
+
*args,
|
|
11
|
+
rect: pygame.Rect,
|
|
12
|
+
display: pygame.Surface,
|
|
13
|
+
function: Callable = lambda : None,
|
|
14
|
+
color: pygame.Color | tuple[int, int, int] = (50, 50, 50),
|
|
15
|
+
**kwargs
|
|
16
|
+
):
|
|
17
|
+
self.rect: pygame.Rect = rect
|
|
18
|
+
self.hitbox_offset = (0, 0)
|
|
19
|
+
|
|
20
|
+
self.display: pygame.Surface = display
|
|
21
|
+
self.color: pygame.Color | tuple[int, int, int] = color
|
|
22
|
+
|
|
23
|
+
self.stored: str = ""
|
|
24
|
+
self.last_stored: str = ""
|
|
25
|
+
self.stored_surf: pygame.Surface = Config.font.render(self.stored, True, Config.BEIGE)
|
|
26
|
+
|
|
27
|
+
self.selected: bool = False
|
|
28
|
+
|
|
29
|
+
self.function = function
|
|
30
|
+
self.args = args
|
|
31
|
+
self.kwargs = kwargs
|
|
32
|
+
|
|
33
|
+
def draw(self, display=None) -> None:
|
|
34
|
+
if not display:
|
|
35
|
+
display = self.display
|
|
36
|
+
|
|
37
|
+
color = self.color
|
|
38
|
+
if self.selected:
|
|
39
|
+
color = (
|
|
40
|
+
min(255, color[0] + 30),
|
|
41
|
+
min(255, color[1] + 30),
|
|
42
|
+
min(255, color[2] + 30)
|
|
43
|
+
)
|
|
44
|
+
Draw.draw_rect(
|
|
45
|
+
display=display,
|
|
46
|
+
color=color,
|
|
47
|
+
rectangle=self.rect,
|
|
48
|
+
border_radius=int(self.rect.h/2)
|
|
49
|
+
)
|
|
50
|
+
Draw.draw_rect(
|
|
51
|
+
display=display,
|
|
52
|
+
color=(
|
|
53
|
+
min(255, color[0] + 30),
|
|
54
|
+
min(255, color[1] + 30),
|
|
55
|
+
min(255, color[2] + 30)
|
|
56
|
+
),
|
|
57
|
+
rectangle=self.rect,
|
|
58
|
+
border_radius=int(self.rect.h/2),
|
|
59
|
+
width=3
|
|
60
|
+
)
|
|
61
|
+
Draw.draw_surface(self.stored_surf, (
|
|
62
|
+
self.rect.x + self.rect.w/2 - self.stored_surf.get_width()/2,
|
|
63
|
+
self.rect.y + self.rect.h/2 - self.stored_surf.get_height()/2
|
|
64
|
+
), display=display)
|
|
65
|
+
|
|
66
|
+
def events(self) -> Any:
|
|
67
|
+
click = False
|
|
68
|
+
for event in Config.events:
|
|
69
|
+
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
|
|
70
|
+
click = True
|
|
71
|
+
mp = pygame.mouse.get_pos()
|
|
72
|
+
|
|
73
|
+
if self.selected:
|
|
74
|
+
for event in Config.events:
|
|
75
|
+
if event.type != pygame.KEYDOWN:
|
|
76
|
+
continue
|
|
77
|
+
if event.key == pygame.K_BACKSPACE:
|
|
78
|
+
self.stored = self.stored[:-1]
|
|
79
|
+
elif event.key == pygame.K_RETURN:
|
|
80
|
+
self.function(self.stored, *self.args, **self.kwargs)
|
|
81
|
+
self.stored = ""
|
|
82
|
+
elif event.unicode.isprintable():
|
|
83
|
+
self.stored += event.unicode
|
|
84
|
+
|
|
85
|
+
if self.stored != self.last_stored:
|
|
86
|
+
self.stored_surf = Draw.render_text(self.stored)
|
|
87
|
+
self.last_stored = self.stored
|
|
88
|
+
|
|
89
|
+
if not click:
|
|
90
|
+
return
|
|
91
|
+
|
|
92
|
+
if Collide.rect_point(
|
|
93
|
+
rect=pygame.Rect(
|
|
94
|
+
self.rect.x + self.hitbox_offset[0],
|
|
95
|
+
self.rect.y + self.hitbox_offset[1],
|
|
96
|
+
self.rect.w,
|
|
97
|
+
self.rect.h
|
|
98
|
+
),
|
|
99
|
+
point=mp
|
|
100
|
+
):
|
|
101
|
+
self.selected = True
|
|
102
|
+
else:
|
|
103
|
+
self.selected = False
|
|
104
|
+
|
|
105
|
+
def update(self, check_events: bool = True):
|
|
106
|
+
value = None
|
|
107
|
+
if check_events:
|
|
108
|
+
value = self.events()
|
|
109
|
+
self.draw()
|
|
110
|
+
return value
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from sverpykit.Draw import Draw
|
|
2
|
+
import pygame
|
|
3
|
+
|
|
4
|
+
class TextBlock:
|
|
5
|
+
def __init__(
|
|
6
|
+
self,
|
|
7
|
+
rect: pygame.Rect,
|
|
8
|
+
text: str,
|
|
9
|
+
font: str = "default"
|
|
10
|
+
):
|
|
11
|
+
self.rect = rect
|
|
12
|
+
self.text_surf = Draw.render_text(str(text), name=font)
|
|
13
|
+
|
|
14
|
+
def draw(self):
|
|
15
|
+
Draw.draw_surface(
|
|
16
|
+
self.text_surf, (
|
|
17
|
+
self.rect.x, self.rect.y
|
|
18
|
+
),
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
def change_text(self, text: str):
|
|
22
|
+
self.text_surf = Draw.render_text(str(text))
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import pygame
|
|
2
|
+
from sverpykit.core import Config
|
|
3
|
+
from sverpykit.Draw import Draw
|
|
4
|
+
from sverpykit.Ui.Button import Button
|
|
5
|
+
|
|
6
|
+
title_bar_height = 30
|
|
7
|
+
title_bar_font = pygame.font.SysFont("arial", 30)
|
|
8
|
+
|
|
9
|
+
class Window:
|
|
10
|
+
def __init__(
|
|
11
|
+
self,
|
|
12
|
+
owner: list,
|
|
13
|
+
rect: pygame.Rect,
|
|
14
|
+
components: list,
|
|
15
|
+
color: tuple[int, int, int] = (150, 150, 150),
|
|
16
|
+
title_bar: bool = True
|
|
17
|
+
):
|
|
18
|
+
self.owner = owner
|
|
19
|
+
|
|
20
|
+
self.rect = rect
|
|
21
|
+
self.components = components
|
|
22
|
+
self.color = color
|
|
23
|
+
self.title_bar = title_bar
|
|
24
|
+
self.title_bar_rect = pygame.Rect(
|
|
25
|
+
self.rect.x,
|
|
26
|
+
self.rect.y - title_bar_height,
|
|
27
|
+
self.rect.w,
|
|
28
|
+
title_bar_height
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
# Events
|
|
32
|
+
self.last_title_bar_touch = None
|
|
33
|
+
|
|
34
|
+
self.operational_buttons = [
|
|
35
|
+
Button(
|
|
36
|
+
rect=pygame.Rect(
|
|
37
|
+
self.rect.x + self.rect.w - title_bar_height * 2,
|
|
38
|
+
self.rect.y - title_bar_height,
|
|
39
|
+
title_bar_height,
|
|
40
|
+
title_bar_height
|
|
41
|
+
),
|
|
42
|
+
button_color=(50, 50, 50),
|
|
43
|
+
surface=title_bar_font.render("-", True, Config.BEIGE),
|
|
44
|
+
display=Config.screen,
|
|
45
|
+
rounding=int(title_bar_height / 3),
|
|
46
|
+
function=self.minimize
|
|
47
|
+
),
|
|
48
|
+
Button(
|
|
49
|
+
rect=pygame.Rect(
|
|
50
|
+
self.rect.x + self.rect.w - title_bar_height,
|
|
51
|
+
self.rect.y - title_bar_height,
|
|
52
|
+
title_bar_height,
|
|
53
|
+
title_bar_height
|
|
54
|
+
),
|
|
55
|
+
button_color=(50, 50, 50),
|
|
56
|
+
surface=title_bar_font.render("x", True, Config.BEIGE),
|
|
57
|
+
display=Config.screen,
|
|
58
|
+
rounding=int(title_bar_height / 3),
|
|
59
|
+
function=self.close
|
|
60
|
+
)
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
for component in self.components:
|
|
64
|
+
component.hitbox_offset = (self.rect.x, self.rect.y)
|
|
65
|
+
|
|
66
|
+
def close(self):
|
|
67
|
+
self.owner.remove(self)
|
|
68
|
+
|
|
69
|
+
def minimize(self):
|
|
70
|
+
pass
|
|
71
|
+
|
|
72
|
+
def events(self):
|
|
73
|
+
mp, click = pygame.mouse.get_pos(), pygame.mouse.get_pressed()[0]
|
|
74
|
+
if self.owner[-1] is not self:
|
|
75
|
+
if (self.rect.collidepoint(mp) or self.title_bar_rect.collidepoint(mp)) and click:
|
|
76
|
+
self.owner.remove(self)
|
|
77
|
+
self.owner.append(self)
|
|
78
|
+
else:
|
|
79
|
+
return
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
if self.title_bar:
|
|
83
|
+
if self.last_title_bar_touch:
|
|
84
|
+
x_offset, y_offset = mp[0] - self.last_title_bar_touch[0], mp[1] - self.last_title_bar_touch[1]
|
|
85
|
+
self.rect.x += x_offset
|
|
86
|
+
self.rect.y += y_offset
|
|
87
|
+
self.title_bar_rect.x += x_offset
|
|
88
|
+
self.title_bar_rect.y += y_offset
|
|
89
|
+
for component in self.components:
|
|
90
|
+
component.hitbox_offset = (self.rect.x, self.rect.y)
|
|
91
|
+
for component in self.operational_buttons:
|
|
92
|
+
component.rect.x += x_offset
|
|
93
|
+
component.rect.y += y_offset
|
|
94
|
+
if self.title_bar_rect.collidepoint(mp) and click:
|
|
95
|
+
self.last_title_bar_touch = mp
|
|
96
|
+
else:
|
|
97
|
+
self.last_title_bar_touch = None
|
|
98
|
+
|
|
99
|
+
[component.events() for component in self.components]
|
|
100
|
+
|
|
101
|
+
return self.rect.collidepoint(mp) or self.title_bar_rect.collidepoint(mp)
|
|
102
|
+
|
|
103
|
+
def draw(self):
|
|
104
|
+
Draw.draw_rect(
|
|
105
|
+
display=Config.screen,
|
|
106
|
+
color=self.color,
|
|
107
|
+
rectangle=self.rect,
|
|
108
|
+
border_bottom_left_radius=3,
|
|
109
|
+
border_bottom_right_radius=3
|
|
110
|
+
)
|
|
111
|
+
Draw.draw_rect(
|
|
112
|
+
display=Config.screen,
|
|
113
|
+
color=(
|
|
114
|
+
max(0, self.color[0] - 10),
|
|
115
|
+
max(0, self.color[1] - 10),
|
|
116
|
+
max(0, self.color[2] - 10)
|
|
117
|
+
),
|
|
118
|
+
rectangle=self.rect,
|
|
119
|
+
border_bottom_left_radius=3,
|
|
120
|
+
border_bottom_right_radius=3,
|
|
121
|
+
width=2
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
display = pygame.Surface((self.rect.w, self.rect.h)).convert_alpha()
|
|
125
|
+
display.fill((0,0,0,0))
|
|
126
|
+
[component.draw(display) for component in self.components]
|
|
127
|
+
Draw.draw_surface(display, (self.rect.x, self.rect.y))
|
|
128
|
+
|
|
129
|
+
if self.title_bar:
|
|
130
|
+
Draw.draw_rect(
|
|
131
|
+
display=Config.screen,
|
|
132
|
+
color=(200, 200, 200),
|
|
133
|
+
rectangle=self.title_bar_rect,
|
|
134
|
+
border_top_left_radius=3,
|
|
135
|
+
border_top_right_radius=3
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
[button.update() for button in self.operational_buttons]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Core
|
|
2
|
+
import pygame
|
|
3
|
+
pygame.init()
|
|
4
|
+
from .core import Config, Runtime
|
|
5
|
+
from .core.Runtime import add_layer, start
|
|
6
|
+
from .core.Config import default_exit as quit_game
|
|
7
|
+
from .core.initialize import set_display, set_frame_method, set_font, set_quit_method, set_tick_method,\
|
|
8
|
+
max_rate
|
|
9
|
+
|
|
10
|
+
# Drawing
|
|
11
|
+
from .Draw.Draw import draw_surface, draw_rect, draw_circle, render_text
|
|
12
|
+
|
|
13
|
+
# Ui parts
|
|
14
|
+
from .Ui.Button import Button
|
|
15
|
+
from .Ui.SearchBar import SearchBar
|
|
16
|
+
from .Ui.DropDown import DropDown
|
|
17
|
+
from .Ui.Window import Window
|
|
18
|
+
from .Ui.TextBlock import TextBlock
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
"Config",
|
|
22
|
+
"Runtime",
|
|
23
|
+
"Draw",
|
|
24
|
+
"Button"
|
|
25
|
+
]
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import pygame, sys
|
|
2
|
+
from typing import Callable
|
|
3
|
+
|
|
4
|
+
def default_exit():
|
|
5
|
+
pygame.quit()
|
|
6
|
+
sys.exit()
|
|
7
|
+
|
|
8
|
+
welcome_text = pygame.font.SysFont("arial", 100).render("Welcome!", True, (255, 255, 255))
|
|
9
|
+
def frame():
|
|
10
|
+
pygame.transform.scale(welcome_text, (screen.get_width(), screen.get_height()))
|
|
11
|
+
screen.blit(welcome_text, (0, 0))
|
|
12
|
+
|
|
13
|
+
def tick():
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
# WINDOW
|
|
17
|
+
screen: pygame.Surface
|
|
18
|
+
|
|
19
|
+
# Events
|
|
20
|
+
max_fps: int | float = 60
|
|
21
|
+
tick_rate: int | float = 60
|
|
22
|
+
events: list[pygame.event.Event] = []
|
|
23
|
+
clock: pygame.time.Clock = pygame.time.Clock()
|
|
24
|
+
delta_time: int
|
|
25
|
+
|
|
26
|
+
# Functions
|
|
27
|
+
exit_function: Callable = default_exit
|
|
28
|
+
frame_function: Callable = frame
|
|
29
|
+
tick_function: Callable = tick
|
|
30
|
+
|
|
31
|
+
# Ui
|
|
32
|
+
fonts: dict[str, pygame.font.Font] = {
|
|
33
|
+
"default": pygame.font.SysFont("arial",32)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
# Colors
|
|
37
|
+
background_color: pygame.Color | tuple[int, int, int] = (25, 25, 25)
|
|
38
|
+
|
|
39
|
+
# Color names
|
|
40
|
+
BEIGE = (220, 245, 245)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from sverpykit.Ui.Window import Window
|
|
2
|
+
from sverpykit.core import Config
|
|
3
|
+
import pygame
|
|
4
|
+
|
|
5
|
+
ui_layers = []
|
|
6
|
+
|
|
7
|
+
def add_layer(
|
|
8
|
+
layer_type: str,
|
|
9
|
+
rectangle: pygame.Rect,
|
|
10
|
+
components: list,
|
|
11
|
+
color: tuple[int, int, int] = (150, 150, 150),
|
|
12
|
+
|
|
13
|
+
**kwargs
|
|
14
|
+
) -> None:
|
|
15
|
+
"""
|
|
16
|
+
:param layer_type: Currently possible: Window.
|
|
17
|
+
:param rectangle: x, y, width, height of the layer.
|
|
18
|
+
:param components: A list of UI parts that belong to the layer.
|
|
19
|
+
:param color: The base color of the layer.
|
|
20
|
+
:param kwargs: Any extra arguments that may not be accessible for all layer types
|
|
21
|
+
:return: Returns nothing.
|
|
22
|
+
"""
|
|
23
|
+
if layer_type.lower() == "window":
|
|
24
|
+
ui_layers.append(Window(ui_layers, rectangle, components, color, **kwargs))
|
|
25
|
+
|
|
26
|
+
tick_counter = 0
|
|
27
|
+
def register_tick() -> None:
|
|
28
|
+
global tick_counter
|
|
29
|
+
tick_counter -= Config.delta_time
|
|
30
|
+
while tick_counter < 0:
|
|
31
|
+
Config.events = pygame.event.get()
|
|
32
|
+
tick_counter += 1 / Config.tick_rate
|
|
33
|
+
|
|
34
|
+
for event in Config.events:
|
|
35
|
+
if event.type == pygame.QUIT:
|
|
36
|
+
Config.exit_function()
|
|
37
|
+
|
|
38
|
+
Config.tick_function()
|
|
39
|
+
for layer in reversed(ui_layers):
|
|
40
|
+
if layer.events(): break
|
|
41
|
+
|
|
42
|
+
def start() -> None:
|
|
43
|
+
"""
|
|
44
|
+
Makes the main game loop so you don't have to.
|
|
45
|
+
Features:
|
|
46
|
+
- Main loop
|
|
47
|
+
- Events
|
|
48
|
+
- FPS control
|
|
49
|
+
- Updating the screen
|
|
50
|
+
- Resetting the screen
|
|
51
|
+
|
|
52
|
+
You can change almost all of these!
|
|
53
|
+
"""
|
|
54
|
+
while True:
|
|
55
|
+
Config.delta_time = Config.clock.tick(Config.max_fps)/1000
|
|
56
|
+
register_tick()
|
|
57
|
+
|
|
58
|
+
Config.screen.fill(Config.background_color)
|
|
59
|
+
Config.frame_function()
|
|
60
|
+
[layer.draw() for layer in ui_layers]
|
|
61
|
+
|
|
62
|
+
pygame.display.flip()
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
from sverpykit.core import Config, Runtime
|
|
2
|
+
from typing import Callable, Optional
|
|
3
|
+
import pygame
|
|
4
|
+
|
|
5
|
+
# Automatic initialization
|
|
6
|
+
pygame.key.set_repeat(500, 50)
|
|
7
|
+
|
|
8
|
+
# Manual initialization
|
|
9
|
+
def set_display(
|
|
10
|
+
width: int,
|
|
11
|
+
height: int,
|
|
12
|
+
flags: int = 0,
|
|
13
|
+
depth: int = 0,
|
|
14
|
+
display: int = 0,
|
|
15
|
+
vsync: int = 0
|
|
16
|
+
) -> pygame.Surface:
|
|
17
|
+
"""
|
|
18
|
+
:param width: Width of the screen
|
|
19
|
+
:param height: Height of the screen
|
|
20
|
+
:param flags: Special properties for the display, pygame.RESIZABLE makes the user able to resize the screen.
|
|
21
|
+
:param depth: How many colors you can use (Most of the time 8-bit is good enough. In which case just leave it blank).
|
|
22
|
+
:param display: Decides which monitor is used for the window.
|
|
23
|
+
:param vsync: Caps framerate to the monitor to avoid screen tearing (Screen tearing is just a visual glitch.)
|
|
24
|
+
:return:
|
|
25
|
+
"""
|
|
26
|
+
Config.screen = pygame.display.set_mode((width, height), flags, depth, display, vsync)
|
|
27
|
+
return Config.screen
|
|
28
|
+
|
|
29
|
+
def max_rate(
|
|
30
|
+
fps: int | None = None,
|
|
31
|
+
tick: int | None = None
|
|
32
|
+
) -> None:
|
|
33
|
+
"""
|
|
34
|
+
:param fps: Caps the max frame rate (Can alwasy go below this number if anything is struggling).
|
|
35
|
+
:param tick: Sets the max tick rate (If the frame rate is lower than the tick rate the ticks will build up, so this is not a cap)
|
|
36
|
+
"""
|
|
37
|
+
Config.max_fps = fps if fps else Config.max_fps
|
|
38
|
+
Config.tick_rate = tick if tick else Config.tick_rate
|
|
39
|
+
|
|
40
|
+
def set_font(
|
|
41
|
+
name: str = "default",
|
|
42
|
+
font: str = "arial",
|
|
43
|
+
size: int = 25,
|
|
44
|
+
bold: bool = False,
|
|
45
|
+
italic: bool = False,
|
|
46
|
+
constructor: Optional[Callable[[Optional[str], int, bool, bool], pygame.font.Font]] = None
|
|
47
|
+
) -> pygame.font.Font:
|
|
48
|
+
"""
|
|
49
|
+
:param name: How to get the font in other parts of sverpykit.
|
|
50
|
+
:param font: The font of the text.
|
|
51
|
+
:param size: How big the font is.
|
|
52
|
+
:param bold: If the font is bold or not.
|
|
53
|
+
:param italic: If the font is italic or not.
|
|
54
|
+
:param constructor: If you like a custom class to be attached to the font.
|
|
55
|
+
:return: Returns the font. Most of the time not needed though.
|
|
56
|
+
"""
|
|
57
|
+
Config.fonts[name] = pygame.font.SysFont(font, size, bold, italic, constructor)
|
|
58
|
+
return Config.fonts[name]
|
|
59
|
+
|
|
60
|
+
def set_quit_method(method: Callable) -> None:
|
|
61
|
+
"""
|
|
62
|
+
:param method: This method/function gets ran when the player presses Alt + F4 or the X in the top right.
|
|
63
|
+
"""
|
|
64
|
+
Config.exit_function = method
|
|
65
|
+
|
|
66
|
+
def set_frame_method(method: Callable) -> None:
|
|
67
|
+
"""
|
|
68
|
+
:param method: This method/function gets ran every frame.
|
|
69
|
+
"""
|
|
70
|
+
Config.frame_function = method
|
|
71
|
+
|
|
72
|
+
def set_tick_method(method: Callable) -> None:
|
|
73
|
+
"""
|
|
74
|
+
:param method: This method/function gets ran every tick.
|
|
75
|
+
"""
|
|
76
|
+
Config.tick_function = method
|
|
77
|
+
|
|
78
|
+
def get_delta() -> int | float:
|
|
79
|
+
"""
|
|
80
|
+
:return: Returns the time it took for the last frame in ms.
|
|
81
|
+
"""
|
|
82
|
+
return Config.delta_time
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
sverpykit/__init__.py
|
|
4
|
+
sverpykit.egg-info/PKG-INFO
|
|
5
|
+
sverpykit.egg-info/SOURCES.txt
|
|
6
|
+
sverpykit.egg-info/dependency_links.txt
|
|
7
|
+
sverpykit.egg-info/requires.txt
|
|
8
|
+
sverpykit.egg-info/top_level.txt
|
|
9
|
+
sverpykit/Collide/Collide.py
|
|
10
|
+
sverpykit/Draw/Draw.py
|
|
11
|
+
sverpykit/Ui/Button.py
|
|
12
|
+
sverpykit/Ui/DropDown.py
|
|
13
|
+
sverpykit/Ui/SearchBar.py
|
|
14
|
+
sverpykit/Ui/TextBlock.py
|
|
15
|
+
sverpykit/Ui/Window.py
|
|
16
|
+
sverpykit/core/Config.py
|
|
17
|
+
sverpykit/core/Runtime.py
|
|
18
|
+
sverpykit/core/initialize.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pygame
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
sverpykit
|