Rearrange all the scroll-while-dragging-or-selecting code to be different,

2000-12-31  Havoc Pennington  <hp@pobox.com>

* gtk/gtktextview.c: Rearrange all the
scroll-while-dragging-or-selecting code to be different, not
necessarily better. ;-)
(gtk_text_view_scroll_to_mark): Change this
function to take within_margin as a fraction instead of a pixel
value, and to take alignment arguments (indicating where to align
the mark inside the visible area)

* gtk/testtextbuffer.c (fill_buffer): fix bad cast of GtkTextTag
to GtkObject

* gtk/gtktextiter.c (gtk_text_iter_set_line_offset): change
behavior so that offsets past the end of the line are not
allowed, and an offset equal to the line length moves the iterator
to the next line
(gtk_text_iter_set_line_index): make parallel change
(gtk_text_iter_get_bytes_in_line): add this function

* gtk/gtktextbtree.c (_gtk_text_line_byte_locate): change handling
of byte indexes off the end of the line; byte index at the end of
the line now returns FALSE and doesn't fill in the requested
values, byte index past the end of the line is an error.  Also,
don't allow -1 offset anymore, since its meaning is unclear.

This change exposes some bug in visual cursor motion, where we
end up with a huge invalid byte index; needs fixing. Symptom of
bug is a crash when you hit up arrow.

(_gtk_text_line_char_locate): match the change to byte_locate

* gtk/gtktextiter.c (find_by_log_attrs): Handle iteration backward
from start of line properly. fixes bug reported by Mikael
Hermansson where backspace would delete all text before the
cursor.
This commit is contained in:
Havoc Pennington 2000-12-31 23:28:57 +00:00 committed by Havoc Pennington
parent 72cdcb6323
commit 7a958797e2
15 changed files with 731 additions and 278 deletions

View File

@ -1,3 +1,40 @@
2000-12-31 Havoc Pennington <hp@pobox.com>
* gtk/gtktextview.c: Rearrange all the
scroll-while-dragging-or-selecting code to be different, not
necessarily better. ;-)
(gtk_text_view_scroll_to_mark): Change this
function to take within_margin as a fraction instead of a pixel
value, and to take alignment arguments (indicating where to align
the mark inside the visible area)
* gtk/testtextbuffer.c (fill_buffer): fix bad cast of GtkTextTag
to GtkObject
* gtk/gtktextiter.c (gtk_text_iter_set_line_offset): change
behavior so that offsets past the end of the line are not
allowed, and an offset equal to the line length moves the iterator
to the next line
(gtk_text_iter_set_line_index): make parallel change
(gtk_text_iter_get_bytes_in_line): add this function
* gtk/gtktextbtree.c (_gtk_text_line_byte_locate): change handling
of byte indexes off the end of the line; byte index at the end of
the line now returns FALSE and doesn't fill in the requested
values, byte index past the end of the line is an error. Also,
don't allow -1 offset anymore, since its meaning is unclear.
This change exposes some bug in visual cursor motion, where we
end up with a huge invalid byte index; needs fixing. Symptom of
bug is a crash when you hit up arrow.
(_gtk_text_line_char_locate): match the change to byte_locate
* gtk/gtktextiter.c (find_by_log_attrs): Handle iteration backward
from start of line properly. fixes bug reported by Mikael
Hermansson where backspace would delete all text before the
cursor.
2000-12-30 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkwindow-win32.c

View File

@ -1,3 +1,40 @@
2000-12-31 Havoc Pennington <hp@pobox.com>
* gtk/gtktextview.c: Rearrange all the
scroll-while-dragging-or-selecting code to be different, not
necessarily better. ;-)
(gtk_text_view_scroll_to_mark): Change this
function to take within_margin as a fraction instead of a pixel
value, and to take alignment arguments (indicating where to align
the mark inside the visible area)
* gtk/testtextbuffer.c (fill_buffer): fix bad cast of GtkTextTag
to GtkObject
* gtk/gtktextiter.c (gtk_text_iter_set_line_offset): change
behavior so that offsets past the end of the line are not
allowed, and an offset equal to the line length moves the iterator
to the next line
(gtk_text_iter_set_line_index): make parallel change
(gtk_text_iter_get_bytes_in_line): add this function
* gtk/gtktextbtree.c (_gtk_text_line_byte_locate): change handling
of byte indexes off the end of the line; byte index at the end of
the line now returns FALSE and doesn't fill in the requested
values, byte index past the end of the line is an error. Also,
don't allow -1 offset anymore, since its meaning is unclear.
This change exposes some bug in visual cursor motion, where we
end up with a huge invalid byte index; needs fixing. Symptom of
bug is a crash when you hit up arrow.
(_gtk_text_line_char_locate): match the change to byte_locate
* gtk/gtktextiter.c (find_by_log_attrs): Handle iteration backward
from start of line properly. fixes bug reported by Mikael
Hermansson where backspace would delete all text before the
cursor.
2000-12-30 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkwindow-win32.c

View File

@ -1,3 +1,40 @@
2000-12-31 Havoc Pennington <hp@pobox.com>
* gtk/gtktextview.c: Rearrange all the
scroll-while-dragging-or-selecting code to be different, not
necessarily better. ;-)
(gtk_text_view_scroll_to_mark): Change this
function to take within_margin as a fraction instead of a pixel
value, and to take alignment arguments (indicating where to align
the mark inside the visible area)
* gtk/testtextbuffer.c (fill_buffer): fix bad cast of GtkTextTag
to GtkObject
* gtk/gtktextiter.c (gtk_text_iter_set_line_offset): change
behavior so that offsets past the end of the line are not
allowed, and an offset equal to the line length moves the iterator
to the next line
(gtk_text_iter_set_line_index): make parallel change
(gtk_text_iter_get_bytes_in_line): add this function
* gtk/gtktextbtree.c (_gtk_text_line_byte_locate): change handling
of byte indexes off the end of the line; byte index at the end of
the line now returns FALSE and doesn't fill in the requested
values, byte index past the end of the line is an error. Also,
don't allow -1 offset anymore, since its meaning is unclear.
This change exposes some bug in visual cursor motion, where we
end up with a huge invalid byte index; needs fixing. Symptom of
bug is a crash when you hit up arrow.
(_gtk_text_line_char_locate): match the change to byte_locate
* gtk/gtktextiter.c (find_by_log_attrs): Handle iteration backward
from start of line properly. fixes bug reported by Mikael
Hermansson where backspace would delete all text before the
cursor.
2000-12-30 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkwindow-win32.c

View File

