-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlibuigtk.c
More file actions
316 lines (253 loc) · 8.26 KB
/
libuigtk.c
File metadata and controls
316 lines (253 loc) · 8.26 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
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
#include "libuigtk.h"
/*___MACROS___________________________________________________________________*/
/* mensagens */
#define UIGTK_MSG_INIT "UIGTK already initialized."
#define UIGTK_MSG_NO_BUILDER "Error getting GtkBuilder."
#define UIGTK_MSG_NO_WINDOW "Top level window (GtkWindow) not found."
#define UIGTK_MSG_NO_INIT "UIGTK not initialized."
#define UIGTK_MSG_NO_QUIT "gtk_main_quit handler not found."
#define UIGTK_MSG_ERR_QUIT "Error when setting gtk_main_quit automatically."
#define UIGTK_MSG_NO_FILE "Interface file not found."
/* protótipos */
#define UIGTK_INIT "uigtk_init (char *file)"
#define UIGTK_CALLBACK "void uigtk_callback (char *name, void (*handler)())"
#define UIGTK_HANDLER "uigtk_handler (handler)"
#define UIGTK_MAIN "uigtk_main (void)"
#define UIGTK_BUILDER "uigtk_builder (void)"
#define UIGTK_OBJECT "uigtk_object (char *id)"
#define UIGTK_SET_OBJECT "uigtk_set_object (var, id)"
#define UIGTK_DIALOG "uigtk_dialog (int type, char *title, char *text)"
/* mensagem de saída padrão */
#define UIGTK_MSG "\n\
\033[0;1;7;%dm %s \
\033[0m \
\033[0;1;3;96mlibuigtk\
\033[0m > %s\
\033[0;2;3m\n\t%s\
\033[0m\n\n"
/* mensagens de erro */
#define UIGTK_INFO(msg) \
g_print(UIGTK_MSG, 34, "INFO", _uigtk_prototype, msg)
#define UIGTK_WARN(msg) \
g_print(UIGTK_MSG, 33, "WARN", _uigtk_prototype, msg)
#define UIGTK_ERROR(msg) \
g_printerr(UIGTK_MSG, 31, "ERROR", _uigtk_prototype, msg)
/*___VARIÁVEIS_INTERNAS_______________________________________________________*/
static int _uigtk_init = 0; /* registra a inicialização do uigtk */
static int _uigtk_quit = 0; /* registra existência de gtk_main_quit */
static int _uigtk_win = 0; /* registra existência de toplevel */
static char *_uigtk_prototype = NULL; /* registra o protótipo da função */
static GtkBuilder *_uigtk_builder = NULL; /* guarda o construtor */
static GtkWindow *_uigtk_window = NULL; /* guarda a janela principal */
/*___FUNÇÕES_INTERNAS_________________________________________________________*/
static int _uigtk_top_level (void)
/* Localiza window top level: retorna 1 ou 0 (sucesso ou erro) */
{
/* definindo valor inicial */
_uigtk_win = 0;
/* obter objetos */
/* https://developer.gnome.org/gtk3/stable/GtkBuilder.html#gtk-builder-get-objects */
GSList *objects = gtk_builder_get_objects(_uigtk_builder);
/* obter janela */
/* https://developer.gnome.org/gtk3/stable/GtkWidget.html#gtk-widget-get-toplevel */
GtkWidget *window = gtk_widget_get_toplevel((GtkWidget*) objects->data);
/* limpar memória */
/* https://developer.gnome.org/glib/stable/glib-Singly-Linked-Lists.html#g-slist-free */
g_slist_free(objects);
/* checar sucesso na obtenção da janela */
/* https://developer.gnome.org/gtk3/stable/GtkWidget.html#gtk-widget-is-toplevel */
if (gtk_widget_is_toplevel(window)) {
_uigtk_window = GTK_WINDOW(window);
_uigtk_win = 1;
}
return _uigtk_win;
}
/*___FUNÇÕES_DO_CABEÇALHO____________________________________________________*/
int uigtk_init (char *file)
{
/* definindo protótipo */
_uigtk_prototype = UIGTK_INIT;
/* Verificando se a inicialização já ocorreu */
if (_uigtk_init) {
UIGTK_WARN(UIGTK_MSG_INIT);
return 0;
}
/* Carregando GTK */
/* https://developer.gnome.org/gtk3/stable/gtk3-General.html#gtk-init */
gtk_init(0, NULL);
/* testando a existência do arquivo */
if (file == NULL || !g_file_test (file, G_FILE_TEST_EXISTS)) {
UIGTK_ERROR(UIGTK_MSG_NO_FILE);
return 0;
}
/* Carregando GTK Builder */
/* https://developer.gnome.org/gtk3/stable/GtkBuilder.html#gtk-builder-new-from-file */
_uigtk_builder = gtk_builder_new_from_file(file);
/* exagero de cautela: no caso de erro acima, deveria abortar o programa */
if (_uigtk_builder == NULL) {
UIGTK_ERROR(UIGTK_MSG_NO_BUILDER);
return 0;
}
/* Obtendo a window top level */
if (!_uigtk_top_level()) {
UIGTK_INFO(UIGTK_MSG_NO_WINDOW);
}
/* Defindo sucesso na inicialização */
_uigtk_init = 1;
return _uigtk_init;
}
/*...........................................................................*/
int uigtk_callback (char *name, void (*handler)())
{
/* definindo protótipo */
_uigtk_prototype = UIGTK_CALLBACK;
/* Verificando se a inicialização já ocorreu */
if (!_uigtk_init) {
UIGTK_ERROR(UIGTK_MSG_NO_INIT);
return 0;
}
/* Definindo handlers */
/* https://developer.gnome.org/gtk3/stable/GtkBuilder.html#gtk-builder-add-callback-symbol */
gtk_builder_add_callback_symbol(_uigtk_builder, name, G_CALLBACK(handler));
/* Validando gtk_main_quit */
/* https://developer.gnome.org/gtk3/stable/gtk3-General.html#gtk-main-quit */
if (handler == gtk_main_quit) {
_uigtk_quit = 1;
}
return 1;
}
/*...........................................................................*/
int uigtk_main (void)
{
/* variáveis iniciais */
int gsignal;
/* definindo protótipo */
_uigtk_prototype = UIGTK_MAIN;
/* Verificando se a inicialização já ocorreu */
if (!_uigtk_init) {
UIGTK_ERROR(UIGTK_MSG_NO_INIT);
return 0;
}
/* Adicionar gtk_main_quit se não definido */
/* https://developer.gnome.org/gobject/stable/gobject-Signals.html#g-signal-connect */
if (!_uigtk_quit && _uigtk_window) {
UIGTK_INFO(UIGTK_MSG_NO_QUIT);
gsignal = g_signal_connect(
G_OBJECT(_uigtk_window), "destroy", G_CALLBACK(gtk_main_quit), NULL
);
if (gsignal <= 0) {
UIGTK_INFO(UIGTK_MSG_ERR_QUIT);
}
}
/* Conectando sinais */
/* https://developer.gnome.org/gtk3/stable/GtkBuilder.html#gtk-builder-connect-signals */
gtk_builder_connect_signals(_uigtk_builder, NULL);
/* GTK main loop */
/* https://developer.gnome.org/gtk3/stable/gtk3-General.html#gtk-main */
gtk_main();
/* Resetando status */
_uigtk_init = 0;
_uigtk_win = 0;
_uigtk_quit = 0;
_uigtk_builder = NULL;
_uigtk_window = NULL;
return 1;
}
/*...........................................................................*/
GtkBuilder *uigtk_builder (void)
{
/* definindo protótipo */
_uigtk_prototype = UIGTK_BUILDER;
/* Verificando se a inicialização já ocorreu */
if (!_uigtk_init) {
UIGTK_ERROR(UIGTK_MSG_NO_INIT);
return NULL;
}
/* retornando valor */
return _uigtk_builder;
}
/*...........................................................................*/
GObject *uigtk_object (char *id)
{
/* definindo protótipo */
_uigtk_prototype = UIGTK_OBJECT;
/* Verificando se a inicialização já ocorreu */
if (!_uigtk_init) {
UIGTK_ERROR(UIGTK_MSG_NO_INIT);
return NULL;
};
/* Retornando objeto */
/* https://developer.gnome.org/gtk3/stable/GtkBuilder.html#gtk-builder-get-object */
return gtk_builder_get_object(_uigtk_builder, id);
}
/*...........................................................................*/
int uigtk_dialog (int type, char *title, char *text)
{
/* definindo protótipo */
_uigtk_prototype = UIGTK_DIALOG;
/* Verificando se a inicialização já ocorreu */
if (!_uigtk_init) {
UIGTK_INFO(UIGTK_MSG_NO_INIT);
gtk_init(0, NULL);
};
/* Verificando se há window toplevel */
if (!_uigtk_win) {
UIGTK_INFO(UIGTK_MSG_NO_WINDOW);
};
/* Definir variáveis */
GtkButtonsType button;
GtkMessageType style;
GtkWidget *dialog;
int result;
/* definindo o tipo de botão e de mensagem */
switch(type) {
case 0:
style = GTK_MESSAGE_INFO;
button = GTK_BUTTONS_OK;
break;
case 1:
style = GTK_MESSAGE_WARNING;
button = GTK_BUTTONS_OK;
break;
case 2:
style = GTK_MESSAGE_ERROR;
button = GTK_BUTTONS_OK;
break;
case 3:
style = GTK_MESSAGE_QUESTION;
button = GTK_BUTTONS_YES_NO;
break;
default:
style = GTK_MESSAGE_OTHER;
button = GTK_BUTTONS_OK_CANCEL;
}
/* Definindo a caixa de mensagem */
dialog = gtk_message_dialog_new (
_uigtk_window,
GTK_DIALOG_MODAL,
style,
button,
"\n%s",
(title != NULL ? title : text)
);
if (title != NULL) {
gtk_message_dialog_format_secondary_text(
GTK_MESSAGE_DIALOG(dialog), "\n%s", text
);
}
/* Obtendo o resultado */
result = gtk_dialog_run(GTK_DIALOG(dialog));
/* Destruindo janela */
gtk_widget_destroy (dialog);
/* Retornando o resultado */
switch (result) {
case GTK_RESPONSE_OK:
return 1;
case GTK_RESPONSE_YES:
return 1;
case GTK_RESPONSE_NO:
return -1;
}
return 0;
}
//interessante: g_print("%s", G_OBJECT_TYPE_NAME(uigtk_get_object("btn1")));