crystalwindow 5.2__tar.gz → 5.3__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.
Files changed (53) hide show
  1. {crystalwindow-5.2/crystalwindow.egg-info → crystalwindow-5.3}/PKG-INFO +1 -1
  2. crystalwindow-5.3/crystalwindow/Fonts.py +30 -0
  3. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/__init__.py +12 -0
  4. crystalwindow-5.3/crystalwindow/apphelper.py +101 -0
  5. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/camera.py +11 -3
  6. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/draw_helpers.py +3 -0
  7. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/objects.py +11 -3
  8. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/window.py +7 -1
  9. {crystalwindow-5.2 → crystalwindow-5.3/crystalwindow.egg-info}/PKG-INFO +1 -1
  10. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow.egg-info/SOURCES.txt +2 -0
  11. {crystalwindow-5.2 → crystalwindow-5.3}/setup.py +1 -1
  12. {crystalwindow-5.2 → crystalwindow-5.3}/LICENSE +0 -0
  13. {crystalwindow-5.2 → crystalwindow-5.3}/MANIFEST.in +0 -0
  14. {crystalwindow-5.2 → crystalwindow-5.3}/README.md +0 -0
  15. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/FileHelper.py +0 -0
  16. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/Icons/default_icon.png +0 -0
  17. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/Icons/file_icons.png +0 -0
  18. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/ai.py +0 -0
  19. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/animation.py +0 -0
  20. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/assets.py +0 -0
  21. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/chatvpn.py +0 -0
  22. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/clock.py +0 -0
  23. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/collision.py +0 -0
  24. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/color_handler.py +0 -0
  25. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/crystal3d.py +0 -0
  26. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/docs/getting_started.md +0 -0
  27. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/docs/index.md +0 -0
  28. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/draw_rects.py +0 -0
  29. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/draw_text_helper.py +0 -0
  30. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/draw_tool.py +0 -0
  31. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/fun_helpers.py +0 -0
  32. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/gametests/3dsquare.py +0 -0
  33. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/gametests/__init__.py +0 -0
  34. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/gametests/__main__.py +0 -0
  35. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/gametests/gravitytest.py +0 -0
  36. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/gametests/guitesting.py +0 -0
  37. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/gametests/sandbox.py +0 -0
  38. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/gametests/squaremove.py +0 -0
  39. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/gametests/testtttagain.py +0 -0
  40. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/gametests/windowtesting.py +0 -0
  41. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/gravity.py +0 -0
  42. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/gui.py +0 -0
  43. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/gui_ext.py +0 -0
  44. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/math.py +0 -0
  45. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/messagebus.py +0 -0
  46. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/sprites.py +0 -0
  47. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/tilemap.py +0 -0
  48. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/ver_warner.py +0 -0
  49. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow/websearch.py +0 -0
  50. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow.egg-info/dependency_links.txt +0 -0
  51. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow.egg-info/requires.txt +0 -0
  52. {crystalwindow-5.2 → crystalwindow-5.3}/crystalwindow.egg-info/top_level.txt +0 -0
  53. {crystalwindow-5.2 → crystalwindow-5.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crystalwindow
3
- Version: 5.2
3
+ Version: 5.3
4
4
  Summary: A Tkinter powered window + GUI toolkit made by Crystal (ME)! Easier apps, smoother UI and all-in-one helpers!, Gui, Buttons, FileHelper, Sprites, Animations, Colors, Math, Gravity, Camera, 3D and more!
5
5
  Home-page: https://pypi.org/project/crystalwindow/
6
6
  Author: CrystalBallyHereXD
@@ -0,0 +1,30 @@
1
+ import os
2
+ from PIL import ImageFont
3
+
4
+ class Font:
5
+ def __init__(self, size=16, font_name="Arial", font_path=None):
6
+ self.size = size
7
+ self.font_name = font_name
8
+ self.font_path = font_path
9
+ self.font = self.load_font()
10
+
11
+ def load_font(self):
12
+ try:
13
+ if self.font_path and os.path.isfile(self.font_path):
14
+ return ImageFont.truetype(self.font_path, self.size)
15
+
16
+ return ImageFont.truetype(self.font_name, self.size)
17
+
18
+ except Exception as e:
19
+ print(f"[Font] Fallback used: {e}")
20
+ return ImageFont.load_default()
21
+
22
+ def set_size(self, new_size):
23
+ self.size = new_size
24
+ self.font = self.load_font()
25
+
26
+ def set_font(self, new_font_name=None, new_font_path=None):
27
+ if new_font_name:
28
+ self.font_name = new_font_name
29
+ self.font_path = new_font_path
30
+ self.font = self.load_font()
@@ -58,6 +58,12 @@ from .chatvpn import ChatVPN, ChatVPNServer
58
58
  # ==== Message Bus ====
59
59
  from .messagebus import send_message, view_message, clear_messages
60
60
 
61
+ # ==== Fonts =======
62
+ from .Fonts import Font
63
+
64
+ # === App/Window ====
65
+ from .apphelper import GameAppHelper
66
+
61
67
  __all__ = [
62
68
  # --- Core ---
63
69
  "Window", "Sprite", "TileMap", "Player", "Block", "Enemy", "Gravity", "FileHelper", "Mathematics",
@@ -103,4 +109,10 @@ __all__ = [
103
109
 
104
110
  # --- Message Bus ---
105
111
  "send_message", "view_message", "clear_messages",
112
+
113
+ # === Fonts ===
114
+ "Font",
115
+
116
+ # --- App/Window ---
117
+ "GameAppHelper",
106
118
  ]
@@ -0,0 +1,101 @@
1
+ import os
2
+ import sys
3
+ import subprocess
4
+
5
+ class GameAppHelper:
6
+ DEFAULT_APPS = {
7
+ "notepad": "notepad.exe",
8
+ "calculator": "calc.exe",
9
+ "explorer": "explorer.exe",
10
+ "cmd": "cmd.exe",
11
+ "powershell": "powershell.exe",
12
+ "taskmgr": "taskmgr.exe",
13
+ "paint": "mspaint.exe"
14
+ }
15
+
16
+ def __init__(self):
17
+ # exe_name -> list of processes
18
+ self.running_apps = {}
19
+
20
+ # -------------------------------
21
+ # OPEN DEFAULT WINDOWS APP
22
+ # -------------------------------
23
+ def open_default_app(self, app_name):
24
+ app = self.DEFAULT_APPS.get(app_name.lower())
25
+ if not app:
26
+ print(f"[AppHelper] Unknown default app: {app_name}")
27
+ return
28
+
29
+ self._launch_process(app)
30
+
31
+ # -------------------------------
32
+ # OPEN ANY APP BY PATH OR EXE
33
+ # -------------------------------
34
+ def open_app(self, app_path):
35
+ exe = os.path.basename(app_path)
36
+ self._launch_process(app_path, exe)
37
+
38
+ # -------------------------------
39
+ # INTERNAL LAUNCH
40
+ # -------------------------------
41
+ def _launch_process(self, command, exe_name=None):
42
+ try:
43
+ proc = subprocess.Popen(command)
44
+
45
+ exe = exe_name or os.path.basename(command)
46
+ exe = exe.lower()
47
+
48
+ self.running_apps.setdefault(exe, []).append(proc)
49
+
50
+ print(f"[AppHelper] Opened {exe}")
51
+
52
+ except Exception as e:
53
+ print(f"[AppHelper] Failed to open app: {e}")
54
+
55
+ # -------------------------------
56
+ # CLOSE / KILL BY EXE NAME
57
+ # -------------------------------
58
+ def close_app(self, exe_name):
59
+ exe = exe_name.lower()
60
+ procs = self.running_apps.get(exe)
61
+
62
+ if not procs:
63
+ print(f"[AppHelper] No running app named {exe}")
64
+ return
65
+
66
+ for proc in procs:
67
+ try:
68
+ proc.kill() # HARD kill
69
+ except Exception:
70
+ os.system(f"taskkill /PID {proc.pid} /F")
71
+
72
+ del self.running_apps[exe]
73
+ print(f"[AppHelper] Closed all instances of {exe}")
74
+
75
+ # -------------------------------
76
+ # CLOSE ONLY ONE INSTANCE (OPTIONAL)
77
+ # -------------------------------
78
+ def close_one(self, exe_name):
79
+ exe = exe_name.lower()
80
+ procs = self.running_apps.get(exe)
81
+
82
+ if not procs:
83
+ print(f"[AppHelper] No running app named {exe}")
84
+ return
85
+
86
+ proc = procs.pop()
87
+ try:
88
+ proc.kill()
89
+ except:
90
+ os.system(f"taskkill /PID {proc.pid} /F")
91
+
92
+ if not procs:
93
+ del self.running_apps[exe]
94
+
95
+ print(f"[AppHelper] Closed one instance of {exe}")
96
+
97
+ # -------------------------------
98
+ # CLOSE PYTHON APP
99
+ # -------------------------------
100
+ def close_current_app(self):
101
+ sys.exit()
@@ -4,6 +4,7 @@ class Camera:
4
4
  self.offset_x = 0
5
5
  self.offset_y = 0
6
6
  self.speed = speed # smoothness
7
+ self.shake = None
7
8
 
8
9
  def update(self, win_width, win_height, dt):
9
10
  # camera aims for target selected
@@ -15,13 +16,16 @@ class Camera:
15
16
  self.offset_x += (target_x - self.offset_x) * self.speed
16
17
  self.offset_y += (target_y - self.offset_y) * self.speed
17
18
 
18
- if hasattr(self, "shake"):
19
- self.shake.update(dt)
19
+ if self.shake:
20
+ alive = self.shake.update(dt)
21
+ if not alive:
22
+ self.shake = None # 💥 ACTUALLY STOPS IT
23
+
20
24
 
21
25
  def apply(self, obj):
22
26
  # shift object's draw position by camera offset
23
27
  sx, sy = (0, 0)
24
- if hasattr(self, "shake"):
28
+ if self.shake:
25
29
  sx, sy = self.shake.offset
26
30
 
27
31
  return (
@@ -34,6 +38,10 @@ class Camera:
34
38
  from .draw_helpers import CameraShake
35
39
  self.shake = CameraShake(intensity, secs)
36
40
 
41
+ # Helper if the shake_scrn dosent want to stop
42
+ def stop_shake(self):
43
+ self.shake = None
44
+
37
45
  def move_to(self, x, y):
38
46
  self.offset_x = x
39
47
  self.offset_y = y
@@ -20,11 +20,14 @@ class CameraShake:
20
20
 
21
21
  def update(self, dt):
22
22
  import random
23
+
23
24
  if self.time_left > 0:
24
25
  self.time_left -= dt
25
26
  self.offset = (
26
27
  random.randint(-self.intensity, self.intensity),
27
28
  random.randint(-self.intensity, self.intensity)
28
29
  )
30
+ return True
29
31
  else:
30
32
  self.offset = (0, 0)
33
+ return False
@@ -128,12 +128,20 @@ class Player(Sprite):
128
128
  # BLOCK (same)
129
129
  # ============================================================
130
130
  class Block(Sprite):
131
- def __init__(self, pos, w, h, color=None, texture=None):
131
+ def __init__(self, x, y, w, h, color=None, texture=None):
132
+ self.x = x
133
+ self.y = y
134
+ self.w, self.h = w, h
135
+ self.color = color
136
+
132
137
  if texture:
133
138
  img = load_image(texture)
134
- super().__init__(pos, size=(w, h), image=img)
139
+ super().__init__((x, y), size=(w, h), image=img)
135
140
  else:
136
- super().__init__(pos, size=(w, h), color=color or (150,150,150))
141
+ super().__init__((x, y), size=(w, h), color=color or (150,150,150))
142
+
143
+ def draw(self, win):
144
+ win.draw_rect(self.color, (self.x, self.y, self.w, self.h))
137
145
 
138
146
  def collide_with(self, other):
139
147
  return self.colliderect(other)
@@ -153,7 +153,7 @@ class Window:
153
153
  self._bg_color = (20, 20, 50)
154
154
  self.draw_calls = []
155
155
  self._key_last = {} # new dict to store last press time per key
156
- self._key_cooldown = 0.00001 # seconds, tweak for faster/slower input
156
+ self._key_cooldown = 0.0001 # seconds, tweak for faster/slower input
157
157
 
158
158
  # === Event bindings ===
159
159
  self.root.bind("<KeyPress>", self._on_keydown)
@@ -193,6 +193,7 @@ class Window:
193
193
  pressed[event.num - 1] = False
194
194
  self._mouse_pressed = tuple(pressed)
195
195
 
196
+
196
197
  # === Helpers ===
197
198
  def key_pressed(self, key):
198
199
  if isinstance(key, str):
@@ -208,6 +209,11 @@ class Window:
208
209
 
209
210
  return False
210
211
 
212
+ def key_held(self, key):
213
+ if isinstance(key, str):
214
+ key = self.KEY_MAP.get(key, key)
215
+ return self.keys.get(key, False)
216
+
211
217
  def mouse_pressed(self, button=1):
212
218
  return self._mouse_pressed[button - 1]
213
219
  def add_tab(self, title, widget):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crystalwindow
3
- Version: 5.2
3
+ Version: 5.3
4
4
  Summary: A Tkinter powered window + GUI toolkit made by Crystal (ME)! Easier apps, smoother UI and all-in-one helpers!, Gui, Buttons, FileHelper, Sprites, Animations, Colors, Math, Gravity, Camera, 3D and more!
5
5
  Home-page: https://pypi.org/project/crystalwindow/
6
6
  Author: CrystalBallyHereXD
@@ -3,9 +3,11 @@ MANIFEST.in
3
3
  README.md
4
4
  setup.py
5
5
  crystalwindow/FileHelper.py
6
+ crystalwindow/Fonts.py
6
7
  crystalwindow/__init__.py
7
8
  crystalwindow/ai.py
8
9
  crystalwindow/animation.py
10
+ crystalwindow/apphelper.py
9
11
  crystalwindow/assets.py
10
12
  crystalwindow/camera.py
11
13
  crystalwindow/chatvpn.py
@@ -7,7 +7,7 @@ with open("README.md", encoding="utf-8") as f:
7
7
 
8
8
  setup(
9
9
  name="crystalwindow",
10
- version="5.2", # Force metadata refresh
10
+ version="5.3", # Force metadata refresh
11
11
  packages=find_packages(include=["crystalwindow", "crystalwindow.*"]),
12
12
 
13
13
  include_package_data=True, # include package_data files
File without changes
File without changes
File without changes
File without changes