mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 10:50:10 +00:00
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:
parent
72cdcb6323
commit
7a958797e2
37
ChangeLog
37
ChangeLog
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,16 +3640,8 @@ _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;
|
||||
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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,9 +2544,9 @@ 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;
|
||||
@ -2511,7 +2562,8 @@ find_line_log_attrs (const GtkTextIter *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;
|
||||
@ -2530,21 +2583,26 @@ find_by_log_attrs (GtkTextIter *iter,
|
||||
|
||||
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,9 +2723,11 @@ 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)
|
||||
@ -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,9 +2817,10 @@ 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);
|
||||
|
||||
@ -2768,7 +2831,14 @@ gtk_text_iter_set_line_offset (GtkTextIter *iter,
|
||||
|
||||
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,6 +2848,7 @@ gtk_text_iter_set_line_index (GtkTextIter *iter,
|
||||
gint byte_on_line)
|
||||
{
|
||||
GtkTextRealIter *real;
|
||||
gint bytes_in_line;
|
||||
|
||||
g_return_if_fail (iter != NULL);
|
||||
|
||||
@ -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 == >k_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;
|
||||
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
@ -3923,6 +4037,12 @@ gtk_text_view_drag_end (GtkWidget *widget,
|
||||
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,6 +4131,7 @@ gtk_text_view_drag_motion (GtkWidget *widget,
|
||||
GtkTextIter end;
|
||||
GdkRectangle target_rect;
|
||||
gint bx, by;
|
||||
gboolean scrolled;
|
||||
|
||||
text_view = GTK_TEXT_VIEW (widget);
|
||||
|
||||
@ -4065,24 +4194,18 @@ 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;
|
||||
scrolled = gtk_text_view_scroll_to_mark (text_view,
|
||||
text_view->dnd_mark,
|
||||
DND_SCROLL_MARGIN, FALSE, 0.0, 0.0);
|
||||
|
||||
margin = MIN (SCREEN_WIDTH (widget), SCREEN_HEIGHT (widget));
|
||||
margin /= 5;
|
||||
if (text_view->scroll_timeout != 0) /* reset on every motion event */
|
||||
gtk_timeout_remove (text_view->scroll_timeout);
|
||||
|
||||
gtk_text_view_scroll_to_mark_adjusted (text_view,
|
||||
gtk_text_buffer_get_mark (get_buffer (text_view),
|
||||
"gtk_drag_target"),
|
||||
margin, 1.0);
|
||||
}
|
||||
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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user