From bb3d700a6c96efb2728c2815062118e9aad326b6 Mon Sep 17 00:00:00 2001 From: tlatorre Date: Sun, 6 Nov 2022 02:29:21 -0600 Subject: add emoji --- vito.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 114 insertions(+), 41 deletions(-) diff --git a/vito.c b/vito.c index 9d2b344..760949d 100644 --- a/vito.c +++ b/vito.c @@ -3,6 +3,8 @@ #define LEN(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) +/* Returns the current time in seconds and milliseconds since the epoch. + * Mostly useful for calculating time intervals. */ static void aeGetTime(long *seconds, long *milliseconds) { struct timeval tv; @@ -12,13 +14,59 @@ static void aeGetTime(long *seconds, long *milliseconds) *milliseconds = tv.tv_usec/1000; } -GtkWidget *window; -GtkWidget *button; GtkWidget *text_widget; -GtkTextBuffer *text_buffer; GtkTextTag *tag; -char alphabet[] = "abcdefghijklmnopqrstuvwxyz_!?."; +#define LEFT_ARROW "\xe2\x86\x90" +#define CLEAR_SCREEN "\xe2\x8e\x9a" +#define DRINK "\xf0\x9f\x8d\xba" +#define FOOD "\xf0\x9f\x8d\xb2" +#define TIRED "\xf0\x9f\x98\xab" +#define HAPPY "\xf0\x9f\x98\x80" +#define LAUGHING "\xf0\x9f\x98\x84" +#define NEWLINE "\xe2\x86\xb5" + +const char *alphabet[] = { + DRINK, + FOOD, + HAPPY, + LAUGHING, + TIRED, + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + LEFT_ARROW, + CLEAR_SCREEN, + "_", + NEWLINE, + "!", + "?", + "." +}; + char buf[1000000]; /* The current alphabetical letter. */ @@ -37,29 +85,33 @@ long released_time_sec = 0; /* Time the mouse was released (milliseconds) */ long released_time_msec = 0; -static int pressed(GtkWidget *widget, gpointer data) +static int pressed(GtkWidget *widget, gpointer data) { aeGetTime(&pressed_time_sec,&pressed_time_msec); - g_print("mouse pressed\n"); return TRUE; } static void write_buf(void) { + GtkTextBuffer *text_buffer; GtkTextIter start, end; text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_widget)); - sprintf(buf+current_position,"%c",alphabet[current_letter % LEN(alphabet)]); + sprintf(buf+current_position,"%s",alphabet[current_letter % LEN(alphabet)]); - gtk_text_buffer_set_text (text_buffer, buf, -1); + gtk_text_buffer_set_text(text_buffer, buf, -1); - gtk_text_buffer_get_iter_at_offset (text_buffer, &start, strlen(buf)-1); - gtk_text_buffer_get_iter_at_offset (text_buffer, &end, strlen(buf)); - gtk_text_buffer_apply_tag (text_buffer, tag, &start, &end); + gtk_text_buffer_get_iter_at_offset(text_buffer, &start, g_utf8_strlen(buf,-1)-1); + gtk_text_buffer_get_iter_at_offset(text_buffer, &end, -1); + gtk_text_buffer_apply_tag(text_buffer, tag, &start, &end); } static int released(GtkWidget *widget, gpointer data) { + GtkTextBuffer *text_buffer; + GtkTextIter start, end; + const char *current_char; + aeGetTime(&released_time_sec,&released_time_msec); long long diff = (released_time_sec - pressed_time_sec)*1000 + (released_time_msec - pressed_time_msec); @@ -67,43 +119,64 @@ static int released(GtkWidget *widget, gpointer data) current_position = 0; current_letter = 0; } else if (diff > 500) { - if (alphabet[current_letter % LEN(alphabet)] == '_') + current_char = alphabet[current_letter % LEN(alphabet)]; + if (!strcmp(current_char,LEFT_ARROW)) { + if (current_position > 0) { + text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_widget)); + gtk_text_buffer_set_text(text_buffer, buf, -1); + + gtk_text_buffer_get_iter_at_offset(text_buffer, &start, 0); + gtk_text_buffer_get_iter_at_offset(text_buffer, &end, g_utf8_strlen(buf,-1)-2); + current_position = strlen(gtk_text_buffer_get_slice(text_buffer,&start,&end,TRUE)); + } + } else if (!strcmp(current_char,CLEAR_SCREEN)) { + current_position = 0; + current_letter = 0; + } else if (!strcmp(current_char,"_")) { sprintf(buf+current_position," "); - else - sprintf(buf+current_position,"%c",alphabet[current_letter % LEN(alphabet)]); - current_position += 1; + current_position += strlen(current_char); + } else if (!strcmp(current_char,NEWLINE)) { + sprintf(buf+current_position,"\n"); + current_position += 1; + } else { + sprintf(buf+current_position,"%s",current_char); + current_position += strlen(current_char); + } if (current_position > LEN(buf) - 1) { /* FIXME: better way to do this? */ current_position = 0; } - current_letter = 0; + /* Uncomment the next line to start over at the beginning of the + * alphabet after a new letter is entered. But, I think it's better + * to keep the current letter. The reason is that you might want to + * delete a whole word and so when you navigate to the backspace you + * just have to keep entering the same letter. */ + //current_letter = 0; } else { current_letter += 1; } write_buf(); - g_print("mouse released\n"); return TRUE; } -static void activate (GtkApplication *app, gpointer user_data) +static void activate(GtkApplication *app, gpointer user_data) { + GtkWidget *window; + GtkTextBuffer *text_buffer; GtkCssProvider *provider; GtkStyleContext *context; GtkGesture *gesture; - text_buffer = gtk_text_buffer_new(NULL); - gtk_text_buffer_set_text(text_buffer,"blah",4); - window = gtk_application_window_new(app); - gtk_window_set_title(GTK_WINDOW (window), "Window"); - gtk_window_set_default_size(GTK_WINDOW (window), 200, 200); + gtk_window_set_title(GTK_WINDOW(window), "Window"); + gtk_window_set_default_size(GTK_WINDOW(window), 200, 200); gesture = gtk_gesture_click_new(); - g_signal_connect(gesture, "pressed", G_CALLBACK (pressed), NULL); - g_signal_connect(gesture, "released", G_CALLBACK (released), NULL); - gtk_widget_add_controller(window, GTK_EVENT_CONTROLLER (gesture)); + g_signal_connect(gesture, "pressed", G_CALLBACK(pressed), NULL); + g_signal_connect(gesture, "released", G_CALLBACK(released), NULL); + gtk_widget_add_controller(window, GTK_EVENT_CONTROLLER(gesture)); text_widget = gtk_text_view_new(); gtk_text_view_set_editable((GtkTextView *) text_widget, FALSE); @@ -114,26 +187,26 @@ static void activate (GtkApplication *app, gpointer user_data) text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_widget)); /* Change default font and color throughout the widget */ - provider = gtk_css_provider_new (); - gtk_css_provider_load_from_data (provider, - "textview {" - " font: 144pt monospace;" - " color: black;" - "}", - -1); - context = gtk_widget_get_style_context (text_widget); - gtk_style_context_add_provider(context, GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + provider = gtk_css_provider_new(); + gtk_css_provider_load_from_data(provider, + "textview {" + " font: 144pt monospace;" + " color: black;" + "}", + -1); + context = gtk_widget_get_style_context(text_widget); + gtk_style_context_add_provider(context, GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); /* Use a tag to change the color for just one part of the widget */ tag = gtk_text_buffer_create_tag(text_buffer, "red_foreground", "foreground", "red", NULL); buf[0] = 'a'; buf[1] = '\0'; write_buf(); - gtk_window_set_child(GTK_WINDOW (window), text_widget); + gtk_window_set_child(GTK_WINDOW(window), text_widget); gtk_window_fullscreen(GTK_WINDOW(window)); - gtk_window_present(GTK_WINDOW (window)); + gtk_window_present(GTK_WINDOW(window)); } int main(int argc, char **argv) @@ -141,10 +214,10 @@ int main(int argc, char **argv) GtkApplication *app; int status; - app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE); - g_signal_connect (app, "activate", G_CALLBACK (activate), NULL); - status = g_application_run (G_APPLICATION (app), argc, argv); - g_object_unref (app); + app = gtk_application_new("org.gtk.example", G_APPLICATION_FLAGS_NONE); + g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); + status = g_application_run(G_APPLICATION(app), argc, argv); + g_object_unref(app); return status; } -- cgit