void gglk_text_update_scrollmark(GglkText *tb) { GtkTextIter olditer, pastiter, iter; gtk_text_buffer_get_iter_at_mark(tb->buffer, &olditer, tb->scrollmark); gtk_text_buffer_get_end_iter(tb->buffer, &iter); gtk_text_buffer_move_mark(tb->buffer, tb->scrollmark, &iter); gtk_text_view_move_mark_onscreen(GTK_TEXT_VIEW(tb), tb->scrollmark); gtk_text_buffer_get_iter_at_mark(tb->buffer, &pastiter, tb->scrollmark); iter = pastiter; gtk_text_view_backward_display_line(GTK_TEXT_VIEW(tb), &iter); /* If we're trying to scroll down, but the backward_display_line made us fail, undo that. */ if(gtk_text_iter_compare(&pastiter, &olditer) >= 0 && gtk_text_iter_compare(&iter, &olditer) <= 0) { iter = pastiter; gtk_text_view_forward_display_line(GTK_TEXT_VIEW(tb), &iter); } gtk_text_buffer_move_mark(tb->buffer, tb->scrollmark, &iter); }
/******************************************************************************* * Advance the cursor n positions on the tutor text view */ gint cursor_advance (gint n) { gint i; gboolean cursor_out_screen; GtkWidget *wg; GtkTextBuffer *buf; GtkTextIter new_start; GtkTextIter old_start; GtkTextIter end; GtkTextMark *mark; wg = get_wg ("text_tutor"); buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (wg)); /* Get current position for the iter old_start */ gtk_text_buffer_get_iter_at_mark (buf, &new_start, gtk_text_buffer_get_insert (buf)); old_start = new_start; /* Get new position for the iter new_start */ if (n > 0) for (i = 0; i < n && gtk_text_iter_forward_cursor_position (&new_start); i++); else for (i = 0; i > n && gtk_text_iter_backward_cursor_position (&new_start); i--); /* Move cursor blinking */ end = new_start; gtk_text_iter_forward_char (&end); gtk_text_buffer_apply_tag_by_name (buf, "cursor_blink", &new_start, &end); end = old_start; gtk_text_iter_forward_char (&end); gtk_text_buffer_remove_tag_by_name (buf, "cursor_blink", &old_start, &end); /* Move cursor */ gtk_text_buffer_place_cursor (buf, &new_start); /* Check need for auto-scrolling */ if (i == n) { end = new_start; gtk_text_iter_forward_line (&end); mark = gtk_text_buffer_create_mark (buf, "aux", &end, FALSE); cursor_out_screen = gtk_text_view_move_mark_onscreen (GTK_TEXT_VIEW (wg), mark); if (cursor_out_screen) { gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (wg), gtk_text_buffer_get_insert (buf), 0.0, TRUE, 0.5, 0.12); } } return (i); }
gboolean gglk_text_can_scroll(GglkText *tb) { GtkTextIter enditer; /* Move the endmark to the end of the buffer. If it must be moved to get back onscreen, then the window might by scrollable. */ gtk_text_buffer_get_end_iter(tb->buffer, &enditer); gtk_text_buffer_move_mark(tb->buffer, tb->endmark, &enditer); if(gtk_text_view_move_mark_onscreen(GTK_TEXT_VIEW(tb), tb->endmark)) return TRUE; return FALSE; }
static VALUE textview_move_mark_onscreen(VALUE self, VALUE mark) { return CBOOL2RVAL(gtk_text_view_move_mark_onscreen(_SELF(self), RVAL2MARK(mark))); }
static gboolean cb_key_press_event(GtkWidget *view, GdkEventKey *event) { GtkTextBuffer *buffer; GtkTextMark *mark; GtkTextIter iter; GdkRectangle prev_rect; if (check_preedit(view)) return FALSE; buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view)); mark = gtk_text_buffer_get_insert(buffer); gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); gtk_text_view_get_iter_location(GTK_TEXT_VIEW(view), &iter, &prev_rect); keyval = 0; //g_print("key-press-event: 0x%X\n", event->keyval); switch (event->keyval) { case GDK_Up: // Try [Shift]+[Down]. it works bad. case GDK_Down: if (gtk_text_view_move_mark_onscreen(GTK_TEXT_VIEW(view), mark)) { GdkRectangle iter_rect; gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); gtk_text_view_get_iter_location(GTK_TEXT_VIEW(view), &iter, &iter_rect); if (iter_rect.y < prev_rect.y) { gtk_text_view_get_line_at_y(GTK_TEXT_VIEW(view), &iter, iter_rect.y - iter_rect.height, NULL); gtk_text_buffer_move_mark(buffer, mark, &iter); } if (!(event->state & GDK_SHIFT_MASK)) { gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); gtk_text_buffer_place_cursor(buffer, &iter); } return TRUE; } break; case GDK_Page_Up: case GDK_Page_Down: if (gtk_text_view_move_mark_onscreen(GTK_TEXT_VIEW(view), mark)) { GdkRectangle visible_rect, iter_rect; gint pos = 0; gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(view), &visible_rect); gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); gtk_text_view_get_iter_location(GTK_TEXT_VIEW(view), &iter, &iter_rect); if (iter_rect.y < prev_rect.y) pos = 1; if (event->keyval == GDK_Page_Up) gtk_text_view_get_line_at_y(GTK_TEXT_VIEW(view), &iter, iter_rect.y - visible_rect.height + iter_rect.height, NULL); else gtk_text_view_get_line_at_y(GTK_TEXT_VIEW(view), &iter, iter_rect.y + visible_rect.height - iter_rect.height, NULL); gtk_text_buffer_move_mark(buffer, mark, &iter); gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(view), mark, 0, TRUE, 0, pos); if (!(event->state & GDK_SHIFT_MASK)) { gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); gtk_text_buffer_place_cursor(GTK_TEXT_VIEW(view)->buffer, &iter); } return TRUE; } break; case GDK_Return: if (indent_get_state()) { indent_real(view); return TRUE; } break; case GDK_Tab: if (event->state & GDK_CONTROL_MASK) { indent_toggle_tab_width(view); return TRUE; } case GDK_ISO_Left_Tab: if (event->state & GDK_SHIFT_MASK) indent_multi_line_unindent(GTK_TEXT_VIEW(view)->buffer); else if (!check_selection_bound(GTK_TEXT_VIEW(view)->buffer)) break; else indent_multi_line_indent(GTK_TEXT_VIEW(view)->buffer); return TRUE; } keyval = event->keyval; if ((event->state & GDK_CONTROL_MASK) || (event->keyval == GDK_Control_L) || (event->keyval == GDK_Control_R)) { keyval = keyval + 0x10000; //g_print("=================================================\n"); } return FALSE; }