Пример #1
0
static Renderer *
renderer_at_x (GtkSourceGutter *gutter,
               gint             x,
               gint            *start,
               gint            *width)
{
	GList *item;
	gint s;
	gint w;

	update_gutter_size (gutter);

	s = 0;

	for (item = gutter->priv->renderers; item; item = g_list_next (item))
	{
		Renderer *renderer = item->data;
		gint xpad;

		if (!gtk_source_gutter_renderer_get_visible (renderer->renderer))
		{
			continue;
		}

		w = gtk_source_gutter_renderer_get_size (renderer->renderer);

		gtk_source_gutter_renderer_get_padding (renderer->renderer,
		                                        &xpad,
		                                        NULL);

		s += xpad;

		if (w > 0 && x >= s && x < s + w)
		{
			if (width)
			{
				*width = w;
			}

			if (start)
			{
				*start = s;
			}

			return renderer;
		}

		s += w + xpad;
	}

	return NULL;
}
Пример #2
0
static gint
calculate_gutter_size (GtkSourceGutter  *gutter,
                       GArray           *sizes)
{
	GList *item;
	gint total_width = 0;

	/* Calculate size */
	for (item = gutter->priv->renderers; item; item = g_list_next (item))
	{
		Renderer *renderer = item->data;
		gint width;

		if (!gtk_source_gutter_renderer_get_visible (renderer->renderer))
		{
			width = 0;
		}
		else
		{
			gint xpad;
			gint size;

			size = gtk_source_gutter_renderer_get_size (renderer->renderer);

			gtk_source_gutter_renderer_get_padding (renderer->renderer,
			                                        &xpad,
			                                        NULL);

			width = size + 2 * xpad;
		}

		if (sizes)
		{
			g_array_append_val (sizes, width);
		}

		total_width += width + gutter->priv->xpad;
	}

	if (gutter->priv->renderers)
	{
		total_width += gutter->priv->xpad;
	}

	return total_width;
}
Пример #3
0
/* Call gtk_source_gutter_renderer_begin() on each renderer. */
static void
begin_draw (GtkSourceGutter *gutter,
	    GtkTextView     *view,
	    GArray          *renderer_widths,
	    LinesInfo       *info,
	    cairo_t         *cr)
{
	GdkRectangle background_area;
	GdkRectangle cell_area;
	GList *l;
	gint renderer_num;

	background_area.x = 0;
	background_area.height = info->total_height;

	gtk_text_view_buffer_to_window_coords (view,
	                                       gutter->priv->window_type,
	                                       0,
	                                       g_array_index (info->buffer_coords, gint, 0),
	                                       NULL,
	                                       &background_area.y);

	cell_area = background_area;

	for (l = gutter->priv->renderers, renderer_num = 0;
	     l != NULL;
	     l = l->next, renderer_num++)
	{
		Renderer *renderer = l->data;
		gint width;
		gint xpad;

		width = g_array_index (renderer_widths, gint, renderer_num);

		if (!gtk_source_gutter_renderer_get_visible (renderer->renderer))
		{
			g_assert_cmpint (width, ==, 0);
			continue;
		}

		gtk_source_gutter_renderer_get_padding (renderer->renderer,
							&xpad,
							NULL);

		background_area.width = width;

		cell_area.width = background_area.width - 2 * xpad;
		cell_area.x = background_area.x + xpad;

		cairo_save (cr);

		gdk_cairo_rectangle (cr, &background_area);
		cairo_clip (cr);

		gtk_source_gutter_renderer_begin (renderer->renderer,
						  cr,
						  &background_area,
						  &cell_area,
						  &info->start,
						  &info->end);

		cairo_restore (cr);

		background_area.x += background_area.width;
	}
Пример #4
0
static gboolean
on_view_draw (GtkSourceView   *view,
              cairo_t         *cr,
              GtkSourceGutter *gutter)
{
	GdkWindow *window;
	GtkTextView *text_view;
	GArray *sizes;
	GdkRectangle clip;
	gint x, y;
	gint y1, y2;
	GArray *numbers;
	GArray *pixels;
	GArray *heights;
	GtkTextIter cur;
	gint cur_line;
	gint count;
	gint i;
	GList *item;
	GtkTextIter start;
	GtkTextIter end;
	GtkTextBuffer *buffer;
	GdkRectangle background_area;
	GdkRectangle cell_area;
	GtkTextIter selection_start;
	GtkTextIter selection_end;
	gboolean has_selection;
	gint idx;
	GtkStyleContext *style_context;
	GdkRGBA fg_color;

	window = gtk_source_gutter_get_window (gutter);

	if (window == NULL || !gtk_cairo_should_draw_window (cr, window))
	{
		return FALSE;
	}

	gtk_cairo_transform_to_window (cr, GTK_WIDGET (view), window);

	text_view = GTK_TEXT_VIEW (view);

	if (!gdk_cairo_get_clip_rectangle (cr, &clip))
	{
		return FALSE;
	}

	gutter->priv->is_drawing = TRUE;

	buffer = gtk_text_view_get_buffer (text_view);

	gdk_window_get_pointer (window, &x, &y, NULL);

	y1 = clip.y;
	y2 = y1 + clip.height;

	/* get the extents of the line printing */
	gtk_text_view_window_to_buffer_coords (text_view,
	                                       gutter->priv->window_type,
	                                       0,
	                                       y1,
	                                       NULL,
	                                       &y1);

	gtk_text_view_window_to_buffer_coords (text_view,
	                                       gutter->priv->window_type,
	                                       0,
	                                       y2,
	                                       NULL,
	                                       &y2);

	numbers = g_array_new (FALSE, FALSE, sizeof (gint));
	pixels = g_array_new (FALSE, FALSE, sizeof (gint));
	heights = g_array_new (FALSE, FALSE, sizeof (gint));
	sizes = g_array_new (FALSE, FALSE, sizeof (gint));

	calculate_gutter_size (gutter, sizes);

	i = 0;
	x = 0;

	background_area.x = 0;
	background_area.height = get_lines (text_view,
	                                    y1,
	                                    y2,
	                                    pixels,
	                                    heights,
	                                    numbers,
	                                    &count,
	                                    &start,
	                                    &end);

	cell_area.x = gutter->priv->xpad;
	cell_area.height = background_area.height;

	gtk_text_view_buffer_to_window_coords (text_view,
	                                       gutter->priv->window_type,
	                                       0,
	                                       g_array_index (pixels, gint, 0),
	                                       NULL,
	                                       &background_area.y);

	cell_area.y = background_area.y;

	item = gutter->priv->renderers;
	idx = 0;

	style_context = gtk_widget_get_style_context (GTK_WIDGET (view));

	gtk_style_context_get_color (style_context,
	                             gtk_widget_get_state (GTK_WIDGET (view)),
	                             &fg_color);

	gdk_cairo_set_source_rgba (cr, &fg_color);

	while (item)
	{
		Renderer *renderer = item->data;
		gint xpad;
		gint width;

		width = g_array_index (sizes, gint, idx++);

		if (gtk_source_gutter_renderer_get_visible (renderer->renderer))
		{
			gtk_source_gutter_renderer_get_padding (renderer->renderer,
			                                        &xpad,
			                                        NULL);

			background_area.width = width;

			cell_area.width = width - 2 * xpad;
			cell_area.x = background_area.x + xpad;

			cairo_save (cr);

			gdk_cairo_rectangle (cr, &background_area);
			cairo_clip (cr);

			gtk_source_gutter_renderer_begin (renderer->renderer,
			                                  cr,
			                                  &background_area,
			                                  &cell_area,
			                                  &start,
			                                  &end);

			cairo_restore (cr);

			background_area.x += background_area.width;
		}

		item = g_list_next (item);
	}

	gtk_text_buffer_get_iter_at_mark (buffer,
	                                  &cur,
	                                  gtk_text_buffer_get_insert (buffer));

	cur_line = gtk_text_iter_get_line (&cur);

	gtk_text_buffer_get_selection_bounds (buffer,
	                                      &selection_start,
	                                      &selection_end);

	has_selection = !gtk_text_iter_equal (&selection_start, &selection_end);

	if (has_selection)
	{
		if (!gtk_text_iter_starts_line (&selection_start))
		{
			gtk_text_iter_set_line_offset (&selection_start, 0);
		}

		if (!gtk_text_iter_ends_line (&selection_end))
		{
			gtk_text_iter_forward_to_line_end (&selection_end);
		}
	}

	for (i = 0; i < count; ++i)
	{
		gint pos;
		gint line_to_paint;

		end = start;

		if (!gtk_text_iter_ends_line (&end))
		{
			gtk_text_iter_forward_to_line_end (&end);
		}

		gtk_text_view_buffer_to_window_coords (text_view,
		                                       gutter->priv->window_type,
		                                       0,
		                                       g_array_index (pixels, gint, i),
		                                       NULL,
		                                       &pos);

		line_to_paint = g_array_index (numbers, gint, i);

		background_area.y = pos;
		background_area.height = g_array_index (heights, gint, i);
		background_area.x = 0;

		idx = 0;

		for (item = gutter->priv->renderers; item; item = g_list_next (item))
		{
			Renderer *renderer;
			gint width;
			GtkSourceGutterRendererState state;
			gint xpad;
			gint ypad;

			renderer = item->data;
			width = g_array_index (sizes, gint, idx++);

			if (!gtk_source_gutter_renderer_get_visible (renderer->renderer))
			{
				continue;
			}

			gtk_source_gutter_renderer_get_padding (renderer->renderer,
			                                        &xpad,
			                                        &ypad);

			background_area.width = width;

			cell_area.y = background_area.y + ypad;
			cell_area.height = background_area.height - 2 * ypad;

			cell_area.x = background_area.x + xpad;
			cell_area.width = background_area.width - 2 * xpad;

			state = GTK_SOURCE_GUTTER_RENDERER_STATE_NORMAL;

			if (line_to_paint == cur_line)
			{
				state |= GTK_SOURCE_GUTTER_RENDERER_STATE_CURSOR;
			}

			if (has_selection &&
			    gtk_text_iter_in_range (&start,
			                            &selection_start,
			                            &selection_end))
			{
				state |= GTK_SOURCE_GUTTER_RENDERER_STATE_SELECTED;
			}

			if (renderer->prelit >= 0 && cell_area.y <= renderer->prelit && cell_area.y + cell_area.height >= renderer->prelit)
			{
				state |= GTK_SOURCE_GUTTER_RENDERER_STATE_PRELIT;
			}

			gtk_source_gutter_renderer_query_data (renderer->renderer,
			                                       &start,
			                                       &end,
			                                       state);

			cairo_save (cr);

			gdk_cairo_rectangle (cr, &background_area);

			cairo_clip (cr);

			/* Call render with correct area */
			gtk_source_gutter_renderer_draw (renderer->renderer,
			                                 cr,
			                                 &background_area,
			                                 &cell_area,
			                                 &start,
			                                 &end,
			                                 state);

			cairo_restore (cr);

			background_area.x += background_area.width;
		}

		gtk_text_iter_forward_line (&start);
	}

	for (item = gutter->priv->renderers; item; item = g_list_next (item))
	{
		Renderer *renderer = item->data;

		if (gtk_source_gutter_renderer_get_visible (renderer->renderer))
		{
			gtk_source_gutter_renderer_end (renderer->renderer);
		}
	}

	g_array_free (numbers, TRUE);
	g_array_free (pixels, TRUE);
	g_array_free (heights, TRUE);

	g_array_free (sizes, TRUE);

	gutter->priv->is_drawing = FALSE;

	return FALSE;
}
Пример #5
0
static gboolean
redraw_for_window (GtkSourceGutter *gutter,
                   GdkEventAny     *event,
                   gboolean         act_on_window,
                   gint             x,
                   gint             y)
{
	Renderer *at_x = NULL;
	GList *item;
	gboolean redraw;
	gint start;

	if (event->window != gtk_source_gutter_get_window (gutter) && act_on_window)
	{
		return FALSE;
	}

	if (act_on_window)
	{
		at_x = renderer_at_x (gutter, x, &start, NULL);
	}

	redraw = FALSE;

	for (item = gutter->priv->renderers; item; item = g_list_next (item))
	{
		Renderer *renderer = item->data;
		gint prelit = renderer->prelit;

		if (!gtk_source_gutter_renderer_get_visible (renderer->renderer))
		{
			renderer->prelit = -1;
		}
		else
		{
			if (renderer != at_x || !act_on_window)
			{
				renderer->prelit = -1;
			}
			else if (renderer_query_activatable (gutter,
			                                     renderer,
			                                     (GdkEvent *)event,
			                                     x,
			                                     y,
			                                     NULL,
			                                     NULL,
			                                     start))
			{
				renderer->prelit = y;
			}
			else
			{
				renderer->prelit = -1;
			}
		}

		redraw |= (renderer->prelit != prelit);
	}

	if (redraw)
	{
		do_redraw (gutter);
	}

	return FALSE;
}