Rework GtkTextView cursor code.

Move the handling of primary/secondary cursors to gtktextdisplay, which
makes code simpler and more consistent to how GtkLabel and GtkEntry
draw cursors, which is useful in preparation to further refactoring.

https://bugzilla.gnome.org/show_bug.cgi?id=640317
This commit is contained in:
Paolo Borelli 2011-11-26 23:48:10 +01:00
parent b3f850e6b9
commit 0bff1af7a2
3 changed files with 49 additions and 100 deletions

View File

@ -822,7 +822,6 @@ gtk_text_layout_draw (GtkTextLayout *layout,
GList **widgets)
{
gint offset_y;
GSList *cursor_list;
GtkTextRenderer *text_renderer;
GtkTextIter selection_start, selection_end;
gboolean have_selection;
@ -862,8 +861,6 @@ gtk_text_layout_draw (GtkTextLayout *layout,
GtkTextLineDisplay *line_display;
gint selection_start_index = -1;
gint selection_end_index = -1;
gboolean have_strong;
gboolean have_weak;
GtkTextLine *line = tmp_list->data;
@ -905,47 +902,52 @@ gtk_text_layout_draw (GtkTextLayout *layout,
selection_start_index, selection_end_index);
/* We paint the cursors last, because they overlap another chunk
and need to appear on top. */
have_strong = FALSE;
have_weak = FALSE;
cursor_list = line_display->cursors;
while (cursor_list)
{
GtkTextCursorDisplay *cursor = cursor_list->data;
if (cursor->is_strong)
have_strong = TRUE;
else
have_weak = TRUE;
cursor_list = cursor_list->next;
}
cursor_list = line_display->cursors;
while (cursor_list)
* and need to appear on top.
*/
if (line_display->cursors != NULL)
{
GtkTextCursorDisplay *cursor = cursor_list->data;
GtkTextDirection dir;
GdkRectangle cursor_location;
int i;
dir = line_display->direction;
if (have_strong && have_weak)
{
if (!cursor->is_strong)
dir = (dir == GTK_TEXT_DIR_RTL) ? GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL;
}
cursor_location.x = line_display->x_offset + cursor->x;
cursor_location.y = line_display->top_margin + cursor->y;
cursor_location.width = 0;
cursor_location.height = cursor->height;
for (i = 0; i < line_display->cursors->len; i++)
{
int index;
PangoRectangle strong_pos, weak_pos;
GdkRectangle cursor_location;
gtk_draw_insertion_cursor (widget, cr, &cursor_location,
cursor->is_strong,
dir, have_strong && have_weak);
index = g_array_index(line_display->cursors, int, i);
pango_layout_get_cursor_pos (line_display->layout, index, &strong_pos, &weak_pos);
cursor_list = cursor_list->next;
cursor_location.x = line_display->x_offset + PANGO_PIXELS (strong_pos.x);
cursor_location.y = line_display->top_margin + PANGO_PIXELS (strong_pos.y);
cursor_location.width = 0;
cursor_location.height = PANGO_PIXELS (strong_pos.height);
if (layout->cursor_direction == GTK_TEXT_DIR_NONE ||
line_display->direction == layout->cursor_direction)
{
gtk_draw_insertion_cursor (widget, cr,
&cursor_location, TRUE, line_display->direction,
layout->cursor_direction != GTK_TEXT_DIR_NONE);
}
if ((strong_pos.x != weak_pos.x || strong_pos.y != weak_pos.y) &&
(layout->cursor_direction == GTK_TEXT_DIR_NONE ||
line_display->direction != layout->cursor_direction))
{
GtkTextDirection dir;
dir = (line_display->direction == GTK_TEXT_DIR_RTL) ? GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL;
cursor_location.x = line_display->x_offset + PANGO_PIXELS (weak_pos.x);
cursor_location.y = line_display->top_margin + PANGO_PIXELS (weak_pos.y);
cursor_location.width = 0;
cursor_location.height = PANGO_PIXELS (weak_pos.height);
gtk_draw_insertion_cursor (widget, cr,
&cursor_location, FALSE, dir,
TRUE);
}
}
}
} /* line_display->height > 0 */

View File

@ -827,8 +827,8 @@ gtk_text_layout_invalidate_cache (GtkTextLayout *layout,
if (cursors_only)
{
g_slist_foreach (display->cursors, (GFunc)g_free, NULL);
g_slist_free (display->cursors);
if (display->cursors)
g_array_free (display->cursors, TRUE);
display->cursors = NULL;
display->cursors_invalid = TRUE;
display->has_block_cursor = FALSE;
@ -1733,11 +1733,6 @@ add_cursor (GtkTextLayout *layout,
GtkTextLineSegment *seg,
gint start)
{
PangoRectangle strong_pos, weak_pos;
GtkTextCursorDisplay *cursor = NULL; /* Quiet GCC */
gboolean add_weak = FALSE;
gboolean add_strong = FALSE;
/* Hide insertion cursor when we have a selection or the layout
* user has hidden the cursor.
*/
@ -1767,46 +1762,10 @@ add_cursor (GtkTextLayout *layout,
}
}
pango_layout_get_cursor_pos (display->layout, start, &strong_pos, &weak_pos);
if (!display->cursors)
display->cursors = g_array_new (FALSE, FALSE, sizeof(int));
if (layout->cursor_direction == GTK_TEXT_DIR_NONE)
{
add_strong = TRUE;
add_weak = TRUE;
}
else if (display->direction == layout->cursor_direction)
add_strong = TRUE;
else
add_weak = TRUE;
if (add_strong)
{
cursor = g_new (GtkTextCursorDisplay, 1);
cursor->x = PANGO_PIXELS (strong_pos.x);
cursor->y = PANGO_PIXELS (strong_pos.y);
cursor->height = PANGO_PIXELS (strong_pos.height);
cursor->is_strong = TRUE;
cursor->is_weak = (layout->cursor_direction == GTK_TEXT_DIR_NONE) ? FALSE : TRUE;
display->cursors = g_slist_prepend (display->cursors, cursor);
}
if (add_weak)
{
if (weak_pos.x == strong_pos.x && add_strong)
cursor->is_weak = TRUE;
else
{
cursor = g_new (GtkTextCursorDisplay, 1);
cursor->x = PANGO_PIXELS (weak_pos.x);
cursor->y = PANGO_PIXELS (weak_pos.y);
cursor->height = PANGO_PIXELS (weak_pos.height);
cursor->is_strong = (layout->cursor_direction == GTK_TEXT_DIR_NONE) ? FALSE : TRUE;
cursor->is_weak = TRUE;
display->cursors = g_slist_prepend (display->cursors, cursor);
}
}
display->cursors = g_array_append_val (display->cursors, start);
}
static gboolean
@ -2530,10 +2489,7 @@ gtk_text_layout_free_line_display (GtkTextLayout *layout,
g_object_unref (display->layout);
if (display->cursors)
{
g_slist_foreach (display->cursors, (GFunc)g_free, NULL);
g_slist_free (display->cursors);
}
g_array_free (display->cursors, TRUE);
if (display->pg_bg_color)
gdk_color_free (display->pg_bg_color);

View File

@ -109,7 +109,6 @@ typedef struct _GtkTextLineData GtkTextLineData;
typedef struct _GtkTextLayout GtkTextLayout;
typedef struct _GtkTextLayoutClass GtkTextLayoutClass;
typedef struct _GtkTextLineDisplay GtkTextLineDisplay;
typedef struct _GtkTextCursorDisplay GtkTextCursorDisplay;
typedef struct _GtkTextAttrAppearance GtkTextAttrAppearance;
struct _GtkTextLayout
@ -225,19 +224,11 @@ struct _GtkTextAttrAppearance
PangoAttribute attr;
GtkTextAppearance appearance;
};
struct _GtkTextCursorDisplay
{
gint x;
gint y;
gint height;
guint is_strong : 1;
guint is_weak : 1;
};
struct _GtkTextLineDisplay
{
PangoLayout *layout;
GSList *cursors;
GArray *cursors; /* indexes of cursors in the PangoLayout */
GtkTextDirection direction;