X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=libchimara%2Fhyperlink.c;h=7d4be655bfd894cb3a86106687cdbbf95396de23;hb=13b21e2a9ba53c7109ae0bbfd774f16f0c9d4413;hp=6d0d263b099c028a633e0b1be61295f8f08eca1f;hpb=42d2c2e53f65402039e0b1c6e48e258fb417bb71;p=rodin%2Fchimara.git diff --git a/libchimara/hyperlink.c b/libchimara/hyperlink.c index 6d0d263..7d4be65 100644 --- a/libchimara/hyperlink.c +++ b/libchimara/hyperlink.c @@ -24,7 +24,7 @@ glk_set_hyperlink(glui32 linkval) } /** - * glk_set_hyperlink: + * glk_set_hyperlink_stream: * @str: The stream to set the hyperlink mode on. * @linkval: Set to nonzero to initiate hyperlink mode. Set to zero to disengage. * @@ -43,7 +43,57 @@ glk_set_hyperlink_stream(strid_t str, glui32 linkval) g_return_if_fail(str->window != NULL); g_return_if_fail(str->window->type == wintype_TextBuffer); - str->hyperlink_mode = (linkval != 0); + flush_window_buffer(str->window); + + if(linkval == 0) { + /* Turn off hyperlink mode */ + str->hyperlink_mode = FALSE; + str->window->current_hyperlink = NULL; + return; + } + + /* Check whether a tag with the needed value already exists */ + hyperlink_t *new_hyperlink = g_hash_table_lookup(str->window->hyperlinks, &linkval); + if(new_hyperlink == NULL) { + /* Create a new hyperlink with the requested value */ + new_hyperlink = g_new0(struct hyperlink, 1); + new_hyperlink->value = linkval; + new_hyperlink->tag = gtk_text_tag_new(NULL); + new_hyperlink->event_handler = g_signal_connect( new_hyperlink->tag, "event", G_CALLBACK(on_hyperlink_clicked), new_hyperlink ); + g_signal_handler_block(new_hyperlink->tag, new_hyperlink->event_handler); + new_hyperlink->window = str->window; + + /* Add the new tag to the tag table of the textbuffer */ + GtkTextBuffer *textbuffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(str->window->widget) ); + GtkTextTagTable *tags = gtk_text_buffer_get_tag_table(textbuffer); + gtk_text_tag_table_add(tags, new_hyperlink->tag); + + printf("inserting link %d\n", linkval); + + gint *linkval_pointer = g_new0(gint, 1); + *linkval_pointer = linkval; + g_hash_table_insert(str->window->hyperlinks, linkval_pointer, new_hyperlink); + } + + str->hyperlink_mode = TRUE; + str->window->current_hyperlink = new_hyperlink; +} + +/* Internal function used to iterate over all the hyperlinks, unblocking the event handler */ +void +hyperlink_unblock_event_handler(gpointer key, gpointer value, gpointer user_data) +{ + hyperlink_t *link = (hyperlink_t *) value; + g_signal_handler_unblock(link->tag, link->event_handler); + printf("unblocking link %d\n", link->value); +} + +/* Internal function used to iterate over all the hyperlinks, blocking the event handler */ +void +hyperlink_block_event_handler(gpointer key, gpointer value, gpointer user_data) +{ + hyperlink_t *link = (hyperlink_t *) value; + g_signal_handler_block(link->tag, link->event_handler); } void @@ -51,10 +101,10 @@ glk_request_hyperlink_event(winid_t win) { VALID_WINDOW(win, return); g_return_if_fail(win != NULL); - g_return_if_fail(win->mouse_click_handler != 0); g_return_if_fail(win->type != wintype_TextBuffer || win->type != wintype_TextGrid); - g_signal_handler_unblock( G_OBJECT(win->widget), win->mouse_click_handler ); + g_hash_table_foreach(win->hyperlinks, hyperlink_unblock_event_handler, NULL); + } void @@ -62,19 +112,20 @@ glk_cancel_hyperlink_event(winid_t win) { VALID_WINDOW(win, return); g_return_if_fail(win != NULL); - g_return_if_fail(win->mouse_click_handler != 0); g_return_if_fail(win->type != wintype_TextBuffer || win->type != wintype_TextGrid); - - g_signal_handler_block( G_OBJECT(win->widget), win->mouse_click_handler ); + + g_hash_table_foreach(win->hyperlinks, hyperlink_block_event_handler, NULL); } -/* Internal function: General callback for signal button-release-event on a - * text buffer or text grid window. Used for detecting clicks on hyperlinks. - * Blocked when not in use. - */ gboolean -on_window_button_release_event(GtkWidget *widget, GdkEventButton *event, winid_t win) +on_hyperlink_clicked(GtkTextTag *tag, GObject *object, GdkEvent *event, GtkTextIter *iter, hyperlink_t *link) { - printf("Click on (%f,%f)\n", event->x, event->y); - return TRUE; + ChimaraGlk *glk = CHIMARA_GLK(gtk_widget_get_ancestor(link->window->widget, CHIMARA_TYPE_GLK)); + g_assert(glk); + + if(event->type == GDK_BUTTON_PRESS) { + event_throw(glk, evtype_Hyperlink, link->window, link->value, 0); + } + + return FALSE; }