#include #include #define LEN(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) static void aeGetTime(long *seconds, long *milliseconds) { struct timeval tv; gettimeofday(&tv, NULL); *seconds = tv.tv_sec; *milliseconds = tv.tv_usec/1000; } GtkWidget *window; GtkWidget *button; GtkWidget *text_widget; GtkTextBuffer *text_buffer; GtkTextTag *tag; char alphabet[] = "abcdefghijklmnopqrstuvwxyz_!?."; char buf[1000000]; /* 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; 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) { 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)]); 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); } static int released(GtkWidget *widget, gpointer data) { 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 > 500) { if (alphabet[current_letter % LEN(alphabet)] == '_') sprintf(buf+current_position," "); else sprintf(buf+current_position,"%c",alphabet[current_letter % LEN(alphabet)]); current_position += 1; if (current_position > LEN(buf) - 1) { /* FIXME: better way to do this? */ current_position = 0; } current_letter = 0; } else { current_letter += 1; } write_buf(); g_print("mouse released\n"); return TRUE; } static void activate (GtkApplication *app, gpointer user_data) { 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); 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); buf[0] = 'a'; buf[1] = '\0'; 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; }