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.
- {crystalwindow-5.4/crystalwindow.egg-info → crystalwindow-5.6}/PKG-INFO +1 -1
- crystalwindow-5.6/crystalwindow/System.py +137 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/__init__.py +7 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/math.py +23 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/window.py +17 -8
- {crystalwindow-5.4 → crystalwindow-5.6/crystalwindow.egg-info}/PKG-INFO +1 -1
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow.egg-info/SOURCES.txt +1 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/setup.py +1 -1
- {crystalwindow-5.4 → crystalwindow-5.6}/LICENSE +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/MANIFEST.in +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/README.md +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/FileHelper.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/Fonts.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/Icons/default_icon.png +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/Icons/file_icons.png +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/ai.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/animation.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/apphelper.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/assets.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/camera.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/chatvpn.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/clock.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/collision.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/color_handler.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/crystal3d.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/docs/getting_started.md +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/docs/index.md +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/draw_helpers.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/draw_rects.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/draw_text_helper.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/draw_tool.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/fun_helpers.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/gametests/3dsquare.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/gametests/__init__.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/gametests/__main__.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/gametests/gravitytest.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/gametests/guitesting.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/gametests/sandbox.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/gametests/squaremove.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/gametests/testtttagain.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/gametests/windowtesting.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/gravity.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/gui.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/gui_ext.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/messagebus.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/objects.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/sprites.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/tilemap.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/ver_warner.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow/websearch.py +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow.egg-info/dependency_links.txt +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow.egg-info/requires.txt +0 -0
- {crystalwindow-5.4 → crystalwindow-5.6}/crystalwindow.egg-info/top_level.txt +0 -0
- {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.
|
|
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
|
-
|
|
125
|
+
# === ICON HANDLING (SAFE + DEFERRED) ===
|
|
126
|
+
self._icon_ref = None # prevent GC
|
|
127
|
+
|
|
128
|
+
if icon:
|
|
126
129
|
try:
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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.
|
|
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
|
|
@@ -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.
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|