static std::vector<LineInfo> getLinesInfo(GtkTextView* textView, int height) { std::vector<LineInfo> linesInfo; int y1 = 0; int y2 = height; gtk_text_view_window_to_buffer_coords(textView, GTK_TEXT_WINDOW_LEFT, 0, y1, NULL, &y1); gtk_text_view_window_to_buffer_coords(textView, GTK_TEXT_WINDOW_LEFT, 0, y2, NULL, &y2); GtkTextIter iter; gtk_text_view_get_line_at_y(textView, &iter, y1, NULL); while(!gtk_text_iter_is_end(&iter)) { int y, height; gtk_text_view_get_line_yrange(textView, &iter, &y, &height); int line = gtk_text_iter_get_line(&iter); linesInfo.push_back(LineInfo(line+1, y)); if((y + height) >= y2) { break; } gtk_text_iter_forward_line(&iter); } if(linesInfo.size() == 0) { linesInfo.push_back(LineInfo(1, 1)); } return linesInfo; }
static void timestamp_display(PurpleConversation *conv, time_t then, time_t now) { PidginConversation *gtk_conv = PIDGIN_CONVERSATION(conv); GtkWidget *imhtml = gtk_conv->imhtml; GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(imhtml)); GtkTextIter iter; const char *mdate; int y, height; GdkRectangle rect; /* display timestamp */ mdate = purple_utf8_strftime(then == 0 ? "%H:%M" : "\n%H:%M", localtime(&now)); gtk_text_buffer_get_end_iter(buffer, &iter); if (gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(buffer), "TIMESTAMP") == NULL) gtk_text_buffer_create_tag(buffer, "TIMESTAMP", "foreground", "#888888", "justification", GTK_JUSTIFY_CENTER, "weight", PANGO_WEIGHT_BOLD, NULL); gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, mdate, strlen(mdate), "TIMESTAMP", NULL); /* scroll view if necessary */ gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect); gtk_text_view_get_line_yrange( GTK_TEXT_VIEW(imhtml), &iter, &y, &height); if (((y + height) - (rect.y + rect.height)) > height && gtk_text_buffer_get_char_count(buffer)) { gboolean smooth = purple_prefs_get_bool( PIDGIN_PREFS_ROOT "/conversations/use_smooth_scrolling"); gtk_imhtml_scroll_to_end(GTK_IMHTML(imhtml), smooth); } }
static void get_renderer_rect (GtkSourceGutter *gutter, Renderer *renderer, GtkTextIter *iter, gint line, GdkRectangle *rectangle, gint start) { gint y; gint ypad; rectangle->x = start; gtk_text_view_get_line_yrange (GTK_TEXT_VIEW (gutter->priv->view), iter, &y, &rectangle->height); rectangle->width = gtk_source_gutter_renderer_get_size (renderer->renderer); gtk_text_view_buffer_to_window_coords (GTK_TEXT_VIEW (gutter->priv->view), gutter->priv->window_type, 0, y, NULL, &rectangle->y); gtk_source_gutter_renderer_get_padding (renderer->renderer, NULL, &ypad); rectangle->y += ypad; rectangle->height -= 2 * ypad; }
static VALUE textview_get_line_yrange(VALUE self, VALUE iter) { int y, height; gtk_text_view_get_line_yrange(_SELF(self), RVAL2ITR(iter), &y, &height); return rb_ary_new3(2, INT2NUM(y), INT2NUM(height)); }
void src_view___::scroll2__(GtkTextIter* ti) { gtk_text_buffer_place_cursor(buf2__(), ti); GtkTextIter i1,i2; gtk_text_buffer_get_selection_bounds (buf2__(), &i1,&i2); GdkRectangle rect; gtk_text_view_get_visible_rect (handle2__(), &rect); int y = -1; int height = -1; gtk_text_view_get_line_yrange (handle2__(), &i1, &y, &height); if (y < rect.y + rect.height + 16) gtk_text_view_scroll_to_mark (handle2__(), gtk_text_buffer_get_insert(buf2__()), 0, false, 0, 0); }
CAMLprim value ml_gtk_text_view_get_line_yrange (value tv, value ti) { CAMLparam2(tv,ti); CAMLlocal1(res); int y,h; gtk_text_view_get_line_yrange(GtkTextView_val(tv), GtkTextIter_val(ti), &y,&h); res = alloc_tuple(2); Store_field(res,0,Val_int(y)); Store_field(res,1,Val_int(h)); CAMLreturn(res); }
static void get_lines (GtkTextView *text_view, gint y1, gint y2, GArray *buffer_coords, GArray *numbers, gint *countp) { GtkTextIter iter; gint count; gint size; gint last_line_num; g_array_set_size (buffer_coords, 0); g_array_set_size (numbers, 0); /* Get iter at first y */ gtk_text_view_get_line_at_y (text_view, &iter, y1, NULL); /* For each iter, get its location and add it to the arrays. * Stop when we pass y2 */ count = 0; size = 0; while (!gtk_text_iter_is_end (&iter)) { gint y, height; gtk_text_view_get_line_yrange (text_view, &iter, &y, &height); g_array_append_val (buffer_coords, y); last_line_num = gtk_text_iter_get_line (&iter); g_array_append_val (numbers, last_line_num); ++count; if ((y + height) >= y2) break; gtk_text_iter_forward_line (&iter); } if (gtk_text_iter_is_end (&iter)) { gint y, height; gint line_num; gtk_text_view_get_line_yrange (text_view, &iter, &y, &height); line_num = gtk_text_iter_get_line (&iter); if (line_num != last_line_num) { g_array_append_val (buffer_coords, y); g_array_append_val (numbers, line_num); ++count; } } *countp = count; }
/* This function is taken and adapted from gtk+/tests/testtext.c */ static LinesInfo * get_lines_info (GtkTextView *text_view, gint first_y_buffer_coord, gint last_y_buffer_coord) { LinesInfo *info; GtkTextIter iter; gint last_line_num = -1; info = lines_info_new (); /* Get iter at first y */ gtk_text_view_get_line_at_y (text_view, &iter, first_y_buffer_coord, NULL); info->start = iter; /* For each iter, get its location and add it to the arrays. * Stop when we pass last_y_buffer_coord. */ while (!gtk_text_iter_is_end (&iter)) { gint y; gint height; gint line_num; gtk_text_view_get_line_yrange (text_view, &iter, &y, &height); g_array_append_val (info->buffer_coords, y); g_array_append_val (info->line_heights, height); info->total_height += height; line_num = gtk_text_iter_get_line (&iter); g_array_append_val (info->line_numbers, line_num); last_line_num = line_num; info->lines_count++; if (last_y_buffer_coord <= (y + height)) { break; } gtk_text_iter_forward_line (&iter); } if (gtk_text_iter_is_end (&iter)) { gint y; gint height; gint line_num; gtk_text_view_get_line_yrange (text_view, &iter, &y, &height); line_num = gtk_text_iter_get_line (&iter); if (line_num != last_line_num) { g_array_append_val (info->buffer_coords, y); g_array_append_val (info->line_heights, height); info->total_height += height; g_array_append_val (info->line_numbers, line_num); info->lines_count++; } } if (info->lines_count == 0) { gint y = 0; gint n = 0; gint height; info->lines_count = 1; g_array_append_val (info->buffer_coords, y); g_array_append_val (info->line_numbers, n); gtk_text_view_get_line_yrange (text_view, &iter, &y, &height); g_array_append_val (info->line_heights, height); info->total_height += height; } info->end = iter; return info; }
// append a string to the WarlockView // string needs to be valid UTF-8, and gets mangled, sorry. static void view_append (WarlockView *view, WString *string) { GtkTextIter iter; GtkTextBuffer *buffer; GtkTextIter start, end; GList *list_current; GdkRectangle rect; int y, height; gboolean scroll; g_assert (view != NULL); buffer = view->text_buffer; list_current = NULL; // Get the end of the buffer gtk_text_buffer_get_end_iter (buffer, &iter); // test if we should scroll gtk_text_view_get_visible_rect (GTK_TEXT_VIEW (view->text_view), &rect); gtk_text_view_get_line_yrange (GTK_TEXT_VIEW(view->text_view), &iter, &y, &height); if(((y + height) - (rect.y + rect.height)) > height){ scroll = FALSE; } else { scroll = TRUE; } // highlighting stuff highlight_match (string); // FIXME the following lines should be done through hooks // script stuff script_match_string (string->string->str); // log it warlock_log (string->string->str); // Put the mark there that will stay in the same place when we insert // text as a reference for highlighting gtk_text_buffer_move_mark (buffer, view->mark, &iter); gtk_text_buffer_insert (buffer, &iter, string->string->str, -1); // markup the buffer with the tags from our string for (list_current = string->highlights; list_current != NULL; list_current = list_current->next) { WHighlight *tmp = list_current->data; debug ("tag: %s offset: %d length: %d\n", tmp->tag_name, tmp->offset, tmp->length); gtk_text_buffer_get_iter_at_mark (buffer, &start, view->mark); gtk_text_iter_forward_chars (&start, tmp->offset); end = start; gtk_text_iter_forward_chars (&end, tmp->length); gtk_text_buffer_apply_tag_by_name (buffer, tmp->tag_name, &start, &end); } if (scroll) { // scroll the end mark on the screen. gtk_text_iter_set_line_offset (&iter, 0); gtk_text_buffer_move_mark (buffer, view->mark, &iter); gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (view->text_view), view->mark, 0, TRUE, 1.0, 0.0); } // Cut off beginning lines that don't fit in the buffer. warlock_view_trim (view); if (view == main_view) prompting = FALSE; }
static void dma_sparse_view_paint_margin (DmaSparseView *view, GdkEventExpose *event) { GtkTextView *text_view; GdkWindow *win; PangoLayout *layout; gint y1, y2; gint y, height; gchar str [16]; gint margin_width; gint margin_length; gint text_width; DmaSparseIter buf_iter; GtkTextIter text_iter; guint prev_address = G_MAXUINT; text_view = GTK_TEXT_VIEW (view); if (!view->priv->show_line_numbers && !view->priv->show_line_markers) { gtk_text_view_set_border_window_size (text_view, GTK_TEXT_WINDOW_LEFT, 0); return; } win = gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_LEFT); y1 = event->area.y; y2 = y1 + event->area.height; /* get the extents of the line printing */ gtk_text_view_window_to_buffer_coords (text_view, GTK_TEXT_WINDOW_LEFT, 0, y1, NULL, &y1); gtk_text_view_window_to_buffer_coords (text_view, GTK_TEXT_WINDOW_LEFT, 0, y2, NULL, &y2); /* set size. */ g_snprintf (str, sizeof (str), "0x%X", G_MAXUINT); margin_length = strlen(str) - 2; layout = gtk_widget_create_pango_layout (GTK_WIDGET (view), str); pango_layout_get_pixel_size (layout, &text_width, NULL); pango_layout_set_width (layout, text_width); pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT); /* determine the width of the left margin. */ if (view->priv->show_line_numbers) margin_width = text_width + 4; else margin_width = 0; if (view->priv->show_line_markers) margin_width += GUTTER_PIXMAP; g_return_if_fail (margin_width != 0); gtk_text_view_set_border_window_size (GTK_TEXT_VIEW (text_view), GTK_TEXT_WINDOW_LEFT, margin_width); /* Display all addresses */ dma_sparse_iter_copy (&buf_iter, &view->priv->start); gtk_text_buffer_get_start_iter (gtk_text_view_get_buffer (text_view), &text_iter); /* Skip line while position doesn't need to be repaint */ gtk_text_view_get_line_yrange (text_view, &text_iter, &y, &height); if (y < y1) { do { if (!dma_sparse_iter_forward_lines (&buf_iter, 1)) return; if (!gtk_text_iter_forward_line (&text_iter)) return; gtk_text_view_get_line_yrange (text_view, &text_iter, &y, &height); } while (y < y1); } /* Display address */ do { gint pos; guint address; gtk_text_view_buffer_to_window_coords (text_view, GTK_TEXT_WINDOW_LEFT, 0, y, NULL, &pos); address = dma_sparse_iter_get_address (&buf_iter); if (view->priv->show_line_numbers) { g_snprintf (str, sizeof (str),"0x%0*lX", margin_length, (long unsigned int)address); pango_layout_set_markup (layout, str, -1); gtk_paint_layout (gtk_widget_get_style (GTK_WIDGET (view)), win, gtk_widget_get_state (GTK_WIDGET (view)), FALSE, NULL, GTK_WIDGET (view), NULL, text_width + 2, pos, layout); } /* Display marker */ if ((prev_address != address) && (view->priv->show_line_markers)) { gint current_marker = dma_sparse_buffer_get_marks (view->priv->buffer, address); if (current_marker) { gint x; if (view->priv->show_line_numbers) x = text_width + 4; else x = 0; draw_line_markers (view, current_marker, x, pos); prev_address = address; } } if (!dma_sparse_iter_forward_lines (&buf_iter, 1)) return; if (!gtk_text_iter_forward_line (&text_iter)) return; gtk_text_view_get_line_yrange (text_view, &text_iter, &y, &height); } while (y < y2); g_object_unref (G_OBJECT (layout)); }
/* This function is taken from gtk+/tests/testtext.c */ static gint get_lines (GtkTextView *text_view, gint first_y, gint last_y, GArray *buffer_coords, GArray *line_heights, GArray *numbers, gint *countp, GtkTextIter *start, GtkTextIter *end) { GtkTextIter iter; gint count; gint last_line_num = -1; gint total_height = 0; g_array_set_size (buffer_coords, 0); g_array_set_size (numbers, 0); if (line_heights != NULL) { g_array_set_size (line_heights, 0); } /* Get iter at first y */ gtk_text_view_get_line_at_y (text_view, &iter, first_y, NULL); /* For each iter, get its location and add it to the arrays. * Stop when we pass last_y */ count = 0; *start = iter; while (!gtk_text_iter_is_end (&iter)) { gint y, height; gtk_text_view_get_line_yrange (text_view, &iter, &y, &height); g_array_append_val (buffer_coords, y); if (line_heights) { g_array_append_val (line_heights, height); } total_height += height; last_line_num = gtk_text_iter_get_line (&iter); g_array_append_val (numbers, last_line_num); ++count; if ((y + height) >= last_y) { break; } gtk_text_iter_forward_line (&iter); } if (gtk_text_iter_is_end (&iter)) { gint y, height; gint line_num; gtk_text_view_get_line_yrange (text_view, &iter, &y, &height); line_num = gtk_text_iter_get_line (&iter); if (line_num != last_line_num) { g_array_append_val (buffer_coords, y); if (line_heights) { g_array_append_val (line_heights, height); } total_height += height; g_array_append_val (numbers, line_num); ++count; } } *countp = count; if (count == 0) { gint y = 0; gint n = 0; gint height; *countp = 1; g_array_append_val (buffer_coords, y); g_array_append_val (numbers, n); if (line_heights) { gtk_text_view_get_line_yrange (text_view, &iter, &y, &height); g_array_append_val (line_heights, height); total_height += height; } } *end = iter; return total_height; }