@ -1,3 +1,40 @@
2000-12-31 Havoc Pennington <hp@pobox.com>
* gtk/gtktextview.c: Rearrange all the
scroll-while-dragging-or-selecting code to be different, not
necessarily better. ;-)
(gtk_text_view_scroll_to_mark): Change this
function to take within_margin as a fraction instead of a pixel
value, and to take alignment arguments (indicating where to align
the mark inside the visible area)
* gtk/testtextbuffer.c (fill_buffer): fix bad cast of GtkTextTag
to GtkObject
* gtk/gtktextiter.c (gtk_text_iter_set_line_offset): change
behavior so that offsets past the end of the line are not
allowed, and an offset equal to the line length moves the iterator
to the next line
(gtk_text_iter_set_line_index): make parallel change
(gtk_text_iter_get_bytes_in_line): add this function
* gtk/gtktextbtree.c (_gtk_text_line_byte_locate): change handling
of byte indexes off the end of the line; byte index at the end of
the line now returns FALSE and doesn't fill in the requested
values, byte index past the end of the line is an error. Also,
don't allow -1 offset anymore, since its meaning is unclear.
This change exposes some bug in visual cursor motion, where we
end up with a huge invalid byte index; needs fixing. Symptom of
bug is a crash when you hit up arrow.
(_gtk_text_line_char_locate): match the change to byte_locate
* gtk/gtktextiter.c (find_by_log_attrs): Handle iteration backward
from start of line properly. fixes bug reported by Mikael
Hermansson where backspace would delete all text before the
cursor.
2000-12-30 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkwindow-win32.c

View File

@ -1,3 +1,40 @@
2000-12-31 Havoc Pennington <hp@pobox.com>
* gtk/gtktextview.c: Rearrange all the
scroll-while-dragging-or-selecting code to be different, not
necessarily better. ;-)
(gtk_text_view_scroll_to_mark): Change this
function to take within_margin as a fraction instead of a pixel
value, and to take alignment arguments (indicating where to align
the mark inside the visible area)
* gtk/testtextbuffer.c (fill_buffer): fix bad cast of GtkTextTag
to GtkObject
* gtk/gtktextiter.c (gtk_text_iter_set_line_offset): change
behavior so that offsets past the end of the line are not
allowed, and an offset equal to the line length moves the iterator
to the next line
(gtk_text_iter_set_line_index): make parallel change
(gtk_text_iter_get_bytes_in_line): add this function
* gtk/gtktextbtree.c (_gtk_text_line_byte_locate): change handling
of byte indexes off the end of the line; byte index at the end of
the line now returns FALSE and doesn't fill in the requested
values, byte index past the end of the line is an error. Also,
don't allow -1 offset anymore, since its meaning is unclear.
This change exposes some bug in visual cursor motion, where we
end up with a huge invalid byte index; needs fixing. Symptom of
bug is a crash when you hit up arrow.
(_gtk_text_line_char_locate): match the change to byte_locate
* gtk/gtktextiter.c (find_by_log_attrs): Handle iteration backward
from start of line properly. fixes bug reported by Mikael
Hermansson where backspace would delete all text before the
cursor.
2000-12-30 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkwindow-win32.c

View File

@ -1,3 +1,40 @@
2000-12-31 Havoc Pennington <hp@pobox.com>
* gtk/gtktextview.c: Rearrange all the
scroll-while-dragging-or-selecting code to be different, not
necessarily better. ;-)
(gtk_text_view_scroll_to_mark): Change this
function to take within_margin as a fraction instead of a pixel
value, and to take alignment arguments (indicating where to align
the mark inside the visible area)
* gtk/testtextbuffer.c (fill_buffer): fix bad cast of GtkTextTag
to GtkObject
* gtk/gtktextiter.c (gtk_text_iter_set_line_offset): change
behavior so that offsets past the end of the line are not
allowed, and an offset equal to the line length moves the iterator
to the next line
(gtk_text_iter_set_line_index): make parallel change
(gtk_text_iter_get_bytes_in_line): add this function
* gtk/gtktextbtree.c (_gtk_text_line_byte_locate): change handling
of byte indexes off the end of the line; byte index at the end of
the line now returns FALSE and doesn't fill in the requested
values, byte index past the end of the line is an error. Also,
don't allow -1 offset anymore, since its meaning is unclear.
This change exposes some bug in visual cursor motion, where we
end up with a huge invalid byte index; needs fixing. Symptom of
bug is a crash when you hit up arrow.
(_gtk_text_line_char_locate): match the change to byte_locate
* gtk/gtktextiter.c (find_by_log_attrs): Handle iteration backward
from start of line properly. fixes bug reported by Mikael
Hermansson where backspace would delete all text before the
cursor.
2000-12-30 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkwindow-win32.c

View File

@ -1,3 +1,40 @@
2000-12-31 Havoc Pennington <hp@pobox.com>
* gtk/gtktextview.c: Rearrange all the
scroll-while-dragging-or-selecting code to be different, not
necessarily better. ;-)
(gtk_text_view_scroll_to_mark): Change this
function to take within_margin as a fraction instead of a pixel
value, and to take alignment arguments (indicating where to align
the mark inside the visible area)
* gtk/testtextbuffer.c (fill_buffer): fix bad cast of GtkTextTag
to GtkObject
* gtk/gtktextiter.c (gtk_text_iter_set_line_offset): change
behavior so that offsets past the end of the line are not
allowed, and an offset equal to the line length moves the iterator
to the next line
(gtk_text_iter_set_line_index): make parallel change
(gtk_text_iter_get_bytes_in_line): add this function
* gtk/gtktextbtree.c (_gtk_text_line_byte_locate): change handling
of byte indexes off the end of the line; byte index at the end of
the line now returns FALSE and doesn't fill in the requested
values, byte index past the end of the line is an error. Also,
don't allow -1 offset anymore, since its meaning is unclear.
This change exposes some bug in visual cursor motion, where we
end up with a huge invalid byte index; needs fixing. Symptom of
bug is a crash when you hit up arrow.
(_gtk_text_line_char_locate): match the change to byte_locate
* gtk/gtktextiter.c (find_by_log_attrs): Handle iteration backward
from start of line properly. fixes bug reported by Mikael
Hermansson where backspace would delete all text before the
cursor.
2000-12-30 Tor Lillqvist <tml@iki.fi>
* gdk/win32/gdkwindow-win32.c

View File

