8
8
from utils import setup_language , get_text , logging
9
9
from launchers import launch_app , system_action
10
10
from settings import SettingsWindow
11
-
12
11
class IconLoader :
13
12
def __init__ (self ):
14
13
self .manager = QNetworkAccessManager ()
15
14
self .icons = {}
16
-
17
15
def load_icon (self , url , callback ):
18
16
if not url :
19
17
logging .error ("Icon URL is empty" )
20
- callback (QPixmap ()) # Return empty pixmap as fallback
18
+ callback (QPixmap ()) # Return empty pixmap as fallback
21
19
return
22
20
request = QNetworkRequest (QUrl (url ))
23
21
reply = self .manager .get (request )
24
22
if reply :
25
23
reply .finished .connect (lambda : self .icon_loaded (reply , callback ))
26
24
else :
27
25
logging .error (f"Failed to create network reply for URL: { url } " )
28
- callback (QPixmap ()) # Return empty pixmap as fallback
29
-
26
+ callback (QPixmap ()) # Return empty pixmap as fallback
30
27
def icon_loaded (self , reply , callback ):
31
28
if reply .error () == QNetworkReply .NoError :
32
29
pixmap = QPixmap ()
@@ -35,14 +32,12 @@ def icon_loaded(self, reply, callback):
35
32
callback (pixmap .scaled (140 , 140 , Qt .KeepAspectRatio , Qt .SmoothTransformation ))
36
33
else :
37
34
logging .error (f"Failed to load pixmap from URL: { reply .url ().toString ()} " )
38
- callback (QPixmap ()) # Fallback empty pixmap
35
+ callback (QPixmap ()) # Fallback empty pixmap
39
36
else :
40
37
logging .error (f"Failed to load icon: { reply .errorString ()} " )
41
- callback (QPixmap ()) # Fallback empty pixmap
38
+ callback (QPixmap ()) # Fallback empty pixmap
42
39
reply .deleteLater ()
43
-
44
40
icon_loader = IconLoader ()
45
-
46
41
class MainWindow (QMainWindow ):
47
42
def __init__ (self ):
48
43
super ().__init__ ()
@@ -54,14 +49,13 @@ def __init__(self):
54
49
self .layout .setAlignment (Qt .AlignCenter )
55
50
self .layout .setSpacing (60 )
56
51
self .layout .setContentsMargins (80 , 80 , 80 , 80 )
57
-
58
52
self .top_layout = QHBoxLayout ()
59
53
self .hackeros_logo = QLabel ()
60
54
self .hackeros_logo .setObjectName ('logo' )
61
55
pixmap_hackeros = QPixmap ('/usr/share/HackerOS/ICONS/HackerOS.png' )
62
56
if pixmap_hackeros .isNull ():
63
57
logging .error ("Failed to load HackerOS.png" )
64
- pixmap_hackeros = QPixmap (120 , 120 ) # Fallback empty pixmap
58
+ pixmap_hackeros = QPixmap (120 , 120 ) # Fallback empty pixmap
65
59
pixmap_hackeros .fill (Qt .transparent )
66
60
self .hackeros_logo .setPixmap (pixmap_hackeros .scaled (120 , 120 , Qt .KeepAspectRatio , Qt .SmoothTransformation ))
67
61
self .hackeros_logo_opacity = QGraphicsOpacityEffect ()
@@ -73,30 +67,26 @@ def __init__(self):
73
67
pixmap_hackermode = QPixmap ('/usr/share/HackerOS/ICONS/Hacker-Mode.png' )
74
68
if pixmap_hackermode .isNull ():
75
69
logging .error ("Failed to load Hacker-Mode.png" )
76
- pixmap_hackermode = QPixmap (120 , 120 ) # Fallback empty pixmap
70
+ pixmap_hackermode = QPixmap (120 , 120 ) # Fallback empty pixmap
77
71
pixmap_hackermode .fill (Qt .transparent )
78
72
self .hackermode_logo .setPixmap (pixmap_hackermode .scaled (120 , 120 , Qt .KeepAspectRatio , Qt .SmoothTransformation ))
79
73
self .hackermode_logo_opacity = QGraphicsOpacityEffect ()
80
74
self .hackermode_logo .setGraphicsEffect (self .hackermode_logo_opacity )
81
75
self .top_layout .addWidget (self .hackermode_logo , alignment = Qt .AlignRight )
82
76
self .layout .addLayout (self .top_layout )
83
-
84
77
self .title = QLabel (get_text ('title' ))
85
78
self .title .setFont (QFont ('Hack' , 70 , QFont .Bold ))
86
79
self .title .setObjectName ('neon-text' )
87
80
self .layout .addWidget (self .title , alignment = Qt .AlignCenter )
88
-
89
81
self .grid_layout = QGridLayout ()
90
82
self .grid_layout .setSpacing (80 )
91
83
self .grid_layout .setContentsMargins (60 , 60 , 60 , 60 )
92
84
self .layout .addLayout (self .grid_layout )
93
-
94
85
self .launcher_buttons = []
95
86
self .add_launcher_button ('steam' , 'https://store.steampowered.com/favicon.ico' , 0 , 0 )
96
87
self .add_launcher_button ('heroic' , 'https://www.heroicgameslauncher.com/favicon.ico' , 0 , 1 )
97
88
self .add_launcher_button ('hyperplay' , 'https://www.hyperplaygaming.com/favicon.ico' , 0 , 2 )
98
89
self .add_launcher_button ('lutris' , 'https://lutris.net/static/images/logo.png' , 0 , 3 )
99
-
100
90
self .bottom_layout = QHBoxLayout ()
101
91
self .hacker_menu_btn = QPushButton (get_text ('hacker_menu' ))
102
92
self .hacker_menu_btn .setObjectName ('action-btn' )
@@ -110,10 +100,8 @@ def __init__(self):
110
100
self .settings_btn .clicked .connect (self .launch_settings )
111
101
self .bottom_layout .addWidget (self .settings_btn , alignment = Qt .AlignRight )
112
102
self .layout .addLayout (self .bottom_layout )
113
-
114
103
self .update_texts ()
115
104
QTimer .singleShot (100 , self .animate_elements )
116
-
117
105
def animate_elements (self ):
118
106
for i , btn in enumerate (self .launcher_buttons ):
119
107
anim = QPropertyAnimation (btn , b"geometry" )
@@ -123,21 +111,18 @@ def animate_elements(self):
123
111
anim .setDuration (2000 )
124
112
anim .setEasingCurve (QEasingCurve .OutQuint )
125
113
QTimer .singleShot (i * 400 , lambda : anim .start ())
126
-
127
114
logo_anim1 = QPropertyAnimation (self .hackeros_logo_opacity , b"opacity" )
128
115
logo_anim1 .setStartValue (0.0 )
129
116
logo_anim1 .setEndValue (1.0 )
130
117
logo_anim1 .setDuration (2000 )
131
118
logo_anim1 .setEasingCurve (QEasingCurve .OutQuint )
132
119
QTimer .singleShot (400 , lambda : logo_anim1 .start ())
133
-
134
120
logo_anim2 = QPropertyAnimation (self .hackermode_logo_opacity , b"opacity" )
135
121
logo_anim2 .setStartValue (0.0 )
136
122
logo_anim2 .setEndValue (1.0 )
137
123
logo_anim2 .setDuration (2000 )
138
124
logo_anim2 .setEasingCurve (QEasingCurve .OutQuint )
139
125
QTimer .singleShot (800 , lambda : logo_anim2 .start ())
140
-
141
126
def add_launcher_button (self , app_name , icon_url , row , col ):
142
127
btn = QPushButton (objectName = 'launcher-btn' )
143
128
btn .setFixedSize (280 , 280 )
@@ -154,7 +139,6 @@ def add_launcher_button(self, app_name, icon_url, row, col):
154
139
btn .clicked .connect (lambda : launch_app (app_name , self ))
155
140
self .grid_layout .addWidget (btn , row , col , alignment = Qt .AlignCenter )
156
141
self .launcher_buttons .append (btn )
157
-
158
142
def update_texts (self ):
159
143
self .setWindowTitle (get_text ('title' ))
160
144
self .title .setText (get_text ('title' ))
@@ -164,12 +148,10 @@ def update_texts(self):
164
148
label = btn .findChildren (QLabel )[1 ]
165
149
key = label .text ().lower ()
166
150
label .setText (get_text (key ))
167
-
168
151
def launch_settings (self ):
169
152
self .hide ()
170
153
self .settings_window = SettingsWindow (self )
171
154
self .settings_window .showFullScreen ()
172
-
173
155
def show_hacker_menu (self ):
174
156
menu = QMenu (self )
175
157
menu .setObjectName ('hacker-menu' )
@@ -179,13 +161,12 @@ def show_hacker_menu(self):
179
161
('restart' , lambda : system_action ('restart' )),
180
162
('sleep' , lambda : system_action ('sleep' )),
181
163
('restart_apps' , lambda : system_action ('restartApps' , self )),
182
- ('restart_sway ' , lambda : system_action ('restartWayfire' ))
164
+ ('restart_app ' , lambda : system_action ('restartApps' , self ))
183
165
]
184
166
for text , callback in actions :
185
167
action = menu .addAction (get_text (text ))
186
168
action .triggered .connect (callback )
187
169
menu .exec (self .hacker_menu_btn .mapToGlobal (self .hacker_menu_btn .rect ().bottomLeft ()))
188
-
189
170
if __name__ == '__main__' :
190
171
app = QApplication (sys .argv )
191
172
stylesheet = """
@@ -287,4 +268,3 @@ def show_hacker_menu(self):
287
268
except Exception as e :
288
269
logging .error (f'Error setting fullscreen in Wayfire: { e } ' )
289
270
sys .exit (app .exec ())
290
-
0 commit comments