crystalwindow 5.4__tar.gz → 5.6__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 (54) hide show
  1. {crystalwindow-5.4/crystalwindow.egg-info → crystalwindow-5.6}/PKG-INFO +1 -1
  2. crystalwindow-5.6/crystalwindow/System.py +137 -0
  3. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/__init__.py +7 -0
  4. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/math.py +23 -0
  5. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/window.py +17 -8
  6. {crystalwindow-5.4 → crystalwindow-5.6/crystalwindow.egg-info}/PKG-INFO +1 -1
  7. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow.egg-info/SOURCES.txt +1 -0
  8. {crystalwindow-5.4 → crystalwindow-5.6}/setup.py +1 -1
  9. {crystalwindow-5.4 → crystalwindow-5.6}/LICENSE +0 -0
  10. {crystalwindow-5.4 → crystalwindow-5.6}/MANIFEST.in +0 -0
  11. {crystalwindow-5.4 → crystalwindow-5.6}/README.md +0 -0
  12. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/FileHelper.py +0 -0
  13. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/Fonts.py +0 -0
  14. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/Icons/default_icon.png +0 -0
  15. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/Icons/file_icons.png +0 -0
  16. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/ai.py +0 -0
  17. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/animation.py +0 -0
  18. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/apphelper.py +0 -0
  19. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/assets.py +0 -0
  20. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/camera.py +0 -0
  21. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/chatvpn.py +0 -0
  22. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/clock.py +0 -0
  23. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/collision.py +0 -0
  24. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/color_handler.py +0 -0
  25. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/crystal3d.py +0 -0
  26. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/docs/getting_started.md +0 -0
  27. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/docs/index.md +0 -0
  28. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/draw_helpers.py +0 -0
  29. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/draw_rects.py +0 -0
  30. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/draw_text_helper.py +0 -0
  31. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/draw_tool.py +0 -0
  32. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/fun_helpers.py +0 -0
  33. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/gametests/3dsquare.py +0 -0
  34. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/gametests/__init__.py +0 -0
  35. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/gametests/__main__.py +0 -0
  36. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/gametests/gravitytest.py +0 -0
  37. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/gametests/guitesting.py +0 -0
  38. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/gametests/sandbox.py +0 -0
  39. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/gametests/squaremove.py +0 -0
  40. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/gametests/testtttagain.py +0 -0
  41. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/gametests/windowtesting.py +0 -0
  42. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/gravity.py +0 -0
  43. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/gui.py +0 -0
  44. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/gui_ext.py +0 -0
  45. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/messagebus.py +0 -0
  46. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/objects.py +0 -0
  47. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/sprites.py +0 -0
  48. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/tilemap.py +0 -0
  49. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/ver_warner.py +0 -0
  50. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/websearch.py +0 -0
  51. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow.egg-info/dependency_links.txt +0 -0
  52. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow.egg-info/requires.txt +0 -0
  53. {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow.egg-info/top_level.txt +0 -0
  54. {crystalwindow-5.4 → crystalwindow-5.6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crystalwindow
3
- Version: 5.4
3
+ Version: 5.6
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,137 @@
1
+ import sys
2
+ import os
3
+ import time
4
+ import platform
5
+ import atexit
6
+
7
+
8
+ class System:
9
+ def __init__(self):
10
+ # ---------- BASIC INFO ----------
11
+ self.system_name = self._get_os_name()
12
+ self.python_version = sys.version
13
+ self.platform = sys.platform
14
+ self.executable = sys.executable
15
+ self.cwd = os.getcwd()
16
+
17
+ # ---------- RUNTIME ----------
18
+ self.start_time = time.time()
19
+ self.logs = []
20
+
21
+ # ---------- CRASH DETECTION ----------
22
+ self.flag_file = ".cw_running.flag"
23
+ self.last_run_crashed = os.path.exists(self.flag_file)
24
+
25
+ # mark app as running
26
+ with open(self.flag_file, "w") as f:
27
+ f.write("running")
28
+
29
+ # cleanup on clean exit
30
+ atexit.register(self._clean_exit)
31
+
32
+ self.log("System initialized")
33
+ if self.last_run_crashed:
34
+ self.log("WARNING: last run did not exit cleanly")
35
+
36
+ # ==============================
37
+ # OS NAME (WINDOWS 11 ETC)
38
+ # ==============================
39
+ def _get_os_name(self):
40
+ system = platform.system()
41
+
42
+ if system == "Windows":
43
+ # returns 10 or 11
44
+ return f"Windows {platform.release()}"
45
+ elif system == "Linux":
46
+ return "Linux"
47
+ elif system == "Darwin":
48
+ return "macOS"
49
+ else:
50
+ return system
51
+
52
+ # ==============================
53
+ # CRASH / STATUS
54
+ # ==============================
55
+ def crashed_before(self):
56
+ return self.last_run_crashed
57
+
58
+ def _clean_exit(self):
59
+ if os.path.exists(self.flag_file):
60
+ os.remove(self.flag_file)
61
+ self.log("Clean exit")
62
+
63
+ # ==============================
64
+ # TIME
65
+ # ==============================
66
+ def uptime_seconds(self):
67
+ return int(time.time() - self.start_time)
68
+
69
+ def uptime_formatted(self):
70
+ s = self.uptime_seconds()
71
+ m, s = divmod(s, 60)
72
+ h, m = divmod(m, 60)
73
+ return f"{h:02}:{m:02}:{s:02}"
74
+
75
+ # ==============================
76
+ # LOGGING
77
+ # ==============================
78
+ def log(self, msg):
79
+ timestamp = time.strftime("%H:%M:%S")
80
+ entry = f"[{timestamp}] {msg}"
81
+ self.logs.append(entry)
82
+
83
+ def save_logs(self, path="system.log"):
84
+ with open(path, "a", encoding="utf-8") as f:
85
+ for line in self.logs:
86
+ f.write(line + "\n")
87
+ self.logs.clear()
88
+
89
+ # ==============================
90
+ # INFO DUMP
91
+ # ==============================
92
+ def get_system_info(self):
93
+ return {
94
+ "system": self.system_name,
95
+ "platform": self.platform,
96
+ "python": self.python_version,
97
+ "executable": self.executable,
98
+ "cwd": self.cwd,
99
+ "uptime": self.uptime_formatted(),
100
+ "last_run_crashed": self.last_run_crashed
101
+ }
102
+
103
+ def delete_file(self, path):
104
+ try:
105
+ if os.path.exists(path):
106
+ os.remove(path)
107
+ self.log(f"Deleted file: {path}")
108
+ return True
109
+ else:
110
+ self.log(f"File not found for deletion: {path}")
111
+ return False
112
+ except Exception as e:
113
+ self.log(f"Error deleting file {path}: {e}")
114
+ return False
115
+
116
+ def create_file(name, filetype):
117
+ full_name = f"{name}.{filetype}"
118
+ try:
119
+ with open(full_name, "w") as f:
120
+ f.write("") # create empty file
121
+ return True
122
+ except Exception as e:
123
+ return False
124
+
125
+ # ==============================
126
+ # WATCHDOG (FREEZE DETECTOR)
127
+ # ==============================
128
+ class Watchdog:
129
+ def __init__(self, timeout=3):
130
+ self.timeout = timeout
131
+ self.last_ping = time.time()
132
+
133
+ def ping(self):
134
+ self.last_ping = time.time()
135
+
136
+ def frozen(self):
137
+ return (time.time() - self.last_ping) > self.timeout
@@ -64,6 +64,10 @@ from .Fonts import Font
64
64
  # === App/Window ====
65
65
  from .apphelper import GameAppHelper
66
66
 
67
+ # === System ===
68
+ from .System import System, Watchdog
69
+
70
+
67
71
  __all__ = [
68
72
  # --- Core ---
69
73
  "Window", "Sprite", "TileMap", "Player", "Block", "Enemy", "Gravity", "FileHelper", "Mathematics",
@@ -115,4 +119,7 @@ __all__ = [
115
119
 
116
120
  # --- App/Window ---
117
121
  "GameAppHelper",
122
+
123
+ # --- System ---
124
+ "System", "Watchdog",
118
125
  ]
@@ -1,3 +1,4 @@
1
+ import matplotlib.pyplot as plt
1
2
  class Mathematics:
2
3
  """
3
4
  A class used to perform basic mathematical operations.
@@ -38,3 +39,25 @@ class Mathematics:
38
39
  raise ZeroDivisionError("Cannot divide by zero!")
39
40
  return num1 / num2
40
41
 
42
+
43
+ @staticmethod
44
+ def export_graph(object, object2, filetype="png", filename="graph"):
45
+ """
46
+ object -> x values (list)
47
+ object2 -> y values (list)
48
+ filetype -> png, webp, jpeg
49
+ """
50
+
51
+ if len(object) != len(object2):
52
+ raise ValueError("X and Y must be same length bruh")
53
+
54
+ plt.figure()
55
+ plt.plot(object, object2, marker="o")
56
+ plt.xlabel("X Axis")
57
+ plt.ylabel("Y Axis")
58
+ plt.title("Generated Graph")
59
+
60
+ plt.grid(True)
61
+
62
+ plt.savefig(f"{filename}.{filetype}")
63
+ plt.close()
@@ -122,17 +122,26 @@ class Window:
122
122
  self.root.protocol("WM_DELETE_WINDOW", self.quit)
123
123
 
124
124
  # === ICON HANDLING ===
125
- if icon and os.path.exists(icon):
125
+ # === ICON HANDLING (SAFE + DEFERRED) ===
126
+ self._icon_ref = None # prevent GC
127
+
128
+ if icon:
126
129
  try:
127
- img = tk.PhotoImage(file=icon)
128
- self.root.iconphoto(True, img)
129
- except Exception:
130
- print("⚠️ Icon load failed, using default")
131
- img = decode_logo()
132
- if img: self.root.iconphoto(True, img)
133
- else:
130
+ if isinstance(icon, str) and os.path.exists(icon):
131
+ self._icon_ref = tk.PhotoImage(file=icon, master=self.root)
132
+ elif isinstance(icon, tk.PhotoImage):
133
+ self._icon_ref = icon
134
+ if self._icon_ref:
135
+ self.root.iconphoto(True, self._icon_ref)
136
+
137
+ except Exception as e:
138
+ print("⚠️ Icon load failed, using default", e)
139
+
140
+ # fallback logo
141
+ if not self._icon_ref:
134
142
  logo = decode_logo()
135
143
  if logo:
144
+ self._icon_ref = logo
136
145
  self.root.iconphoto(True, logo)
137
146
 
138
147
  # === Canvas setup ===
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crystalwindow
3
- Version: 5.4
3
+ Version: 5.6
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
@@ -4,6 +4,7 @@ README.md
4
4
  setup.py
5
5
  crystalwindow/FileHelper.py
6
6
  crystalwindow/Fonts.py
7
+ crystalwindow/System.py
7
8
  crystalwindow/__init__.py
8
9
  crystalwindow/ai.py
9
10
  crystalwindow/animation.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.4", # Force metadata refresh
10
+ version="5.6", # 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