@ -1053,9 +1053,9 @@ _gtk_text_btree_insert (GtkTextIter *iter,
_gtk_text_btree_get_iter_at_line (tree,
&start,
start_line,
start_byte_index);
&start,
start_line,
start_byte_index);
end = start;
/* We could almost certainly be more efficient here
@ -3545,13 +3545,13 @@ _gtk_text_line_char_to_byte (GtkTextLine *line,
/* FIXME sync with char_locate (or figure out a clean
way to merge the two functions) */
void
gboolean
_gtk_text_line_byte_locate (GtkTextLine *line,
gint byte_offset,
GtkTextLineSegment **segment,
GtkTextLineSegment **any_segment,
gint *seg_byte_offset,
gint *line_byte_offset)
gint byte_offset,
GtkTextLineSegment **segment,
GtkTextLineSegment **any_segment,
gint *seg_byte_offset,
gint *line_byte_offset)
{
GtkTextLineSegment *seg;
GtkTextLineSegment *after_prev_indexable;
@ -3560,16 +3560,8 @@ _gtk_text_line_byte_locate (GtkTextLine *line,
gint offset;
gint bytes_in_line;
g_return_if_fail (line != NULL);
if (byte_offset < 0)
{
/* -1 means end of line; we here assume no line is
longer than 1 bazillion bytes, of course we assumed
that anyway since we'd wrap around... */
byte_offset = G_MAXINT;
}
g_return_val_if_fail (line != NULL, FALSE);
g_return_val_if_fail (byte_offset >= 0, FALSE);
*segment = NULL;
*any_segment = NULL;
@ -3602,11 +3594,10 @@ _gtk_text_line_byte_locate (GtkTextLine *line,
if (seg == NULL)
{
/* We went off the end of the line */
*segment = last_indexable;
*any_segment = after_prev_indexable;
/* subtracting 1 is OK, we know it's a newline at the end. */
offset = (*segment)->byte_count - 1;
bytes_in_line -= (*segment)->byte_count;
if (offset != 0)
g_warning ("%s: byte index off the end of the line", G_STRLOC);
return FALSE;
}
else
{
@ -3628,17 +3619,19 @@ _gtk_text_line_byte_locate (GtkTextLine *line,
g_assert (*seg_byte_offset < (*segment)->byte_count);
*line_byte_offset = bytes_in_line + *seg_byte_offset;
return TRUE;
}
/* FIXME sync with byte_locate (or figure out a clean
way to merge the two functions) */
void
gboolean
_gtk_text_line_char_locate (GtkTextLine *line,
gint char_offset,
GtkTextLineSegment **segment,
GtkTextLineSegment **any_segment,
gint *seg_char_offset,
gint *line_char_offset)
gint char_offset,
GtkTextLineSegment **segment,
GtkTextLineSegment **any_segment,
gint *seg_char_offset,
gint *line_char_offset)
{
GtkTextLineSegment *seg;
GtkTextLineSegment *after_prev_indexable;
@ -3647,17 +3640,9 @@ _gtk_text_line_char_locate (GtkTextLine *line,
gint offset;
gint chars_in_line;
g_return_if_fail (line != NULL);
if (char_offset < 0)
{
/* -1 means end of line; we here assume no line is
longer than 1 bazillion chars, of course we assumed
that anyway since we'd wrap around... */
char_offset = G_MAXINT;
}
g_return_val_if_fail (line != NULL, FALSE);
g_return_val_if_fail (char_offset >= 0, FALSE);
*segment = NULL;
*any_segment = NULL;
chars_in_line = 0;
@ -3688,12 +3673,11 @@ _gtk_text_line_char_locate (GtkTextLine *line,
if (seg == NULL)
{
/* We went off the end of the line */
*segment = last_indexable;
*any_segment = after_prev_indexable;
/* subtracting 1 is OK, we know it's a newline at the end. */
offset = (*segment)->char_count - 1;
chars_in_line -= (*segment)->char_count;
/* end of the line */
if (offset != 0)
g_warning ("%s: char offset off the end of the line", G_STRLOC);
return FALSE;
}
else
{
@ -3715,6 +3699,8 @@ _gtk_text_line_char_locate (GtkTextLine *line,
g_assert (*seg_char_offset < (*segment)->char_count);
*line_char_offset = chars_in_line + *seg_char_offset;
return TRUE;
}
void

View File

@ -225,13 +225,13 @@ GtkTextLineSegment *_gtk_text_line_byte_to_segment (GtkTextLine
GtkTextLineSegment *_gtk_text_line_char_to_segment (GtkTextLine *line,
gint char_offset,
gint *seg_offset);
void _gtk_text_line_byte_locate (GtkTextLine *line,
gboolean _gtk_text_line_byte_locate (GtkTextLine *line,
gint byte_offset,
GtkTextLineSegment **segment,
GtkTextLineSegment **any_segment,
gint *seg_byte_offset,
gint *line_byte_offset);
void _gtk_text_line_char_locate (GtkTextLine *line,
gboolean _gtk_text_line_char_locate (GtkTextLine *line,
gint char_offset,
GtkTextLineSegment **segment,
GtkTextLineSegment **any_segment,

View File

@ -93,12 +93,11 @@ iter_set_from_byte_offset (GtkTextRealIter *iter,
iter_set_common (iter, line);
_gtk_text_line_byte_locate (iter->line,
byte_offset,
&iter->segment,
&iter->any_segment,
&iter->segment_byte_offset,
&iter->line_byte_offset);
byte_offset,
&iter->segment,
&iter->any_segment,
&iter->segment_byte_offset,
&iter->line_byte_offset);
}
static void
@ -109,11 +108,11 @@ iter_set_from_char_offset (GtkTextRealIter *iter,
iter_set_common (iter, line);
_gtk_text_line_char_locate (iter->line,
char_offset,
&iter->segment,
&iter->any_segment,
&iter->segment_char_offset,
&iter->line_char_offset);
char_offset,
&iter->segment,
&iter->any_segment,
&iter->segment_char_offset,
&iter->line_char_offset);
}
static void
@ -1289,8 +1288,8 @@ gtk_text_iter_get_language (const GtkTextIter *iter)
* gtk_text_iter_starts_line:
* @iter: an iterator
*
* Returns TRUE if @iter begins a newline-terminated line,
* i.e. gtk_text_iter_get_line_offset () would return 0.
* Returns TRUE if @iter begins a paragraph,
* i.e. if gtk_text_iter_get_line_offset () would return 0.
* However this function is potentially more efficient than
* gtk_text_iter_get_line_offset () because it doesn't have to compute
* the offset, it just has to see whether it's 0.
@ -1419,7 +1418,7 @@ gtk_text_iter_is_first (const GtkTextIter *iter)
* @iter: an iterator
*
* Returns the number of characters in the line containing @iter,
* including the terminating newline.
* including the paragraph delimiters.
*
* Return value: number of characters in the line
**/
@ -1463,6 +1462,54 @@ gtk_text_iter_get_chars_in_line (const GtkTextIter *iter)
return count;
}
/**
* gtk_text_iter_get_bytes_in_line:
* @iter: an iterator
*
* Returns the number of bytes in the line containing @iter,
* including the paragraph delimiters.
*
* Return value: number of bytes in the line
**/
gint
gtk_text_iter_get_bytes_in_line (const GtkTextIter *iter)
{
GtkTextRealIter *real;
gint count;
GtkTextLineSegment *seg;
g_return_val_if_fail (iter != NULL, FALSE);
real = gtk_text_iter_make_surreal (iter);
if (real == NULL)
return 0;
check_invariants (iter);
if (real->line_byte_offset >= 0)
{
/* We can start at the segments we've already found. */
count = real->line_byte_offset - real->segment_byte_offset;
seg = gtk_text_iter_get_indexable_segment (iter);
}
else
{
/* count whole line. */
seg = real->line->segments;
count = 0;
}
while (seg != NULL)
{
count += seg->byte_count;
seg = seg->next;
}
return count;
}
/**
* gtk_text_iter_get_attributes:
* @iter: an iterator
@ -2388,7 +2435,8 @@ typedef gboolean (* FindLogAttrFunc) (const PangoLogAttr *attrs,
gint offset,
gint min_offset,
gint len,
gint *found_offset);
gint *found_offset,
gboolean already_moved_initially);
typedef gboolean (* TestLogAttrFunc) (const PangoLogAttr *attrs,
gint offset,
@ -2400,9 +2448,11 @@ find_word_end_func (const PangoLogAttr *attrs,
gint offset,
gint min_offset,
gint len,
gint *found_offset)
gint *found_offset,
gboolean already_moved_initially)
{
++offset; /* We always go to the NEXT word end */
if (!already_moved_initially)
++offset;
/* Find end of next word */
while (offset < min_offset + len &&
@ -2428,9 +2478,11 @@ find_word_start_func (const PangoLogAttr *attrs,
gint offset,
gint min_offset,
gint len,
gint *found_offset)
gint *found_offset,
gboolean already_moved_initially)
{
--offset; /* We always go to the NEXT word start */
if (!already_moved_initially)
--offset;
/* Find start of prev word */
while (offset >= min_offset &&
@ -2469,7 +2521,6 @@ static gboolean
test_log_attrs (const GtkTextIter *iter,
TestLogAttrFunc func)
{
gchar *paragraph;
gint char_len;
const PangoLogAttr *attrs;
int offset;
@ -2493,25 +2544,26 @@ test_log_attrs (const GtkTextIter *iter,
static gboolean
find_line_log_attrs (const GtkTextIter *iter,
FindLogAttrFunc func,
gint *found_offset)
gint *found_offset,
gboolean already_moved_initially)
{
gchar *paragraph;
gint char_len;
const PangoLogAttr *attrs;
int offset;
gboolean result = FALSE;
g_return_val_if_fail (iter != NULL, FALSE);
attrs = _gtk_text_buffer_get_line_log_attrs (gtk_text_iter_get_buffer (iter),
iter, &char_len);
iter, &char_len);
offset = gtk_text_iter_get_line_offset (iter);
g_assert (char_len > 0);
if (offset < char_len)
result = (* func) (attrs, offset, 0, char_len, found_offset);
result = (* func) (attrs, offset, 0, char_len, found_offset,
already_moved_initially);
return result;
}
@ -2520,7 +2572,8 @@ find_line_log_attrs (const GtkTextIter *iter,
static gboolean
find_by_log_attrs (GtkTextIter *iter,
FindLogAttrFunc func,
gboolean forward)
gboolean forward,
gboolean already_moved_initially)
{
GtkTextIter orig;
gint offset = 0;
@ -2529,22 +2582,27 @@ find_by_log_attrs (GtkTextIter *iter,
g_return_val_if_fail (iter != NULL, FALSE);
orig = *iter;
found = find_line_log_attrs (iter, func, &offset);
found = find_line_log_attrs (iter, func, &offset, already_moved_initially);
if (!found)
{
if (forward)
{
if (gtk_text_iter_forward_line (iter))
return find_by_log_attrs (iter, func, forward);
return find_by_log_attrs (iter, func, forward,
TRUE);
else
return FALSE;
}
else
{
if (gtk_text_iter_backward_line (iter))
return find_by_log_attrs (iter, func, forward);
{
/* go to end of previous line */
gtk_text_iter_set_line_offset (iter, 0);
if (gtk_text_iter_backward_char (iter))
return find_by_log_attrs (iter, func, forward,
TRUE);
else
return FALSE;
}
@ -2562,13 +2620,13 @@ find_by_log_attrs (GtkTextIter *iter,
gboolean
gtk_text_iter_forward_word_end (GtkTextIter *iter)
{
return find_by_log_attrs (iter, find_word_end_func, TRUE);
return find_by_log_attrs (iter, find_word_end_func, TRUE, FALSE);
}
gboolean
gtk_text_iter_backward_word_start (GtkTextIter *iter)
{
return find_by_log_attrs (iter, find_word_start_func, FALSE);
return find_by_log_attrs (iter, find_word_start_func, FALSE, FALSE);
}
/* FIXME a loop around a truly slow function means
@ -2645,9 +2703,11 @@ find_forward_cursor_pos_func (const PangoLogAttr *attrs,
gint offset,
gint min_offset,
gint len,
gint *found_offset)
gint *found_offset,
gboolean already_moved_initially)
{
++offset; /* We always go to the NEXT position */
if (!already_moved_initially)
++offset;
while (offset < (min_offset + len) &&
!attrs[offset].is_cursor_position)
@ -2663,16 +2723,18 @@ find_backward_cursor_pos_func (const PangoLogAttr *attrs,
gint offset,
gint min_offset,
gint len,
gint *found_offset)
gint *found_offset,
gboolean already_moved_initially)
{
--offset; /* We always go to the NEXT position */
if (!already_moved_initially)
--offset;
while (offset > min_offset &&
!attrs[offset].is_cursor_position)
--offset;
*found_offset = offset;
return offset >= min_offset;
}
@ -2688,13 +2750,13 @@ is_cursor_pos_func (const PangoLogAttr *attrs,
gboolean
gtk_text_iter_forward_cursor_position (GtkTextIter *iter)
{
return find_by_log_attrs (iter, find_forward_cursor_pos_func, TRUE);
return find_by_log_attrs (iter, find_forward_cursor_pos_func, TRUE, FALSE);
}
gboolean
gtk_text_iter_backward_cursor_position (GtkTextIter *iter)
{
return find_by_log_attrs (iter, find_backward_cursor_pos_func, FALSE);
return find_by_log_attrs (iter, find_backward_cursor_pos_func, FALSE, FALSE);
}
gboolean
@ -2755,20 +2817,28 @@ gtk_text_iter_is_cursor_position (const GtkTextIter *iter)
void
gtk_text_iter_set_line_offset (GtkTextIter *iter,
gint char_on_line)
gint char_on_line)
{
GtkTextRealIter *real;
gint chars_in_line;
g_return_if_fail (iter != NULL);
real = gtk_text_iter_make_surreal (iter);
if (real == NULL)
return;
check_invariants (iter);
iter_set_from_char_offset (real, real->line, char_on_line);
chars_in_line = gtk_text_iter_get_chars_in_line (iter);
g_return_if_fail (char_on_line <= chars_in_line);
if (char_on_line < chars_in_line)
iter_set_from_char_offset (real, real->line, char_on_line);
else
gtk_text_iter_forward_line (iter); /* set to start of next line */
check_invariants (iter);
}
@ -2778,7 +2848,8 @@ gtk_text_iter_set_line_index (GtkTextIter *iter,
gint byte_on_line)
{
GtkTextRealIter *real;
gint bytes_in_line;
g_return_if_fail (iter != NULL);
real = gtk_text_iter_make_surreal (iter);
@ -2788,7 +2859,14 @@ gtk_text_iter_set_line_index (GtkTextIter *iter,
check_invariants (iter);
iter_set_from_byte_offset (real, real->line, byte_on_line);
bytes_in_line = gtk_text_iter_get_bytes_in_line (iter);
g_return_if_fail (byte_on_line <= bytes_in_line);
if (byte_on_line < bytes_in_line)
iter_set_from_byte_offset (real, real->line, byte_on_line);
else
gtk_text_iter_forward_line (iter);
if (real->segment->type == &gtk_text_char_type &&
(real->segment->body.chars[real->segment_byte_offset] & 0xc0) == 0x80)
@ -2849,9 +2927,9 @@ gtk_text_iter_set_offset (GtkTextIter *iter, gint char_index)
return;
line = _gtk_text_btree_get_line_at_char (real->tree,
char_index,
&line_start,
&real_char_index);
char_index,
&line_start,
&real_char_index);
iter_set_from_char_offset (real, line, real_char_index - line_start);
@ -2886,7 +2964,9 @@ gtk_text_iter_forward_to_end (GtkTextIter *iter)
* Moves the iterator to point to the paragraph delimiter characters,
* which will be either a newline, a carriage return, a carriage
* return/newline in sequence, or the Unicode paragraph separator
* character.
* character. If the iterator is already at the paragraph delimiter
* characters, moves to the paragraph delimiter characters for the
* next line.
*
* Return value: %TRUE if we moved and the new location is not the end iterator
**/
@ -2899,6 +2979,7 @@ gtk_text_iter_forward_to_delimiters (GtkTextIter *iter)
g_return_val_if_fail (iter != NULL, FALSE);
current_offset = gtk_text_iter_get_line_offset (iter);
/* FIXME assumption that line ends in a newline; broken */
new_offset = gtk_text_iter_get_chars_in_line (iter) - 1;
if (current_offset < new_offset)
@ -3955,8 +4036,8 @@ gtk_text_iter_reorder (GtkTextIter *first,
void
_gtk_text_btree_get_iter_at_char (GtkTextBTree *tree,
GtkTextIter *iter,
gint char_index)
GtkTextIter *iter,
gint char_index)
{
GtkTextRealIter *real = (GtkTextRealIter*)iter;
gint real_char_index;
@ -3978,9 +4059,9 @@ _gtk_text_btree_get_iter_at_char (GtkTextBTree *tree,
void
_gtk_text_btree_get_iter_at_line_char (GtkTextBTree *tree,
GtkTextIter *iter,
gint line_number,
gint char_on_line)
GtkTextIter *iter,
gint line_number,
gint char_on_line)
{
GtkTextRealIter *real = (GtkTextRealIter*)iter;
GtkTextLine *line;
@ -3990,7 +4071,7 @@ _gtk_text_btree_get_iter_at_line_char (GtkTextBTree *tree,
g_return_if_fail (tree != NULL);
line = _gtk_text_btree_get_line (tree, line_number, &real_line);
iter_init_from_char_offset (iter, tree, line, char_on_line);
/* We might as well cache this, since we know it. */
@ -4001,9 +4082,9 @@ _gtk_text_btree_get_iter_at_line_char (GtkTextBTree *tree,
void
_gtk_text_btree_get_iter_at_line_byte (GtkTextBTree *tree,
GtkTextIter *iter,
gint line_number,
gint byte_index)
GtkTextIter *iter,
gint line_number,
gint byte_index)
{
GtkTextRealIter *real = (GtkTextRealIter*)iter;
GtkTextLine *line;
@ -4031,9 +4112,9 @@ _gtk_text_btree_get_iter_at_line_byte (GtkTextBTree *tree,
void
_gtk_text_btree_get_iter_at_line (GtkTextBTree *tree,
GtkTextIter *iter,
GtkTextLine *line,
gint byte_offset)
GtkTextIter *iter,
GtkTextLine *line,
gint byte_offset)
{
g_return_if_fail (iter != NULL);
g_return_if_fail (tree != NULL);
@ -4253,8 +4334,8 @@ gtk_text_iter_check (const GtkTextIter *iter)
if (real->line_byte_offset >= 0)
{
_gtk_text_line_byte_locate (real->line, real->line_byte_offset,
&byte_segment, &byte_any_segment,
&seg_byte_offset, &line_byte_offset);
&byte_segment, &byte_any_segment,
&seg_byte_offset, &line_byte_offset);
if (line_byte_offset != real->line_byte_offset)
g_error ("wrong byte offset was stored in iterator");
@ -4284,8 +4365,8 @@ gtk_text_iter_check (const GtkTextIter *iter)
if (real->line_char_offset >= 0)
{
_gtk_text_line_char_locate (real->line, real->line_char_offset,
&char_segment, &char_any_segment,
&seg_char_offset, &line_char_offset);
&char_segment, &char_any_segment,
&seg_char_offset, &line_char_offset);
if (line_char_offset != real->line_char_offset)
g_error ("wrong char offset was stored in iterator");

View File

@ -133,6 +133,7 @@ gboolean gtk_text_iter_ends_line (const GtkTextIter *iter);
gboolean gtk_text_iter_is_cursor_position (const GtkTextIter *iter);
gint gtk_text_iter_get_chars_in_line (const GtkTextIter *iter);
gint gtk_text_iter_get_bytes_in_line (const GtkTextIter *iter);
gboolean gtk_text_iter_get_attributes (const GtkTextIter *iter,
GtkTextAttributes *values);

View File

@ -1136,25 +1136,179 @@ gtk_text_view_scroll_to_mark_adjusted (GtkTextView *text_view,
* gtk_text_view_scroll_to_mark:
* @text_view: a #GtkTextView
* @mark: a #GtkTextMark
* @mark_within_margin: a margin
* @within_margin: margin as a [0.0,0.5) fraction of screen size
* @use_align: whether to use alignment arguments (if %FALSE, just get the mark onscreen)
* @xalign: horizontal alignment of mark within visible area.
* @yalign: vertical alignment of mark within visible area
*
* Scrolls @text_view so that @mark is on the screen. If
* @mark_within_margin is nonzero, the mark will be moved onscreen by
* that many pixels. For example, if @mark_within_margin is 5, the
* mark will be at least 5 pixels away from the edge of the screen,
* if possible.
* Scrolls @text_view so that @mark is on the screen in the position
* indicated by @xalign and @yalign. An alignment of 0.0 indicates
* left or top, 1.0 indicates right or bottom, 0.5 means center. If @use_align
* is %FALSE, the text scrolls the minimal distance to get the mark onscreen,
* possibly not scrolling at all. The effective screen for purposes
* of this function is reduced by a margin of size @within_margin.
*
* Return value: TRUE if scrolling occurred
* Return value: %TRUE if scrolling occurred
**/
gboolean
gtk_text_view_scroll_to_mark (GtkTextView *text_view,
GtkTextMark *mark,
gint mark_within_margin)
gdouble within_margin,
gboolean use_align,
gdouble xalign,
gdouble yalign)
{
g_return_val_if_fail (mark_within_margin >= 0, FALSE);
GtkTextIter iter;
GdkRectangle rect;
GdkRectangle screen;
gint screen_bottom;
gint screen_right;
gint scroll_dest;
GtkWidget *widget;
gboolean retval = FALSE;
gint scroll_inc;
gint screen_xoffset, screen_yoffset;
gint current_x_scroll, current_y_scroll;
return gtk_text_view_scroll_to_mark_adjusted (text_view, mark,
mark_within_margin, 1.0);
g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), FALSE);
g_return_val_if_fail (GTK_IS_TEXT_MARK (mark), FALSE);
g_return_val_if_fail (within_margin >= 0.0 && within_margin < 0.5, FALSE);
g_return_val_if_fail (xalign >= 0.0 && xalign <= 1.0, FALSE);
g_return_val_if_fail (yalign >= 0.0 && yalign <= 1.0, FALSE);
widget = GTK_WIDGET (text_view);
if (!GTK_WIDGET_MAPPED (widget))
{
g_warning ("FIXME need to implement scroll_to_mark for unmapped GtkTextView?");
return FALSE;
}
gtk_text_buffer_get_iter_at_mark (get_buffer (text_view), &iter, mark);
gtk_text_layout_get_iter_location (text_view->layout,
&iter,
&rect);
/* Be sure the scroll region is up-to-date */
gtk_text_view_scroll_calc_now (text_view);
current_x_scroll = text_view->xoffset;
current_y_scroll = text_view->yoffset;
screen.x = current_x_scroll;
screen.y = current_y_scroll;
screen.width = SCREEN_WIDTH (widget);
screen.height = SCREEN_HEIGHT (widget);
screen_xoffset = screen.width * within_margin;
screen_yoffset = screen.height * within_margin;
screen.x += screen_xoffset;
screen.y += screen_yoffset;
screen.width -= screen_xoffset * 2;
screen.height -= screen_yoffset * 2;
/* paranoia check */
if (screen.width < 1)
screen.width = 1;
if (screen.height < 1)
screen.height = 1;
screen_right = screen.x + screen.width;
screen_bottom = screen.y + screen.height;
/* The alignment affects the point in the target character that we
* choose to align. If we're doing right/bottom alignment, we align
* the right/bottom edge of the character the mark is at; if we're
* doing left/top we align the left/top edge of the character; if
* we're doing center alignment we align the center of the
* character.
*/
/* Vertical scroll */
scroll_inc = 0;
scroll_dest = current_y_scroll;
if (use_align)
{
scroll_dest = rect.y + (rect.height * yalign) - (screen.height * yalign);
/* if scroll_dest < screen.y, we move a negative increment (up),
* else a positive increment (down)
*/
scroll_inc = scroll_dest - screen.y + screen_yoffset;
}
else
{
/* move minimum to get onscreen */
if (rect.y < screen.y)
{
scroll_dest = rect.y;
scroll_inc = scroll_dest - screen.y - screen_yoffset;
}
else if ((rect.y + rect.height) > screen_bottom)
{
scroll_dest = rect.y + rect.height;
scroll_inc = scroll_dest - screen_bottom + screen_yoffset;
}
}
if (scroll_inc != 0)
{
set_adjustment_clamped (get_vadjustment (text_view),
current_y_scroll + scroll_inc);
retval = TRUE;
}
/* Horizontal scroll */
scroll_inc = 0;
scroll_dest = current_x_scroll;
if (use_align)
{
scroll_dest = rect.x + (rect.width * xalign) - (screen.width * xalign);
/* if scroll_dest < screen.y, we move a negative increment (left),
* else a positive increment (right)
*/
scroll_inc = scroll_dest - screen.x + screen_xoffset;
}
else
{
/* move minimum to get onscreen */
if (rect.x < screen.x)
{
scroll_dest = rect.x;
scroll_inc = scroll_dest - screen.x - screen_xoffset;
}
else if ((rect.x + rect.width) > screen_right)
{
scroll_dest = rect.x + rect.width;
scroll_inc = scroll_dest - screen_right + screen_xoffset;
}
}
if (scroll_inc != 0)
{
set_adjustment_clamped (get_hadjustment (text_view),
current_x_scroll + scroll_inc);
retval = TRUE;
}
return retval;
}
gboolean
gtk_text_view_scroll_mark_onscreen (GtkTextView *text_view,
GtkTextMark *mark)
{
g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), FALSE);
g_return_val_if_fail (GTK_IS_TEXT_MARK (mark), FALSE);
return gtk_text_view_scroll_to_mark (text_view, mark, 0.0, FALSE, 0.0, 0.0);
}
static gboolean
@ -1176,7 +1330,7 @@ clamp_iter_onscreen (GtkTextView *text_view, GtkTextIter *iter)
* Moves a mark within the buffer so that it's
* located within the currently-visible text area.
*
* Return value: %TRUE if scrolling occurred
* Return value: %TRUE if the mark moved (wasn't already onscreen)
**/
gboolean
gtk_text_view_move_mark_onscreen (GtkTextView *text_view,
@ -2533,7 +2687,7 @@ gtk_text_view_key_press_event (GtkWidget *widget, GdkEventKey *event)
gtk_text_view_scroll_to_mark (text_view,
gtk_text_buffer_get_mark (get_buffer (text_view),
"insert"),
0);
0.0, FALSE, 0.0, 0.0);
retval = TRUE;
}
/* Pass through Tab as literal tab, unless Control is held down */
@ -2541,10 +2695,9 @@ gtk_text_view_key_press_event (GtkWidget *widget, GdkEventKey *event)
{
gtk_text_buffer_insert_interactive_at_cursor (get_buffer (text_view), "\t", 1,
text_view->editable);
gtk_text_view_scroll_to_mark (text_view,
gtk_text_buffer_get_mark (get_buffer (text_view),
"insert"),
0);
gtk_text_view_scroll_mark_onscreen (text_view,
gtk_text_buffer_get_mark (get_buffer (text_view),
"insert"));
retval = TRUE;
}
else
@ -3190,9 +3343,9 @@ gtk_text_view_move_cursor (GtkTextView *text_view,
else
gtk_text_buffer_place_cursor (get_buffer (text_view), &newplace);
gtk_text_view_scroll_to_mark (text_view,
gtk_text_buffer_get_mark (get_buffer (text_view),
"insert"), 0);
gtk_text_view_scroll_mark_onscreen (text_view,
gtk_text_buffer_get_mark (get_buffer (text_view),
"insert"));
if (step == GTK_MOVEMENT_DISPLAY_LINES)
{
@ -3265,10 +3418,9 @@ gtk_text_view_scroll_pages (GtkTextView *text_view,
/* Adjust to have the cursor _entirely_ onscreen, move_mark_onscreen
* only guarantees 1 pixel onscreen.
*/
gtk_text_view_scroll_to_mark (text_view,
gtk_text_buffer_get_mark (get_buffer (text_view),
"insert"),
0);
gtk_text_view_scroll_mark_onscreen (text_view,
gtk_text_buffer_get_mark (get_buffer (text_view),
"insert"));
}
static gboolean
@ -3308,8 +3460,8 @@ gtk_text_view_insert_at_cursor (GtkTextView *text_view,
static void
gtk_text_view_delete_from_cursor (GtkTextView *text_view,
GtkDeleteType type,
gint count)
GtkDeleteType type,
gint count)
{
GtkTextIter insert;
GtkTextIter start;
@ -3423,9 +3575,8 @@ gtk_text_view_delete_from_cursor (GtkTextView *text_view,
gtk_text_buffer_end_user_action (get_buffer (text_view));
gtk_text_view_scroll_to_mark (text_view,
gtk_text_buffer_get_mark (get_buffer (text_view), "insert"),
0);
gtk_text_view_scroll_mark_onscreen (text_view,
gtk_text_buffer_get_mark (get_buffer (text_view), "insert"));
}
}
@ -3433,30 +3584,27 @@ static void
gtk_text_view_cut_clipboard (GtkTextView *text_view)
{
gtk_text_buffer_cut_clipboard (get_buffer (text_view), text_view->editable);
gtk_text_view_scroll_to_mark (text_view,
gtk_text_buffer_get_mark (get_buffer (text_view),
"insert"),
0);
gtk_text_view_scroll_mark_onscreen (text_view,
gtk_text_buffer_get_mark (get_buffer (text_view),
"insert"));
}
static void
gtk_text_view_copy_clipboard (GtkTextView *text_view)
{
gtk_text_buffer_copy_clipboard (get_buffer (text_view));
gtk_text_view_scroll_to_mark (text_view,
gtk_text_buffer_get_mark (get_buffer (text_view),
"insert"),
0);
gtk_text_view_scroll_mark_onscreen (text_view,
gtk_text_buffer_get_mark (get_buffer (text_view),
"insert"));
}
static void
gtk_text_view_paste_clipboard (GtkTextView *text_view)
{
gtk_text_buffer_paste_clipboard (get_buffer (text_view), text_view->editable);
gtk_text_view_scroll_to_mark (text_view,
gtk_text_buffer_get_mark (get_buffer (text_view),
"insert"),
0);
gtk_text_view_scroll_mark_onscreen (text_view,
gtk_text_buffer_get_mark (get_buffer (text_view),
"insert"));
}
static void
@ -3486,86 +3634,31 @@ gtk_text_view_unselect (GtkTextView *text_view)
}
static gboolean
move_insert_to_pointer_and_scroll (GtkTextView *text_view, gboolean partial_scroll)
move_mark_to_pointer_and_scroll (GtkTextView *text_view,
const gchar *mark_name)
{
gint x, y;
GdkModifierType state;
GtkTextIter newplace;
gint adjust = 0;
gboolean in_threshold = FALSE;
gdk_window_get_pointer (text_view->text_window->bin_window,
&x, &y, &state);
/* Adjust movement by how long we've been selecting, to
get an acceleration effect. The exact numbers are
pretty arbitrary. We have a threshold before we
start to accelerate. */
/* uncommenting this printf helps visualize how it works. */
/* printf ("%d\n", text_view->scrolling_accel_factor); */
if (text_view->scrolling_accel_factor > 10)
adjust = (text_view->scrolling_accel_factor - 10) * 75;
if (y < 0) /* scrolling upward */
adjust = -adjust;
/* No adjust if the pointer has moved back inside the window for sure.
Also I'm adding a small threshold where no adjust is added,
in case you want to do a continuous slow scroll. */
#define SLOW_SCROLL_TH 7
if (x >= (0 - SLOW_SCROLL_TH) &&
x < (SCREEN_WIDTH (text_view) + SLOW_SCROLL_TH) &&
y >= (0 - SLOW_SCROLL_TH) &&
y < (SCREEN_HEIGHT (text_view) + SLOW_SCROLL_TH))
{
adjust = 0;
in_threshold = TRUE;
}
gtk_text_layout_get_iter_at_pixel (text_view->layout,
&newplace,
x + text_view->xoffset,
y + text_view->yoffset + adjust);
y + text_view->yoffset);
{
gboolean scrolled = FALSE;
GtkTextMark *insert_mark =
gtk_text_buffer_get_mark (get_buffer (text_view), "insert");
GtkTextMark *mark =
gtk_text_buffer_get_mark (get_buffer (text_view), mark_name);
gtk_text_buffer_move_mark (get_buffer (text_view),
insert_mark,
mark,
&newplace);
if (partial_scroll)
scrolled = gtk_text_view_scroll_to_mark_adjusted (text_view, insert_mark, 0, 0.7);
else
scrolled = gtk_text_view_scroll_to_mark_adjusted (text_view, insert_mark, 0, 1.0);
if (scrolled)
{
/* We want to avoid rapid jump to super-accelerated when you
leave the slow scroll threshold after scrolling for a
while. So we slowly decrease accel when scrolling inside
the threshold.
*/
if (in_threshold)
{
if (text_view->scrolling_accel_factor > 1)
text_view->scrolling_accel_factor -= 2;
}
else
text_view->scrolling_accel_factor += 1;
}
else
{
/* If we don't scroll we're probably inside the window, but
potentially just a bit outside. We decrease acceleration
while the user is fooling around inside the window.
Acceleration decreases faster than it increases. */
if (text_view->scrolling_accel_factor > 4)
text_view->scrolling_accel_factor -= 5;
}
scrolled = gtk_text_view_scroll_mark_onscreen (text_view, mark);
return scrolled;
}
@ -3578,32 +3671,57 @@ selection_scan_timeout (gpointer data)
text_view = GTK_TEXT_VIEW (data);
if (move_insert_to_pointer_and_scroll (text_view, TRUE))
{
return TRUE; /* remain installed. */
}
else
{
text_view->selection_drag_scan_timeout = 0;
return FALSE; /* remove ourselves */
}
move_mark_to_pointer_and_scroll (text_view, "insert");
return TRUE; /* remain installed. */
}
#define DND_SCROLL_MARGIN 0.20
static gint
drag_scan_timeout (gpointer data)
{
GtkTextView *text_view;
gint x, y;
GdkModifierType state;
GtkTextIter newplace;
text_view = GTK_TEXT_VIEW (data);
gdk_window_get_pointer (text_view->text_window->bin_window,
&x, &y, &state);
gtk_text_layout_get_iter_at_pixel (text_view->layout,
&newplace,
x + text_view->xoffset,
y + text_view->yoffset);
gtk_text_buffer_move_mark (get_buffer (text_view),
text_view->dnd_mark,
&newplace);
gtk_text_view_scroll_to_mark (text_view,
text_view->dnd_mark,
DND_SCROLL_MARGIN, FALSE, 0.0, 0.0);
return TRUE;
}
static gint
selection_motion_event_handler (GtkTextView *text_view, GdkEventMotion *event, gpointer data)
{
if (move_insert_to_pointer_and_scroll (text_view, TRUE))
{
/* If we had to scroll offscreen, insert a timeout to do so
again. Note that in the timeout, even if the mouse doesn't
move, due to this scroll xoffset/yoffset will have changed
and we'll need to scroll again. */
if (text_view->selection_drag_scan_timeout != 0) /* reset on every motion event */
gtk_timeout_remove (text_view->selection_drag_scan_timeout);
move_mark_to_pointer_and_scroll (text_view, "insert");
text_view->selection_drag_scan_timeout =
gtk_timeout_add (50, selection_scan_timeout, text_view);
}
/* If we had to scroll offscreen, insert a timeout to do so
* again. Note that in the timeout, even if the mouse doesn't
* move, due to this scroll xoffset/yoffset will have changed
* and we'll need to scroll again.
*/
if (text_view->scroll_timeout != 0) /* reset on every motion event */
gtk_timeout_remove (text_view->scroll_timeout);
text_view->scroll_timeout =
gtk_timeout_add (50, selection_scan_timeout, text_view);
return TRUE;
}
@ -3619,8 +3737,6 @@ gtk_text_view_start_selection_drag (GtkTextView *text_view,
gtk_grab_add (GTK_WIDGET (text_view));
text_view->scrolling_accel_factor = 0;
newplace = *iter;
gtk_text_buffer_place_cursor (get_buffer (text_view), &newplace);
@ -3641,16 +3757,14 @@ gtk_text_view_end_selection_drag (GtkTextView *text_view, GdkEventButton *event)
gtk_signal_disconnect (GTK_OBJECT (text_view), text_view->selection_drag_handler);
text_view->selection_drag_handler = 0;
text_view->scrolling_accel_factor = 0;
if (text_view->selection_drag_scan_timeout != 0)
if (text_view->scroll_timeout != 0)
{
gtk_timeout_remove (text_view->selection_drag_scan_timeout);
text_view->selection_drag_scan_timeout = 0;
gtk_timeout_remove (text_view->scroll_timeout);
text_view->scroll_timeout = 0;
}
/* one last update to current position */
move_insert_to_pointer_and_scroll (text_view, FALSE);
move_mark_to_pointer_and_scroll (text_view, "insert");
gtk_grab_remove (GTK_WIDGET (text_view));
@ -3869,7 +3983,7 @@ gtk_text_view_reset_im_context (GtkTextView *text_view)
{
if (text_view->need_im_reset)
{
text_view->need_im_reset = 0;
text_view->need_im_reset = FALSE;
gtk_im_context_reset (text_view->im_context);
}
}
@ -3921,8 +4035,14 @@ gtk_text_view_drag_end (GtkWidget *widget,
GtkTextView *text_view;
text_view = GTK_TEXT_VIEW (widget);
gtk_text_mark_set_visible (text_view->dnd_mark, FALSE);
if (text_view->scroll_timeout != 0)
{
gtk_timeout_remove (text_view->scroll_timeout);
text_view->scroll_timeout = 0;
}
}
static void
@ -3986,8 +4106,16 @@ gtk_text_view_drag_leave (GtkWidget *widget,
GdkDragContext *context,
guint time)
{
GtkTextView *text_view;
text_view = GTK_TEXT_VIEW (widget);
gtk_text_mark_set_visible (text_view->dnd_mark, FALSE);
if (text_view->scroll_timeout != 0)
gtk_timeout_remove (text_view->scroll_timeout);
text_view->scroll_timeout = 0;
}
static gboolean
@ -4003,11 +4131,12 @@ gtk_text_view_drag_motion (GtkWidget *widget,
GtkTextIter end;
GdkRectangle target_rect;
gint bx, by;
gboolean scrolled;
text_view = GTK_TEXT_VIEW (widget);
target_rect = text_view->text_window->allocation;
if (x < target_rect.x ||
y < target_rect.y ||
x > (target_rect.x + target_rect.width) ||
@ -4065,25 +4194,19 @@ gtk_text_view_drag_motion (GtkWidget *widget,
}
gtk_text_buffer_move_mark (get_buffer (text_view),
gtk_text_buffer_get_mark (get_buffer (text_view),
"gtk_drag_target"),
text_view->dnd_mark,
&newplace);
{
/* The effect of this is that the text scrolls if you're near
the edge. We have to scroll whether or not we're inside
the selection. */
gint margin;
margin = MIN (SCREEN_WIDTH (widget), SCREEN_HEIGHT (widget));
margin /= 5;
gtk_text_view_scroll_to_mark_adjusted (text_view,
gtk_text_buffer_get_mark (get_buffer (text_view),
"gtk_drag_target"),
margin, 1.0);
}
scrolled = gtk_text_view_scroll_to_mark (text_view,
text_view->dnd_mark,
DND_SCROLL_MARGIN, FALSE, 0.0, 0.0);
if (text_view->scroll_timeout != 0) /* reset on every motion event */
gtk_timeout_remove (text_view->scroll_timeout);
text_view->scroll_timeout =
gtk_timeout_add (50, drag_scan_timeout, text_view);
return TRUE;
}
@ -4360,10 +4483,9 @@ gtk_text_view_commit_handler (GtkIMContext *context,
gtk_text_buffer_end_user_action (get_buffer (text_view));
gtk_text_view_scroll_to_mark (text_view,
gtk_text_buffer_get_mark (get_buffer (text_view),
"insert"),
0);
gtk_text_view_scroll_mark_onscreen (text_view,
gtk_text_buffer_get_mark (get_buffer (text_view),
"insert"));
}
static void

View File

@ -67,8 +67,7 @@ struct _GtkTextView
GtkTextBuffer *buffer;
guint selection_drag_handler;
guint selection_drag_scan_timeout;
gint scrolling_accel_factor;
guint scroll_timeout;
/* Default style settings */
gint pixels_above_lines;
@ -175,7 +174,12 @@ void gtk_text_view_set_buffer (GtkTextView *text_view,
GtkTextBuffer *gtk_text_view_get_buffer (GtkTextView *text_view);
gboolean gtk_text_view_scroll_to_mark (GtkTextView *text_view,
GtkTextMark *mark,
gint mark_within_margin);
gdouble within_margin,
gboolean use_align,
gdouble xalign,
gdouble yalign);
gboolean gtk_text_view_scroll_mark_onscreen (GtkTextView *text_view,
GtkTextMark *mark);
gboolean gtk_text_view_move_mark_onscreen (GtkTextView *text_view,
GtkTextMark *mark);
gboolean gtk_text_view_place_cursor_onscreen (GtkTextView *text_view);

View File

@ -602,7 +602,7 @@ fill_buffer (GtkTextBuffer *buffer)
color.blue = color.green = 0;
color.red = 0xffff;
g_object_set (GTK_OBJECT (tag),
g_object_set (G_OBJECT (tag),
"rise", -4,
"foreground_gdk", &color,
NULL);

View File

@ -602,7 +602,7 @@ fill_buffer (GtkTextBuffer *buffer)
color.blue = color.green = 0;
color.red = 0xffff;
g_object_set (GTK_OBJECT (tag),
g_object_set (G_OBJECT (tag),
"rise", -4,
"foreground_gdk", &color,
NULL);