Last active
March 17, 2021 02:03
-
-
Save Miqueas/c52a7f6684036030572a66d1f58ba574 to your computer and use it in GitHub Desktop.
[C + Gtk 3] Generic password window
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <gtk/gtk.h> | |
GtkWidget *user, *pass, *confirm, *clear, *check; | |
GRegex *patt; | |
GtkWidget* build_grid() { | |
GtkWidget *label; | |
GtkWidget *grid = g_object_new( | |
GTK_TYPE_GRID, | |
"visible", TRUE, | |
"column-spacing", 6, | |
"row-spacing", 6, | |
"halign", GTK_ALIGN_CENTER, | |
"valign", GTK_ALIGN_CENTER, | |
NULL | |
); | |
user = g_object_new(GTK_TYPE_ENTRY, "visible", TRUE, NULL); | |
pass = g_object_new(GTK_TYPE_ENTRY, "visible", TRUE, "visibility", FALSE, NULL); | |
confirm = g_object_new(GTK_TYPE_ENTRY, "visible", TRUE, "visibility", FALSE, NULL); | |
gtk_entry_set_input_purpose(GTK_ENTRY(pass), GTK_INPUT_PURPOSE_PASSWORD); | |
gtk_entry_set_input_purpose(GTK_ENTRY(confirm), GTK_INPUT_PURPOSE_PASSWORD); | |
label = g_object_new( | |
GTK_TYPE_LABEL, | |
"label", "Usuario", | |
"visible", TRUE, | |
"xalign", 1.0, | |
NULL | |
); | |
gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 1, 1); | |
gtk_grid_attach(GTK_GRID(grid), user, 1, 0, 1, 1); | |
label = g_object_new( | |
GTK_TYPE_LABEL, | |
"label", "Contraseña", | |
"visible", TRUE, | |
"xalign", 1.0, | |
NULL | |
); | |
gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 1, 1); | |
gtk_grid_attach(GTK_GRID(grid), pass, 1, 1, 1, 1); | |
label = g_object_new( | |
GTK_TYPE_LABEL, | |
"label", "Repita la contraseña", | |
"visible", TRUE, | |
"xalign", 1.0, | |
NULL | |
); | |
gtk_grid_attach(GTK_GRID(grid), label, 0, 2, 1, 1); | |
gtk_grid_attach(GTK_GRID(grid), confirm, 1, 2, 1, 1); | |
check = g_object_new( | |
GTK_TYPE_CHECK_BUTTON, | |
"label", "Mostrar contraseña", | |
"visible", TRUE, | |
NULL | |
); | |
clear = g_object_new( | |
GTK_TYPE_BUTTON, | |
"label", "Limpiar", | |
"visible", TRUE, | |
"halign", GTK_ALIGN_END, | |
NULL | |
); | |
gtk_grid_attach(GTK_GRID(grid), check, 1, 3, 1, 1); | |
gtk_grid_attach(GTK_GRID(grid), clear, 1, 4, 1, 1); | |
return grid; | |
} | |
gboolean user_input(GtkWidget *self, GdkEvent *ev, gpointer data) { | |
const char *val = gtk_entry_get_text(GTK_ENTRY(self)); | |
if ( g_regex_match(patt, val, 0, NULL) ) { | |
gtk_entry_set_icon_from_icon_name( | |
GTK_ENTRY(self), | |
GTK_ENTRY_ICON_SECONDARY, "process-completed-symbolic" | |
); | |
} else { | |
gtk_entry_set_icon_from_icon_name( | |
GTK_ENTRY(self), | |
GTK_ENTRY_ICON_SECONDARY, "process-error-symbolic" | |
); | |
} | |
return FALSE; | |
} | |
gboolean confirm_input(GtkWidget *self, GdkEvent *ev, gpointer data) { | |
const char *original = gtk_entry_get_text(GTK_ENTRY(pass)); | |
const char *confirmation = gtk_entry_get_text(GTK_ENTRY(self)); | |
if ( g_str_equal(confirmation, original) ) { | |
gtk_entry_set_icon_from_icon_name( | |
GTK_ENTRY(self), | |
GTK_ENTRY_ICON_SECONDARY, "process-completed-symbolic" | |
); | |
} else { | |
gtk_entry_set_icon_from_icon_name( | |
GTK_ENTRY(self), | |
GTK_ENTRY_ICON_SECONDARY, "process-error-symbolic" | |
); | |
} | |
return FALSE; | |
} | |
void check_toggled(GtkWidget *self, gpointer data) { | |
gboolean active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(self)); | |
if (active) { | |
gtk_entry_set_visibility(GTK_ENTRY(pass), TRUE); | |
gtk_entry_set_visibility(GTK_ENTRY(confirm), TRUE); | |
} else { | |
gtk_entry_set_visibility(GTK_ENTRY(pass), FALSE); | |
gtk_entry_set_visibility(GTK_ENTRY(confirm), FALSE); | |
} | |
} | |
void clear_clicked(GtkWidget *self, gpointer data) { | |
gtk_entry_set_text(GTK_ENTRY(user), ""); | |
gtk_entry_set_text(GTK_ENTRY(pass), ""); | |
gtk_entry_set_text(GTK_ENTRY(confirm), ""); | |
} | |
void app_activate(GtkApplication *self, gpointer data) { | |
GtkWidget *win = g_object_new( | |
GTK_TYPE_APPLICATION_WINDOW, | |
"application", self, | |
"border-width", 10, | |
NULL | |
); | |
gtk_container_add(GTK_CONTAINER(win), build_grid()); | |
patt = g_regex_new("^([a-z]+[a-z0-9]*)$", 0, 0, NULL); | |
g_signal_connect(user, "notify::text", G_CALLBACK(user_input), NULL); | |
g_signal_connect(confirm, "notify::text", G_CALLBACK(confirm_input), NULL); | |
g_signal_connect(check, "toggled", G_CALLBACK(check_toggled), NULL); | |
g_signal_connect(clear, "clicked", G_CALLBACK(clear_clicked), NULL); | |
gtk_window_present(GTK_WINDOW(win)); | |
} | |
int main(int argc, char **argv) { | |
GtkApplication *app = gtk_application_new("org.example.gtk.password", G_APPLICATION_FLAGS_NONE); | |
g_signal_connect(app, "activate", G_CALLBACK(app_activate), NULL); | |
int res = g_application_run(G_APPLICATION(app), argc, argv); | |
g_object_unref(app); | |
g_clear_pointer(&patt, g_regex_unref); | |
return res; | |
} |
Ah, y casi olvidaba: ese GRegex
no se va a liberar solo
g_clear_pointer (&patt, g_regex_unref);
Lo haces antes del return res;
@nahuelwexd corregido! Gracias por comentar :P
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Todos los
GtkWidget
s heredan deGInitiallyUnowned
, evitandote la necesidad de desreferenciarlos manualmente si los empacas dentro de otroGtkWidget
, por lo que incluso podrías cambiar tu código a algo como esto:Nota: Vala tiene soporte de sintaxis para
GRegex
😉Usa la señal
::notify
en lugar de::key-release-event
para obtener un evento cada vez que la propiedad:text
cambia, en lugar de obtener uno cada vez que el usuario suelta una teclaEs preferible trabajar con
GtkWidget
en lugar de clases más específicasEs más idiomático que devuelvas un
GtkWidget*
en lugar de unGtkGrid*
Mira también de informar a los OSK de que esas entradas son para contraseñas mediante la propiedad
:input-purpose