-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
249 lines (206 loc) · 9.5 KB
/
main.py
File metadata and controls
249 lines (206 loc) · 9.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Importa as bibliotecas necessárias.
# O gi (GObject Introspection) é usado para criar bindings para bibliotecas baseadas em GObject, como GTK e Adwaita.
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
from gi.repository import Gtk, Adw, Gio, GLib
import os
import gettext
# Configura o gettext para tradução.
APPNAME = "cornercraft"
LOCALE_DIR = os.path.join(os.environ["HOME"], ".local/share/locale")
gettext.bindtextdomain(APPNAME, LOCALE_DIR)
gettext.textdomain(APPNAME)
_ = gettext.gettext
# Define a classe principal da aplicação, que herda de Adw.Application.
# O Adw.Application é uma classe especial que lida com o ciclo de vida da aplicação.
class CornerCraftApp(Adw.Application):
def __init__(self, **kwargs):
# O super().__init__() chama o construtor da classe pai (Adw.Application).
super().__init__(**kwargs)
# Conecta o sinal 'activate' a um método (on_activate).
# O sinal 'activate' é emitido quando a aplicação é iniciada.
self.connect('activate', self.on_activate)
def on_activate(self, app):
# Este método é chamado quando a aplicação é ativada.
# Cria uma instância da nossa janela principal (MainWindow).
self.win = MainWindow(application=app)
# Apresenta a janela ao usuário.
self.win.present()
# Define a classe da janela principal, que herda de Gtk.ApplicationWindow.
class MainWindow(Gtk.ApplicationWindow):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Define o ícone da janela
self.set_icon_name("cornercraft")
# Define o tamanho padrão e o título da janela.
self.set_default_size(400, 500)
self.set_title(_("CornerCraft"))
# Cria uma caixa vertical (Gtk.Box) para organizar os widgets.
self.box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)
# Adiciona a caixa como o widget filho da janela.
self.set_child(self.box)
# Cria um Adw.HeaderBar, que é a barra de título da janela.
self.header = Adw.HeaderBar()
self.set_titlebar(self.header)
# Cria uma Adw.PreferencesPage, que é uma página de preferências padrão do Adwaita.
self.page = Adw.PreferencesPage()
self.box.append(self.page)
# Cria um grupo de preferências (Adw.PreferencesGroup) para os raios dos cantos.
self.group = Adw.PreferencesGroup(title=_("Corner Radius"))
self.page.add(self.group)
# Lock switch
self.lock_row = Adw.ActionRow(title=_("Lock all values"))
self.group.add(self.lock_row)
self.lock_switch = Gtk.Switch()
self.lock_switch.set_active(False)
self.lock_switch.connect("notify::active", self.on_lock_switch_toggled)
self.lock_row.add_suffix(self.lock_switch)
self.lock_row.set_activatable_widget(self.lock_switch)
# Raio das janelas
self.windows_row = Adw.ActionRow(title=_("Windows radius"))
self.group.add(self.windows_row)
self.windows_spin = Gtk.SpinButton.new_with_range(0, 100, 1)
self.windows_spin.set_value(12)
self.windows_spin.connect("value-changed", self.on_windows_spin_changed)
self.windows_row.add_suffix(self.windows_spin)
self.windows_row.set_activatable_widget(self.windows_spin)
# Raio de Radio, Switch
self.radio_switch_row = Adw.ActionRow(title=_("Radio, Switch radius"))
self.group.add(self.radio_switch_row)
self.radio_switch_spin = Gtk.SpinButton.new_with_range(0, 100, 1)
self.radio_switch_spin.set_value(12)
self.radio_switch_row.add_suffix(self.radio_switch_spin)
self.radio_switch_row.set_activatable_widget(self.radio_switch_spin)
# Raio dos Botões
self.buttons_row = Adw.ActionRow(title=_("Buttons radius"))
self.group.add(self.buttons_row)
self.buttons_spin = Gtk.SpinButton.new_with_range(0, 100, 1)
self.buttons_spin.set_value(12)
self.buttons_row.add_suffix(self.buttons_spin)
self.buttons_row.set_activatable_widget(self.buttons_spin)
# Raio das Entradas de Texto
self.text_inputs_row = Adw.ActionRow(title=_("Text Inputs radius"))
self.group.add(self.text_inputs_row)
self.text_inputs_spin = Gtk.SpinButton.new_with_range(0, 100, 1)
self.text_inputs_spin.set_value(12)
self.text_inputs_row.add_suffix(self.text_inputs_spin)
self.text_inputs_row.set_activatable_widget(self.text_inputs_spin)
# Raio de Menus e Popovers
self.menus_popovers_row = Adw.ActionRow(title=_("Menus and Popovers radius"))
self.group.add(self.menus_popovers_row)
self.menus_popovers_spin = Gtk.SpinButton.new_with_range(0, 100, 1)
self.menus_popovers_spin.set_value(12)
self.menus_popovers_row.add_suffix(self.menus_popovers_spin)
self.menus_popovers_row.set_activatable_widget(self.menus_popovers_spin)
# Caixa de botões
self.button_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6, margin_top=12, margin_bottom=12, margin_start=12, margin_end=12)
self.box.append(self.button_box)
# Botão "Set" (Aplicar)
self.set_button = Gtk.Button(label=_("Set"))
self.set_button.connect("clicked", self.on_set_clicked)
self.button_box.append(self.set_button)
# Botão "Restore Defaults" (Restaurar Padrões)
self.restore_button = Gtk.Button(label=_("Restore Defaults"))
self.restore_button.connect("clicked", self.on_restore_clicked)
self.button_box.append(self.restore_button)
self.on_lock_switch_toggled(self.lock_switch)
def on_lock_switch_toggled(self, switch, *args):
is_active = switch.get_active()
self.radio_switch_spin.set_sensitive(not is_active)
self.buttons_spin.set_sensitive(not is_active)
self.text_inputs_spin.set_sensitive(not is_active)
self.menus_popovers_spin.set_sensitive(not is_active)
if is_active:
self.sync_values()
def on_windows_spin_changed(self, spin_button):
if self.lock_switch.get_active():
self.sync_values()
def sync_values(self):
value = self.windows_spin.get_value()
self.radio_switch_spin.set_value(value)
self.buttons_spin.set_value(value)
self.text_inputs_spin.set_value(value)
self.menus_popovers_spin.set_value(value)
# Método chamado quando o botão "Set" é clicado.
def on_set_clicked(self, widget):
self.apply_css()
# Método chamado quando o botão "Restore Defaults" é clicado.
def on_restore_clicked(self, widget):
# Restaura os valores padrão dos SpinButtons.
self.windows_spin.set_value(12)
self.radio_switch_spin.set_value(12)
self.buttons_spin.set_value(12)
self.text_inputs_spin.set_value(12)
self.menus_popovers_spin.set_value(12)
self.lock_switch.set_active(False)
# Aplica o CSS vazio para remover as personalizações.
self.apply_css(restore=True)
# Método que aplica o CSS.
def apply_css(self, restore=False):
# <-- aqui entra A NOVA VERSÃO que só mexe no bloco CornerCraft
home = os.path.expanduser("~")
gtk3_css_path = os.path.join(home, ".config/gtk-3.0/gtk.css")
gtk4_css_path = os.path.join(home, ".config/gtk-4.0/gtk.css")
windows_radius = self.windows_spin.get_value_as_int()
radio_switch_radius = self.radio_switch_spin.get_value_as_int()
buttons_radius = self.buttons_spin.get_value_as_int()
text_inputs_radius = self.text_inputs_spin.get_value_as_int()
menus_popovers_radius = self.menus_popovers_spin.get_value_as_int()
block_start = "/* CornerCraft start*/"
block_end = "/* CornerCraft end*/"
if not restore:
css_block = f"""
{block_start}
* {{
border-radius: {windows_radius}px;
}}
radio, switch, slider {{
border-radius: {radio_switch_radius}px;
}}
button {{
border-radius: {buttons_radius}px;
}}
entry, textview {{
border-radius: {text_inputs_radius}px;
}}
menu, popover {{
border-radius: {menus_popovers_radius}px;
}}
{block_end}
"""
else:
css_block = ""
def update_file(path: str):
os.makedirs(os.path.dirname(path), exist_ok=True)
try:
with open(path, "r") as f:
content = f.read()
except FileNotFoundError:
content = ""
start_idx = content.find(block_start)
if start_idx != -1:
end_idx = content.find(block_end, start_idx)
if end_idx != -1:
end_idx += len(block_end)
content = content[:start_idx] + content[end_idx:]
content = content.strip()
if css_block.strip():
if content:
new_content = content + "\n\n" + css_block.strip() + "\n"
else:
new_content = css_block.strip() + "\n"
else:
new_content = content + ("\n" if content else "")
with open(path, "w") as f:
f.write(new_content)
update_file(gtk3_css_path)
update_file(gtk4_css_path)
# Ponto de entrada da aplicação.
if __name__ == "__main__":
# Cria uma instância da nossa aplicação.
app = CornerCraftApp(application_id="com.github.dudumaroja.cornercraft")
# Executa a aplicação.
app.run([])