diff options
author | tlatorre <tlatorre@uchicago.edu> | 2022-11-12 13:47:35 -0800 |
---|---|---|
committer | tlatorre <tlatorre@uchicago.edu> | 2022-11-12 13:47:35 -0800 |
commit | e5dfc1285f4be8559a6f1f42e52facee72808a99 (patch) | |
tree | 372d43fea9457d4e28463e78b16e74d0d941fe19 /vito.c | |
parent | e7766d22748115410567d666906162c9bdb91548 (diff) | |
download | moji-e5dfc1285f4be8559a6f1f42e52facee72808a99.tar.gz moji-e5dfc1285f4be8559a6f1f42e52facee72808a99.tar.bz2 moji-e5dfc1285f4be8559a6f1f42e52facee72808a99.zip |
rename project to moji
Diffstat (limited to 'vito.c')
-rw-r--r-- | vito.c | 337 |
1 files changed, 0 insertions, 337 deletions
@@ -1,337 +0,0 @@ -#include <gtk/gtk.h> -#include <sys/time.h> -#include <stdlib.h> -#include <gdk/gdkkeysyms.h> -#include <gdk/gdkenums.h> - -/* Time in milliseconds it takes to write a character, i.e. if you hold down - * the mouse button for this many ms it will write the character and move on to - * the next character (or emoji). - * - * Initially had this set to 500 ms (half a second), but that was a bit short, - * so I've updated it to one second. */ -#define CLICK_TIME 1000 - -#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; - - gettimeofday(&tv, NULL); - *seconds = tv.tv_sec; - *milliseconds = tv.tv_usec/1000; -} - -GtkWidget *text_widget; -GtkTextTag *tag; - -/* List of emojis. */ -#define STOP "\xf0\x9f\x9b\x91" -#define THANK_YOU "\xf0\x9f\x99\x8f" -#define UNAMUSED "\xf0\x9f\x98\x92" -#define SLEEPING "\xf0\x9f\x98\xb4" -#define BED "\xf0\x9f\x9b\x8f" -#define CHAIR "\xf0\x9f\xaa\x91" -#define NURSE "\xf0\x9f\x91\xa9\xe2\x80\x8d\xe2\x9a\x95\xef\xb8\x8f" -#define ROLLING_EYES "\xf0\x9f\x99\x84" -#define OVERHEATED "\xf0\x9f\xa5\xb5" -#define FREEZING "\xf0\x9f\xa5\xb6" -#define NAUSEOUS "\xf0\x9f\xa4\xa2" -#define THINKING "\xf0\x9f\xa4\x94" -#define THUMBS_UP "\xf0\x9f\x91\x8d" -#define THUMBS_DOWN "\xf0\x9f\x91\x8e" -#define LEFT_ARROW "\xe2\x86\x90" -#define CLEAR_SCREEN "\xe2\x8e\x9a" -#define SOUND "\xf0\x9f\x94\x8a" -#define DROPLET "\xf0\x9f\x92\xa7" -#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" - -typedef struct chars -{ - const char **characters; - int len; -} chars; - -const char *emoji_array[] = { - THINKING, - THUMBS_UP, - THUMBS_DOWN, - STOP, - HAPPY, - LAUGHING, - TIRED, - FREEZING, - OVERHEATED, - NAUSEOUS, - ROLLING_EYES, - SLEEPING, - UNAMUSED, - THANK_YOU, - NURSE, - DROPLET, - CHAIR, - BED, - //FOOD, - LEFT_ARROW, - CLEAR_SCREEN, -}; - -const char *alphabet_array[] = { - "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, - SOUND, - "_", - NEWLINE, - "!", - "?", - "." -}; - -chars emoji = { emoji_array, LEN(emoji_array)}; -chars alphabet = {alphabet_array, LEN(alphabet_array)}; -chars *current_chars = &emoji; - -char buf[100000]; - -/* The current alphabetical letter. */ -int current_letter = 0; -/* The current position in the buffer. - * - * FIXME: What to do if we run out of buffer space?. */ -int current_position = 0; - -/* Time the mouse was clicked (seconds) */ -long pressed_time_sec = 0; -/* Time the mouse was clicked (milliseconds) */ -long pressed_time_msec = 0; -/* Time the mouse was released (seconds) */ -long released_time_sec = 0; -/* Time the mouse was released (milliseconds) */ -long released_time_msec = 0; - -void backspace(void) -{ - GtkTextBuffer *text_buffer; - GtkTextIter start, end; - - 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)); - } -} - -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,"%s",current_chars->characters[current_letter % current_chars->len]); - - gtk_text_buffer_set_text(text_buffer, buf, -1); - - 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 right_click_pressed(GtkWidget *widget, gpointer data) -{ - backspace(); - write_buf(); - return TRUE; -} - -static int right_click_released(GtkWidget *widget, gpointer data) -{ - return TRUE; -} - -static int pressed(GtkWidget *widget, gpointer data) -{ - aeGetTime(&pressed_time_sec,&pressed_time_msec); - return TRUE; -} - -static int released(GtkWidget *widget, gpointer data) -{ - 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); - - if (diff > 10000) { - current_position = 0; - current_letter = 0; - } else if (diff > CLICK_TIME) { - current_char = current_chars->characters[current_letter % current_chars->len]; - if (!strcmp(current_char,LEFT_ARROW)) { - backspace(); - } else if (!strcmp(current_char,CLEAR_SCREEN)) { - current_position = 0; - current_letter = 0; - } else if (!strcmp(current_char,SOUND)) { - char cmd[1000000]; - buf[current_position] = '\0'; - sprintf(cmd, "gtts-cli \"%s\" --output vito.mp3", buf); - if (!system(cmd)) { - system("mpg123 vito.mp3"); - system("rm vito.mp3"); - } - } else if (!strcmp(current_char,"_")) { - sprintf(buf+current_position," "); - 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; - } - /* 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(); - - return TRUE; -} - -gboolean on_key_press(GtkEventControllerKey *, guint keyval, guint keycode, GdkModifierType mod, gpointer user_data) -{ - switch (keyval) - { - case GDK_KEY_space: - if (current_chars == &emoji) - current_chars = &alphabet; - else if (current_chars == &alphabet) - current_chars = &emoji; - current_letter = 0; - write_buf(); - break; - case GDK_KEY_BackSpace: - backspace(); - write_buf(); - break; - default: - return FALSE; - } - return FALSE; -} - -static void activate(GtkApplication *app, gpointer user_data) -{ - GtkWidget *window; - GtkTextBuffer *text_buffer; - GtkCssProvider *provider; - GtkStyleContext *context; - GtkGesture *gesture, *right_click_gesture; - GtkEventController *event_controller; - - window = gtk_application_window_new(app); - gtk_window_set_title(GTK_WINDOW(window), "Window"); - gtk_window_set_default_size(GTK_WINDOW(window), 200, 200); - - event_controller = gtk_event_controller_key_new(); - g_signal_connect(event_controller, "key-pressed", G_CALLBACK(on_key_press), NULL); - gtk_widget_add_controller(window, event_controller); - - right_click_gesture = gtk_gesture_click_new(); - gtk_gesture_single_set_button(GTK_GESTURE_SINGLE (right_click_gesture), 3); - g_signal_connect(right_click_gesture, "pressed", G_CALLBACK(right_click_pressed), NULL); - g_signal_connect(right_click_gesture, "released", G_CALLBACK(right_click_released), NULL); - gtk_widget_add_controller(window, GTK_EVENT_CONTROLLER(right_click_gesture)); - - 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)); - - text_widget = gtk_text_view_new(); - gtk_text_view_set_editable((GtkTextView *) text_widget, FALSE); - gtk_text_view_set_cursor_visible((GtkTextView *) text_widget, TRUE); - gtk_text_view_set_wrap_mode((GtkTextView *) text_widget, GTK_WRAP_CHAR); - gtk_widget_set_can_focus(text_widget, FALSE); - gtk_widget_set_can_target(text_widget, FALSE); - 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); - - /* 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); - write_buf(); - gtk_window_set_child(GTK_WINDOW(window), text_widget); - - gtk_window_fullscreen(GTK_WINDOW(window)); - - gtk_window_present(GTK_WINDOW(window)); -} - -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); - - return status; -} |