mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-09-29 18:47:38 +00:00
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:
parent
b3f850e6b9
commit
0bff1af7a2
@ -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 */
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user