PGTKernelBasic 0.22.0__py3-none-any.whl

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.
@@ -0,0 +1,84 @@
1
+ from Kernel.PgRenderCompo.Render import *
2
+ from Kernel.RFlags import *
3
+ from Kernel.KernelWidget import Widget
4
+ from Kernel.PgRenderCompo.TextObj import Label
5
+ def Remove_bg(widget: Widget, screen):
6
+ if border in widget.vflags:
7
+ set_border(widget, screen)
8
+ widget.hide_itself()
9
+ def Remove_border(widget: Widget, screen):
10
+ if bg_widget in widget.vflags:
11
+ fill_bg(widget, screen)
12
+ else:
13
+ widget.hide_itself()
14
+ def Remove_corner_radius(widget: Widget, screen):
15
+ if border in widget.vflags:
16
+ valpack = widget.vflags[border]
17
+ pygame.draw.rect(screen, valpack.border_col, widget.get_rect(), valpack.border_width)
18
+ def Remove_textpack(label: Label, screen):
19
+ if bg_widget in label.vflags:
20
+ fill_bg(label, screen)
21
+ elif border in label.vflags:
22
+ set_border(label, screen)
23
+ else:
24
+ widget.hide_itself()
25
+ def Remove_textBold(label: Label, screen):
26
+ label.dirty_auto_flag.add(text_auto_resize)
27
+ if bg_widget in label.vflags:
28
+ fill_bg(label, screen)
29
+ else:
30
+ label.hide_itself()
31
+ label.font.set_bold(False)
32
+ text_surface = label.font.render(label.textpack.Text, label.smooth, label.textpack.Color)
33
+ screen.blit(text_surface, label.get_pos())
34
+ def Remove_textItalic(label: Label, screen):
35
+ label.dirty_auto_flag.add(text_auto_resize)
36
+ if bg_widget in label.vflags:
37
+ fill_bg(label, screen)
38
+ else:
39
+ label.hide_itself()
40
+ label.font.set_italic(False)
41
+ text_surface = label.font.render(label.textpack.Text, label.smooth, label.textpack.Color)
42
+ screen.blit(text_surface, label.get_pos())
43
+ def Remove_textUnderline(label:Label, screen):
44
+ label.dirty_auto_flag.add(text_auto_resize)
45
+ if bg_widget in label.vflags:
46
+ fill_bg(label, screen)
47
+ else:
48
+ label.hide_itself()
49
+ label.font.set_underline(False)
50
+ text_surface = label.font.render(label.textpack.Text, label.smooth, label.textpack.Color)
51
+ screen.blit(text_surface, label.get_pos())
52
+ def Remove_textStrikethrough(label:Label, screen):
53
+ label.dirty_auto_flag.add(text_auto_resize)
54
+ if bg_widget in label.vflags:
55
+ fill_bg(label, screen)
56
+ else:
57
+ label.hide_itself()
58
+ label.font.set_strikethrough(False)
59
+ text_surface = label.font.render(label.textpack.Text, label.smooth, label.textpack.Color)
60
+ screen.blit(text_surface, label.get_pos())
61
+ def Remove_textAntialias(label : Label, screen):
62
+ if bg_widget in label.vflags:
63
+ fill_bg(label, screen)
64
+ else:
65
+ label.hide_itself()
66
+ label.smooth = False
67
+ text_surface = label.font.render(label.textpack.Text, label.smooth, label.textpack.Color)
68
+ screen.blit(text_surface, label.get_pos())
69
+ def Remove_textBg(label: Label, screen):
70
+ label.hide_itself()
71
+ font = label.font if hasattr(label, 'font') else \
72
+ pygame.font.SysFont(label.textpack.Font, label.textpack.Size)
73
+
74
+ font.set_bold(text_Is_Bold in label.uflags)
75
+ font.set_italic(text_Is_Italic in label.uflags)
76
+ font.set_underline(text_Is_Underline in label.uflags)
77
+ font.set_strikethrough(text_Is_Strikethrough in label.uflags)
78
+
79
+ text_surface = font.render(
80
+ label.textpack.Text,
81
+ text_Is_Antialias in label.uflags,
82
+ label.textpack.Color
83
+ )
84
+ screen.blit(text_surface, label.get_pos())
@@ -0,0 +1,78 @@
1
+ import pygame
2
+
3
+ from Kernel.VFlags import *
4
+ from Kernel.UFlags import *
5
+ from Kernel.KernelWidget import Widget
6
+ from Kernel.PgRenderCompo.TextObj import Label
7
+
8
+ """
9
+ Surface
10
+ """
11
+
12
+
13
+ def get_rounded_surface(surface, radius):
14
+ size = surface.get_size()
15
+ target = pygame.Surface(size, pygame.SRCALPHA)
16
+ target.fill((0, 0, 0, 0))
17
+ pygame.draw.rect(target, (255, 255, 255, 255), (0, 0, size[0], size[1]), border_radius=radius)
18
+ target.blit(surface, (0, 0), special_flags=pygame.BLEND_RGBA_MIN)
19
+ return target
20
+ def fill_bg(widget: Widget, screen: pygame.Surface):
21
+ bg = widget.vflags[bg_widget]
22
+ radius = widget.vflags.get(corner_radius, 0)
23
+ if isinstance(bg, tuple):
24
+ pygame.draw.rect(screen, bg, (widget.rect.x, widget.rect.y, widget.rect.w, widget.rect.h), border_radius=radius)
25
+ elif isinstance(bg, pygame.Surface):
26
+ cache_key = f"_rounded_bg_cache_{widget.rect.w}_{widget.rect.h}_{radius}"
27
+ rounded_bg = getattr(widget, cache_key, None)
28
+ if rounded_bg is None:
29
+ scaled_bg = pygame.transform.smoothscale(bg, (int(widget.rect.w), int(widget.rect.h)))
30
+ if radius > 0:
31
+ rounded_bg = get_rounded_surface(scaled_bg, radius)
32
+ else:
33
+ rounded_bg = scaled_bg
34
+ setattr(widget, cache_key, rounded_bg)
35
+ screen.blit(rounded_bg, (widget.rect.x, widget.rect.y))
36
+ def set_border(widget: Widget, screen):
37
+ valpack = widget.vflags[border]
38
+ if corner_radius in widget.vflags:
39
+ pygame.draw.rect(screen, valpack.border_col, widget.get_rect(), valpack.border_width, widget.vflags[corner_radius])
40
+ else:
41
+ pygame.draw.rect(screen, valpack.border_col, widget.get_rect(), valpack.border_width)
42
+ """
43
+ Text
44
+ """
45
+ def draw_text(label: Label, screen):
46
+ text_surface = label.font.render(label.textpack.Text, label.smooth, label.textpack.Color, label.bg)
47
+ screen.blit(text_surface, label.get_pos())
48
+ def set_Bold(label: Label):
49
+ label.font.set_bold(True)
50
+ label.dirty_vflags.add(textpack)
51
+ label.dirty_auto_flag.add(text_auto_resize)
52
+ def set_Italic(label: Label):
53
+ label.font.set_italic(True)
54
+ label.dirty_vflags.add(textpack)
55
+ label.hide_itself()
56
+ label.dirty_auto_flag.add(text_auto_resize)
57
+ def set_Underline(label: Label):
58
+ label.font.set_underline(True)
59
+ label.dirty_vflags.add(textpack)
60
+ label.hide_itself()
61
+ label.dirty_auto_flag.add(text_auto_resize)
62
+ def set_Strikethrough(label: Label):
63
+ label.font.set_strikethrough(True)
64
+ label.dirty_vflags.add(textpack)
65
+ label.dirty_auto_flag.add(text_auto_resize)
66
+ def set_Antialias(label: Label):
67
+ label.smooth = True
68
+ label.dirty_vflags.add(textpack)
69
+ def set_have_Background(label: Label):
70
+ if bg_widget in label.vflags:
71
+ label.bg = label.vflags[bg_widget]
72
+ label.dirty_vflags.add(textpack)
73
+ else:
74
+ raise ValueError('Background color is not found')
75
+ def text_resize(label: Label):
76
+ text_surface = label.font.render(label.textpack.Text, label.smooth, label.textpack.Color)
77
+ new_size = text_surface.get_size()
78
+ label.Size_update(new_size)
@@ -0,0 +1,127 @@
1
+ import pygame
2
+
3
+ from Kernel.PgRenderCompo.ButtonObj import FixedButton
4
+ from Kernel.UFlags import *
5
+ from Kernel.KernelWidget import Widget, MainScreen
6
+ from Kernel.ObjType import RectTuple, PosTuple, TextPack, Border
7
+ from Kernel.VFlags import *
8
+ import re
9
+ def trashfunc(*args, **kwargs):
10
+ pass
11
+ re_search = re.search
12
+ re_findall = re.findall
13
+ re_sub = re.sub
14
+ re_split = re.split
15
+ re_match = re.match
16
+ re_compile = re.compile
17
+ re_escape = re.escape
18
+ EMAIL_PATTERN = re.compile(r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}')
19
+ URL_PATTERN = re.compile(r'https?://\S+')
20
+ HASHTAG_PATTERN = re.compile(r'#\w+')
21
+ MENTION_PATTERN = re.compile(r'@\w+')
22
+ def extract_emails(text):
23
+ return EMAIL_PATTERN.findall(text)
24
+ def extract_urls(text):
25
+ return URL_PATTERN.findall(text)
26
+ def extract_hashtags(text):
27
+ return HASHTAG_PATTERN.findall(text)
28
+ def safe_substitute(text, pattern, replacement):
29
+ """Safe regex substitution với escape"""
30
+ return re_sub(re_escape(pattern), replacement, text)
31
+ #wrap
32
+ SysFont = pygame.font.SysFont
33
+ Font = pygame.font.Font
34
+ class Label(Widget):
35
+ __slots__ = ('font', 'textpack', 'smooth', 'bg')
36
+ def __init__(self, parent: Widget | MainScreen, color,
37
+ size, text,
38
+ Uflags: set | tuple = (), pos : PosTuple=(0, 0), font ="timesnewroman", name: None | str = None):
39
+ self.textpack = TextPack(color, font, size, text)
40
+ self.font = pygame.font.SysFont(self.textpack.Font, self.textpack.Size)
41
+ text_surface = self.font.render(self.textpack.Text, False, self.textpack.Color)
42
+ pygameRect = text_surface.get_rect()
43
+ x,y = pos
44
+ tuple_rect = (x,y,pygameRect.w, pygameRect.h)
45
+ super().__init__(parent, rect=tuple_rect,name=name, can_change=True)
46
+ self.add_vflag((textpack, TextPack(color, font, size, text)))
47
+ if isinstance(Uflags, set):
48
+ self.uflags = Uflags
49
+ self.dirty_uflags = Uflags
50
+ else:
51
+ for flag in Uflags:
52
+ self.add_uflag(flag)
53
+ self.smooth = text_Is_Antialias in self.uflags
54
+ self.bg = None
55
+ def smooth_update(self):
56
+ self.smooth = text_Is_Antialias in self.uflags
57
+ def Rect_update(self, rect: RectTuple):
58
+ self.rect.x = rect[0]
59
+ self.rect.y = rect[1]
60
+ self.rect.w = rect[2]
61
+ self.rect.h = rect[3]
62
+ def Size_update(self, size: PosTuple):
63
+ self.rect.w = size[0]
64
+ self.rect.h = size[1]
65
+ def change_text(self, new_text: str):
66
+ self.hide_itself()
67
+ self.textpack.Text = new_text
68
+ new_w, new_h = self.font.size(self.textpack.Text)
69
+ self.Size_update((new_w, new_h))
70
+ self.dirty_vflags.add(textpack)
71
+ class LineEdit(FixedButton):
72
+ def __init__(self, parent, text_size, width_line_edit ,pos: PosTuple=(0,0), bg=(255,255,255),
73
+ text_color=(0,0,0), border_radius=4, border_width=1, border_color = (0,0,0),
74
+ text_font="timesnewroman", text_uflags=None, pad_x=8, pad_y=4, name: str | None = None):
75
+ text_uflags = {text_Is_Antialias} if not text_uflags else text_uflags
76
+ text_pos = (pad_x + border_width, pad_y + border_width)
77
+ temp_font = pygame.font.SysFont(text_font, text_size)
78
+ height_line_edit = temp_font.get_height() + pad_y * 2 + border_width * 2
79
+ rect = (pos[0], pos[1], width_line_edit, height_line_edit)
80
+ super().__init__(parent, rect, bg, name=name)
81
+ self.label = Label(self, text_color, text_size, "", text_uflags, text_pos, font=text_font)
82
+ self.add_vflag((border, Border(border_width, border_color)))
83
+ self.add_vflag((corner_radius, border_radius))
84
+ self.text = self.label.textpack.Text
85
+ self.display_text = self.text
86
+ self.fully = False
87
+ self.display_start = 0
88
+ self.pad_x = pad_x
89
+ self.pad_y = pad_y
90
+
91
+ def _update_display_offset(self):
92
+ b_width = self.vflags[border].border_width
93
+ max_width = self.rect.w - self.pad_x * 2 - b_width * 2
94
+ while True:
95
+ current_w = self.label.font.size(self.text[self.display_start:])[0]
96
+ if current_w <= max_width or self.display_start >= len(self.text):
97
+ break
98
+ self.display_start += 1
99
+ self.fully = True
100
+ while self.display_start > 0:
101
+ test_start = self.display_start - 1
102
+ test_w = self.label.font.size(self.text[test_start:])[0]
103
+ if test_w <= max_width:
104
+ self.display_start = test_start
105
+ else:
106
+ break
107
+ if self.display_start == 0:
108
+ self.fully = False
109
+ self.label.change_text(self.text[self.display_start:])
110
+ def process_addchar(self, char: str):
111
+ self.text += char
112
+ self._update_display_offset()
113
+ def process_backspace(self):
114
+ if len(self.text) > 0:
115
+ self.text = self.text[:-1]
116
+ self._update_display_offset()
117
+
118
+ def dispatch_hover(self, mouse_pos):
119
+ pygame.mouse.set_cursor(pygame.SYSTEM_CURSOR_IBEAM)
120
+ return super().dispatch_hover(mouse_pos)
121
+
122
+ def dispatch_release(self, mouse_pos):
123
+ pygame.mouse.set_cursor(pygame.SYSTEM_CURSOR_ARROW)
124
+ return super().dispatch_release(mouse_pos)
125
+ def clear_text(self):
126
+ self.text = ""
127
+ self._update_display_offset()
@@ -0,0 +1,5 @@
1
+ from Kernel.PgRenderCompo.LinkRenderfunc import *
2
+ from Kernel.PgRenderCompo.RRender import *
3
+ from Kernel.PgRenderCompo.Render import *
4
+ from Kernel.PgRenderCompo.TextObj import *
5
+ from Kernel.PgRenderCompo.ButtonObj import *
Kernel/RFlags.py ADDED
@@ -0,0 +1,63 @@
1
+ from Kernel.UFlags import *
2
+ from Kernel.VFlags import *
3
+ """
4
+ RUFLAGS
5
+ """
6
+ Rtext_Is_Bold = text_Is_Bold + 2000
7
+ Rtext_Is_Italic = text_Is_Italic + 2000
8
+ Rtext_Is_Underline = text_Is_Underline + 2000
9
+ Rtext_Is_Strikethrough = text_Is_Strikethrough + 2000
10
+ Rtext_Is_Antialias = text_Is_Antialias + 2000
11
+ Rtext_have_background = text_have_background + 2000
12
+ Rhave_margin = have_margin + 2000
13
+ """
14
+ RVflags
15
+ """
16
+ Rbg_widget = bg_widget + 2000
17
+ Rborder = border + 2000
18
+ Rcorner_radius = corner_radius + 2000
19
+ Rtextpack = textpack + 2000
20
+ RDownrclick = Downrclick + 2000
21
+ RDownlclick = Downlclick + 2000
22
+ RDownscrollmouse = Downscrollmouse + 2000
23
+ RDownscrollup = Downscrollup + 2000
24
+ RDownscrolldown = Downscrolldown + 2000
25
+ RUprclick = Uprclick + 2000
26
+ RUplclick = Uplclick + 2000
27
+ RUpscrollmouse = Upscrollmouse + 2000
28
+ RUpscrollup = Upscrollup + 2000
29
+ RUpscrolldown = Upscrolldown + 2000
30
+ Rhover_bg = hover_bg + 2000
31
+ Rpressed_bg = pressed_bg + 2000
32
+ RHover_func = Hoverfunc + 2000
33
+ RRealeasefunc = Realeasefunc + 2000
34
+ """
35
+ Link Rflag to Uflag, Vflag
36
+ """
37
+ rflags_to_uflags = {
38
+ text_Is_Bold: Rtext_Is_Bold,
39
+ text_Is_Italic: Rtext_Is_Italic,
40
+ text_Is_Underline: Rtext_Is_Underline,
41
+ text_Is_Strikethrough: Rtext_Is_Strikethrough,
42
+ text_Is_Antialias: Rtext_Is_Antialias,
43
+ text_have_background: Rtext_have_background,
44
+ have_margin: Rhave_margin
45
+ }
46
+ rflags_to_vflags = {
47
+ bg_widget: Rbg_widget,
48
+ border: Rborder,
49
+ corner_radius: Rcorner_radius,
50
+ textpack: Rtextpack,
51
+ Downrclick: RDownrclick,
52
+ Downlclick: RDownlclick,
53
+ Downscrollmouse: RDownscrollmouse,
54
+ Downscrolldown: RDownscrolldown,
55
+ Downscrollup: RDownscrollup,
56
+ Uprclick: RUprclick,
57
+ Uplclick: RUplclick,
58
+ Upscrollmouse: RUpscrollmouse,
59
+ Upscrollup: RUpscrollup,
60
+ Upscrolldown: RUpscrolldown,
61
+ Hoverfunc: RHover_func,
62
+ Realeasefunc: RRealeasefunc
63
+ }
Kernel/UFlags.py ADDED
@@ -0,0 +1,18 @@
1
+ ##########
2
+ #COMMON
3
+ ##########
4
+ have_margin = 1
5
+ ############
6
+ #LABEL
7
+ ############
8
+ text_Is_Bold = have_margin + 1
9
+ text_Is_Italic = text_Is_Bold + 1
10
+ text_Is_Underline = text_Is_Italic + 1
11
+ text_Is_Strikethrough = text_Is_Underline + 1
12
+ text_Is_Antialias = text_Is_Strikethrough + 1
13
+ text_have_background = text_Is_Antialias + 1
14
+
15
+ ###########
16
+ #Aflags
17
+ ###########
18
+ text_auto_resize = 4001
Kernel/VFlags.py ADDED
@@ -0,0 +1,29 @@
1
+ ##########
2
+ #COMMON
3
+ ##########
4
+
5
+ bg_widget = 1001 # Not for Label
6
+ border = bg_widget + 1 # Not for Label
7
+ corner_radius = border + 1 # Not for Label
8
+ #########
9
+ #LABEL
10
+ ########
11
+ textpack = corner_radius + 1
12
+ ##########
13
+ #BUTTON
14
+ ##########
15
+ Downrclick = textpack + 1
16
+ Downlclick = Downrclick + 1
17
+ Downscrollmouse = Downlclick + 1
18
+ Downscrollup = Downscrollmouse + 1
19
+ Downscrolldown = Downscrollup + 1
20
+ Uprclick = Downscrolldown + 1
21
+ Uplclick = Uprclick + 1
22
+ Upscrollmouse = Uplclick + 1
23
+ Upscrollup = Upscrollmouse + 1
24
+ Upscrolldown = Upscrollup + 1
25
+ hover_bg = Upscrolldown + 1
26
+ pressed_bg = hover_bg + 1
27
+ Hoverfunc = pressed_bg + 1
28
+ Realeasefunc = Hoverfunc + 1
29
+ print(Downlclick)
Kernel/__init__.py ADDED
@@ -0,0 +1,15 @@
1
+ from .KernelColor import *
2
+ from .KernelPosition import *
3
+ from .geometry import *
4
+ from .KernelWidget import *
5
+ from .ObjType import *
6
+ from .KernalInit import *
7
+ from .PgRenderCompo import *
8
+ from .ImageObj import *
9
+ from .KernelAudio import *
10
+ from .KernelLayout import *
11
+ from .KernelEvent import *
12
+ from .KernelRun import *
13
+ from .VFlags import *
14
+ from .UFlags import *
15
+ from .RFlags import *
Kernel/geometry.py ADDED
@@ -0,0 +1,117 @@
1
+ #v0.09
2
+ from Kernel import KernalInit
3
+ import math
4
+ KernalInit.init()
5
+ #wrap some useful function from a math lib
6
+ sqrt = math.sqrt
7
+ atan2 = math.atan2
8
+ degrees = math.degrees
9
+ radians = math.radians
10
+ cos = math.cos
11
+ sin = math.sin
12
+ pi = math.pi
13
+ def to_vector(pos_x:float, pos_y:float):
14
+ """change 2 pos to a vector"""
15
+ return pos_y - pos_x
16
+ def magnitude(vec):
17
+ """return the distance of two pos"""
18
+ return math.sqrt(vec[0]*vec[0] + vec[1]*vec[1])
19
+ def vector_between(p1, p2):
20
+ """return the vector between two pos"""
21
+ return p2[0] - p1[0], p2[1] - p1[1]
22
+ def normalize(vec):
23
+ """Return unit vector."""
24
+ mag = magnitude(vec)
25
+ if mag == 0:
26
+ return 0.0, 0.0
27
+ return vec[0] / mag, vec[1] / mag
28
+ def midpoint(p1, p2):
29
+ """
30
+ return the pos of the midpoint in the line
31
+ """
32
+ return (p1[0] + p2[0]) * 0.5, (p1[1] + p2[1]) * 0.5
33
+ def point_on_circle(center, radius, angle_deg):
34
+ """
35
+ return position of the point in the circle
36
+ """
37
+ rad = math.radians(angle_deg)
38
+ return (center[0] + radius * math.cos(rad),
39
+ center[1] + radius * math.sin(rad))
40
+ def clamp_point(point, rect):
41
+ """Clamp point to be inside rect (pygame.Rect or (x,y,w,h))."""
42
+ x, y = point
43
+ rx, ry, rw, rh = rect
44
+ return (max(rx, min(x, rx + rw)),
45
+ max(ry, min(y, ry + rh)))
46
+ def vector_to_angle(dx, dy):
47
+ """
48
+ Return angle in degrees (0° to 360°) of vector (dx, dy).
49
+ 0° points to the right (positive X), 90° points down (positive Y in pygame).
50
+ """
51
+ # math.atan2(dy, dx) returns radians, convert to degrees
52
+ angle_rad = math.atan2(dy, dx)
53
+ angle_deg = math.degrees(angle_rad)
54
+ # Normalize to 0–360
55
+ return angle_deg % 360.0
56
+ # Rect utilities
57
+ def rect_intersection(rect1, rect2):
58
+ """Return overlapping rect as pygame.Rect, or None if no intersection."""
59
+ x1 = max(rect1[0], rect2[0])
60
+ y1 = max(rect1[1], rect2[1])
61
+ x2 = min(rect1[0] + rect1[2], rect2[0] + rect2[2])
62
+ y2 = min(rect1[1] + rect1[3], rect2[1] + rect2[3])
63
+ if x2 > x1 and y2 > y1:
64
+ return x1, y1, x2 - x1, y2 - y1
65
+ return None
66
+ def rect_union(rect1, rect2):
67
+ """Return the smallest rect containing both rects."""
68
+ x1 = min(rect1[0], rect2[0])
69
+ y1 = min(rect1[1], rect2[1])
70
+ x2 = max(rect1[0] + rect1[2], rect2[0] + rect2[2])
71
+ y2 = max(rect1[1] + rect1[3], rect2[1] + rect2[3])
72
+ return x1, y1, x2 - x1, y2 - y1
73
+
74
+ def rotate_point(point, center, angle_deg):
75
+ """
76
+ Rotate a point around a center by a given angle (degrees).
77
+ Positive angle = counter‑clockwise (mathematical convention).
78
+ """
79
+ px, py = point
80
+ cx, cy = center
81
+ rad = radians(angle_deg)
82
+ cos_a = cos(rad)
83
+ sin_a = sin(rad)
84
+
85
+ # Translate to origin
86
+ dx = px - cx
87
+ dy = py - cy
88
+
89
+ # Rotate
90
+ rx = dx * cos_a - dy * sin_a
91
+ ry = dx * sin_a + dy * cos_a
92
+
93
+ # Translate back
94
+ return rx + cx, ry + cy
95
+ def pytagore(a, b):
96
+ """Return sqrt(a² + b²) – Pythagorean distance for a right triangle."""
97
+ return sqrt(a*a + b*b)
98
+ def law_of_cosines(a, b, angle_deg):
99
+ """Return length of side c given sides a, b and included angle C in degrees."""
100
+ rad = radians(angle_deg)
101
+ return sqrt(a*a + b*b - 2*a*b*cos(rad))
102
+ def triangle_area(p1, p2, p3):
103
+ """Area of triangle given three points (x, y)."""
104
+ x1, y1 = p1
105
+ x2, y2 = p2
106
+ x3, y3 = p3
107
+ return abs((x1*(y2 - y3) + x2*(y3 - y1) + x3*(y1 - y2)) / 2.0)
108
+ def point_line_distance(point, line_p1, line_p2):
109
+ """Distance from point to line defined by two points."""
110
+ x0, y0 = point
111
+ x1, y1 = line_p1
112
+ x2, y2 = line_p2
113
+ numerator = abs((x2-x1)*(y1-y0) - (x1-x0)*(y2-y1))
114
+ denominator = sqrt((x2-x1)**2 + (y2-y1)**2)
115
+ if denominator == 0:
116
+ return distance(point, line_p1) # a line is a point
117
+ return numerator / denominator
@@ -0,0 +1,11 @@
1
+ Metadata-Version: 2.4
2
+ Name: PGTKernelBasic
3
+ Version: 0.22.0
4
+ Summary: Lightweight UI framework for Pygame
5
+ Author: Your Name
6
+ Requires-Python: >=3.8
7
+ Requires-Dist: pygame>=2.5.0
8
+ Dynamic: author
9
+ Dynamic: requires-dist
10
+ Dynamic: requires-python
11
+ Dynamic: summary
@@ -0,0 +1,25 @@
1
+ Kernel/ImageObj.py,sha256=l5YqW-Ec8-y__FeDstFZMHjiFZM8oEvLpbu16eaZbbI,2123
2
+ Kernel/KernalInit.py,sha256=vSOKLSx3-mq9wrq0qvgoffpC0bOCtDa55gJW2yvIjSg,428
3
+ Kernel/KernelAudio.py,sha256=Ok3fItLbBS6soVL6RafOjk6kF6SKdnUt4OBXt9s95ok,3328
4
+ Kernel/KernelColor.py,sha256=VAuCAJYxbTT7q_5q8AXvNBI6hm2me7wyES0fgNQo56A,11688
5
+ Kernel/KernelEvent.py,sha256=uSG7WiAMYYxYcS2vnhYSAFRJp0mdJrQyy31gO5DOrzE,4962
6
+ Kernel/KernelLayout.py,sha256=qmT51niftTM3BXLsIvQZ_FnpBbEYN6O897HtffndrfY,2181
7
+ Kernel/KernelPosition.py,sha256=MiBa9e3Y8Bwn7ZAzPg6Rpjlk5A5_m3rf12qDW1U-kko,8837
8
+ Kernel/KernelRun.py,sha256=sTJjybXbztF-Toa8saCh6bei-uAPmkCEBO1SCK7sTlY,3269
9
+ Kernel/KernelWidget.py,sha256=jnixXqRTmXsMzFplEyvv0GDhG6cKv_ZBbmfX3dZfaKc,14153
10
+ Kernel/ObjType.py,sha256=nMDAW4X9sQXJVHp_GZ9VWGwpbiYvACa4CAulWQHhIEE,519
11
+ Kernel/RFlags.py,sha256=5a1_spKQTs5_jKWPb3oCdIb982difdg7eajAIYxpHFc,1900
12
+ Kernel/UFlags.py,sha256=sUYj_ZJVNvJc6FoEz3Cx0po5RRDmm523eC2j8l2XkUY,393
13
+ Kernel/VFlags.py,sha256=vC5NmxwffemPbDr4v33nKjwmE_w4hzTvIXfzKnVoQT4,687
14
+ Kernel/__init__.py,sha256=mMRCcLAqvAIgSKx-ua5RLHUvndSp8Xrf9NLCdMerVL0,397
15
+ Kernel/geometry.py,sha256=NVS79eW6f5qjM-yDgOwVR7658IVbBR1DwCjA0s2Iys8,3916
16
+ Kernel/PgRenderCompo/ButtonObj.py,sha256=9GIyI5ALCLivVTK0tM6d1ulIB2YLR_0DEYjlIWEii_4,7182
17
+ Kernel/PgRenderCompo/LinkRenderfunc.py,sha256=FU1QBj8d8IZl7AQJ6604O72fwk-e95p0IbfeDFCD4XM,2024
18
+ Kernel/PgRenderCompo/RRender.py,sha256=chAI4igqbJpY8s79-UCpT9jijHoHmpXwIeqe32fUjeo,3362
19
+ Kernel/PgRenderCompo/Render.py,sha256=TaG5gMO5Hp50h2EQLFi4n5ilKlVoLzQXzGRJsGSpwTU,3164
20
+ Kernel/PgRenderCompo/TextObj.py,sha256=9g_U35WEaYO3gvSH-Ooj-6nf7M9p7uBygxj4tyaToyg,5430
21
+ Kernel/PgRenderCompo/__init__.py,sha256=zr0m8zWkT6lXVSy5v4ls8TaQKqhU6eUc53QQCye2jOM,226
22
+ pgtkernelbasic-0.22.0.dist-info/METADATA,sha256=I8pwS98eHWe2ZDnzjdvSLPPuIBbbgmv659YJct2jXPQ,266
23
+ pgtkernelbasic-0.22.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
24
+ pgtkernelbasic-0.22.0.dist-info/top_level.txt,sha256=3u1ALZzWhzGJKcnPs01FzOXDJ0qJMXClfgsjPEsOtPE,7
25
+ pgtkernelbasic-0.22.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ Kernel