handle 0-height empty/invisible lines.
2001-04-21 Havoc Pennington <hp@pobox.com> * gtk/gtktextdisplay.c (gtk_text_layout_draw): handle 0-height empty/invisible lines. * gtk/gtktextiter.c (gtk_text_iter_set_visible_line_offset) (gtk_text_iter_set_visible_line_index): new functions to set indexes excluding invisible text * gtk/gtktextlayout.c (line_display_iter_to_index): get visible index * gtk/gtktextiter.c (gtk_text_iter_get_visible_line_index) (gtk_text_iter_get_visible_line_offset): new functions to get indexes excluding invisible text * gtk/gtkmessagedialog.c (gtk_message_dialog_init): strip out a bunch of extra padding that served no purpose * gtk/gtkdialog.c: Make all the spacings configurable via style properties, for chubbiness configuration in themes * tests/testtext.c: fix path to the immodules.
This commit is contained in:
parent
60051ff670
commit
b84d2f1234
16 changed files with 584 additions and 104 deletions
24
ChangeLog
24
ChangeLog
|
|
@ -1,3 +1,27 @@
|
|||
2001-04-21 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* gtk/gtktextdisplay.c (gtk_text_layout_draw): handle 0-height
|
||||
empty/invisible lines.
|
||||
|
||||
* gtk/gtktextiter.c (gtk_text_iter_set_visible_line_offset)
|
||||
(gtk_text_iter_set_visible_line_index): new functions to set
|
||||
indexes excluding invisible text
|
||||
|
||||
* gtk/gtktextlayout.c (line_display_iter_to_index): get visible
|
||||
index
|
||||
|
||||
* gtk/gtktextiter.c (gtk_text_iter_get_visible_line_index)
|
||||
(gtk_text_iter_get_visible_line_offset): new functions to
|
||||
get indexes excluding invisible text
|
||||
|
||||
* gtk/gtkmessagedialog.c (gtk_message_dialog_init): strip out a
|
||||
bunch of extra padding that served no purpose
|
||||
|
||||
* gtk/gtkdialog.c: Make all the spacings configurable via style
|
||||
properties, for chubbiness configuration in themes
|
||||
|
||||
* tests/testtext.c: fix path to the immodules.
|
||||
|
||||
Mon Apr 23 18:57:03 2001 Jonathan Blandford <jrb@redhat.com>
|
||||
|
||||
* gtk/gtksocket.c (gtk_socket_filter_func): add missing '}' that
|
||||
|
|
|
|||
|
|
@ -1,3 +1,27 @@
|
|||
2001-04-21 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* gtk/gtktextdisplay.c (gtk_text_layout_draw): handle 0-height
|
||||
empty/invisible lines.
|
||||
|
||||
* gtk/gtktextiter.c (gtk_text_iter_set_visible_line_offset)
|
||||
(gtk_text_iter_set_visible_line_index): new functions to set
|
||||
indexes excluding invisible text
|
||||
|
||||
* gtk/gtktextlayout.c (line_display_iter_to_index): get visible
|
||||
index
|
||||
|
||||
* gtk/gtktextiter.c (gtk_text_iter_get_visible_line_index)
|
||||
(gtk_text_iter_get_visible_line_offset): new functions to
|
||||
get indexes excluding invisible text
|
||||
|
||||
* gtk/gtkmessagedialog.c (gtk_message_dialog_init): strip out a
|
||||
bunch of extra padding that served no purpose
|
||||
|
||||
* gtk/gtkdialog.c: Make all the spacings configurable via style
|
||||
properties, for chubbiness configuration in themes
|
||||
|
||||
* tests/testtext.c: fix path to the immodules.
|
||||
|
||||
Mon Apr 23 18:57:03 2001 Jonathan Blandford <jrb@redhat.com>
|
||||
|
||||
* gtk/gtksocket.c (gtk_socket_filter_func): add missing '}' that
|
||||
|
|
|
|||
|
|
@ -1,3 +1,27 @@
|
|||
2001-04-21 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* gtk/gtktextdisplay.c (gtk_text_layout_draw): handle 0-height
|
||||
empty/invisible lines.
|
||||
|
||||
* gtk/gtktextiter.c (gtk_text_iter_set_visible_line_offset)
|
||||
(gtk_text_iter_set_visible_line_index): new functions to set
|
||||
indexes excluding invisible text
|
||||
|
||||
* gtk/gtktextlayout.c (line_display_iter_to_index): get visible
|
||||
index
|
||||
|
||||
* gtk/gtktextiter.c (gtk_text_iter_get_visible_line_index)
|
||||
(gtk_text_iter_get_visible_line_offset): new functions to
|
||||
get indexes excluding invisible text
|
||||
|
||||
* gtk/gtkmessagedialog.c (gtk_message_dialog_init): strip out a
|
||||
bunch of extra padding that served no purpose
|
||||
|
||||
* gtk/gtkdialog.c: Make all the spacings configurable via style
|
||||
properties, for chubbiness configuration in themes
|
||||
|
||||
* tests/testtext.c: fix path to the immodules.
|
||||
|
||||
Mon Apr 23 18:57:03 2001 Jonathan Blandford <jrb@redhat.com>
|
||||
|
||||
* gtk/gtksocket.c (gtk_socket_filter_func): add missing '}' that
|
||||
|
|
|
|||
|
|
@ -1,3 +1,27 @@
|
|||
2001-04-21 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* gtk/gtktextdisplay.c (gtk_text_layout_draw): handle 0-height
|
||||
empty/invisible lines.
|
||||
|
||||
* gtk/gtktextiter.c (gtk_text_iter_set_visible_line_offset)
|
||||
(gtk_text_iter_set_visible_line_index): new functions to set
|
||||
indexes excluding invisible text
|
||||
|
||||
* gtk/gtktextlayout.c (line_display_iter_to_index): get visible
|
||||
index
|
||||
|
||||
* gtk/gtktextiter.c (gtk_text_iter_get_visible_line_index)
|
||||
(gtk_text_iter_get_visible_line_offset): new functions to
|
||||
get indexes excluding invisible text
|
||||
|
||||
* gtk/gtkmessagedialog.c (gtk_message_dialog_init): strip out a
|
||||
bunch of extra padding that served no purpose
|
||||
|
||||
* gtk/gtkdialog.c: Make all the spacings configurable via style
|
||||
properties, for chubbiness configuration in themes
|
||||
|
||||
* tests/testtext.c: fix path to the immodules.
|
||||
|
||||
Mon Apr 23 18:57:03 2001 Jonathan Blandford <jrb@redhat.com>
|
||||
|
||||
* gtk/gtksocket.c (gtk_socket_filter_func): add missing '}' that
|
||||
|
|
|
|||
|
|
@ -1,3 +1,27 @@
|
|||
2001-04-21 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* gtk/gtktextdisplay.c (gtk_text_layout_draw): handle 0-height
|
||||
empty/invisible lines.
|
||||
|
||||
* gtk/gtktextiter.c (gtk_text_iter_set_visible_line_offset)
|
||||
(gtk_text_iter_set_visible_line_index): new functions to set
|
||||
indexes excluding invisible text
|
||||
|
||||
* gtk/gtktextlayout.c (line_display_iter_to_index): get visible
|
||||
index
|
||||
|
||||
* gtk/gtktextiter.c (gtk_text_iter_get_visible_line_index)
|
||||
(gtk_text_iter_get_visible_line_offset): new functions to
|
||||
get indexes excluding invisible text
|
||||
|
||||
* gtk/gtkmessagedialog.c (gtk_message_dialog_init): strip out a
|
||||
bunch of extra padding that served no purpose
|
||||
|
||||
* gtk/gtkdialog.c: Make all the spacings configurable via style
|
||||
properties, for chubbiness configuration in themes
|
||||
|
||||
* tests/testtext.c: fix path to the immodules.
|
||||
|
||||
Mon Apr 23 18:57:03 2001 Jonathan Blandford <jrb@redhat.com>
|
||||
|
||||
* gtk/gtksocket.c (gtk_socket_filter_func): add missing '}' that
|
||||
|
|
|
|||
|
|
@ -1,3 +1,27 @@
|
|||
2001-04-21 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* gtk/gtktextdisplay.c (gtk_text_layout_draw): handle 0-height
|
||||
empty/invisible lines.
|
||||
|
||||
* gtk/gtktextiter.c (gtk_text_iter_set_visible_line_offset)
|
||||
(gtk_text_iter_set_visible_line_index): new functions to set
|
||||
indexes excluding invisible text
|
||||
|
||||
* gtk/gtktextlayout.c (line_display_iter_to_index): get visible
|
||||
index
|
||||
|
||||
* gtk/gtktextiter.c (gtk_text_iter_get_visible_line_index)
|
||||
(gtk_text_iter_get_visible_line_offset): new functions to
|
||||
get indexes excluding invisible text
|
||||
|
||||
* gtk/gtkmessagedialog.c (gtk_message_dialog_init): strip out a
|
||||
bunch of extra padding that served no purpose
|
||||
|
||||
* gtk/gtkdialog.c: Make all the spacings configurable via style
|
||||
properties, for chubbiness configuration in themes
|
||||
|
||||
* tests/testtext.c: fix path to the immodules.
|
||||
|
||||
Mon Apr 23 18:57:03 2001 Jonathan Blandford <jrb@redhat.com>
|
||||
|
||||
* gtk/gtksocket.c (gtk_socket_filter_func): add missing '}' that
|
||||
|
|
|
|||
|
|
@ -1,3 +1,27 @@
|
|||
2001-04-21 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* gtk/gtktextdisplay.c (gtk_text_layout_draw): handle 0-height
|
||||
empty/invisible lines.
|
||||
|
||||
* gtk/gtktextiter.c (gtk_text_iter_set_visible_line_offset)
|
||||
(gtk_text_iter_set_visible_line_index): new functions to set
|
||||
indexes excluding invisible text
|
||||
|
||||
* gtk/gtktextlayout.c (line_display_iter_to_index): get visible
|
||||
index
|
||||
|
||||
* gtk/gtktextiter.c (gtk_text_iter_get_visible_line_index)
|
||||
(gtk_text_iter_get_visible_line_offset): new functions to
|
||||
get indexes excluding invisible text
|
||||
|
||||
* gtk/gtkmessagedialog.c (gtk_message_dialog_init): strip out a
|
||||
bunch of extra padding that served no purpose
|
||||
|
||||
* gtk/gtkdialog.c: Make all the spacings configurable via style
|
||||
properties, for chubbiness configuration in themes
|
||||
|
||||
* tests/testtext.c: fix path to the immodules.
|
||||
|
||||
Mon Apr 23 18:57:03 2001 Jonathan Blandford <jrb@redhat.com>
|
||||
|
||||
* gtk/gtksocket.c (gtk_socket_filter_func): add missing '}' that
|
||||
|
|
|
|||
|
|
@ -496,6 +496,7 @@ This can later be composited together with other
|
|||
#GtkRcStyle structures to form a #GtkStyle.
|
||||
</para>
|
||||
|
||||
@parent_instance:
|
||||
@name:
|
||||
@bg_pixmap_name:
|
||||
@font_desc:
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@ static void gtk_dialog_get_property (GObject *object,
|
|||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gtk_dialog_style_set (GtkWidget *widget,
|
||||
GtkStyle *prev_style);
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
|
|
@ -111,7 +113,8 @@ gtk_dialog_class_init (GtkDialogClass *class)
|
|||
gobject_class->get_property = gtk_dialog_get_property;
|
||||
|
||||
widget_class->key_press_event = gtk_dialog_key_press;
|
||||
|
||||
widget_class->style_set = gtk_dialog_style_set;
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_HAS_SEPARATOR,
|
||||
g_param_spec_boolean ("has_separator",
|
||||
|
|
@ -128,6 +131,59 @@ gtk_dialog_class_init (GtkDialogClass *class)
|
|||
gtk_marshal_NONE__INT,
|
||||
GTK_TYPE_NONE, 1,
|
||||
GTK_TYPE_INT);
|
||||
|
||||
gtk_widget_class_install_style_property (widget_class,
|
||||
g_param_spec_int ("content_area_border",
|
||||
_("Content area border"),
|
||||
_("Width of border around the main dialog area"),
|
||||
0,
|
||||
G_MAXINT,
|
||||
2,
|
||||
G_PARAM_READABLE));
|
||||
gtk_widget_class_install_style_property (widget_class,
|
||||
g_param_spec_int ("button_spacing",
|
||||
_("Button spacing"),
|
||||
_("Spacing between buttons"),
|
||||
0,
|
||||
G_MAXINT,
|
||||
1,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
gtk_widget_class_install_style_property (widget_class,
|
||||
g_param_spec_int ("action_area_border",
|
||||
_("Action area border"),
|
||||
_("Width of border around the button area at the bottom of the dialog"),
|
||||
0,
|
||||
G_MAXINT,
|
||||
0,
|
||||
G_PARAM_READABLE));
|
||||
}
|
||||
|
||||
static void
|
||||
update_spacings (GtkDialog *dialog)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
gint content_area_border;
|
||||
gint button_spacing;
|
||||
gint action_area_border;
|
||||
|
||||
widget = GTK_WIDGET (dialog);
|
||||
|
||||
gtk_widget_style_get (widget,
|
||||
"content_area_border",
|
||||
&content_area_border,
|
||||
"button_spacing",
|
||||
&button_spacing,
|
||||
"action_area_border",
|
||||
&action_area_border,
|
||||
NULL);
|
||||
|
||||
gtk_container_set_border_width (GTK_CONTAINER (dialog->vbox),
|
||||
content_area_border);
|
||||
gtk_box_set_spacing (GTK_BOX (dialog->action_area),
|
||||
button_spacing);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area),
|
||||
action_area_border);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -143,8 +199,6 @@ gtk_dialog_init (GtkDialog *dialog)
|
|||
NULL);
|
||||
|
||||
dialog->vbox = gtk_vbox_new (FALSE, 0);
|
||||
|
||||
gtk_container_set_border_width (GTK_CONTAINER (dialog->vbox), 2);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (dialog), dialog->vbox);
|
||||
gtk_widget_show (dialog->vbox);
|
||||
|
|
@ -152,11 +206,8 @@ gtk_dialog_init (GtkDialog *dialog)
|
|||
dialog->action_area = gtk_hbutton_box_new ();
|
||||
|
||||
gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog->action_area),
|
||||
GTK_BUTTONBOX_END);
|
||||
GTK_BUTTONBOX_END);
|
||||
|
||||
gtk_box_set_spacing (GTK_BOX (dialog->action_area), 5);
|
||||
|
||||
gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area), 5);
|
||||
gtk_box_pack_end (GTK_BOX (dialog->vbox), dialog->action_area,
|
||||
FALSE, TRUE, 0);
|
||||
gtk_widget_show (dialog->action_area);
|
||||
|
|
@ -252,6 +303,13 @@ gtk_dialog_key_press (GtkWidget *widget,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_dialog_style_set (GtkWidget *widget,
|
||||
GtkStyle *prev_style)
|
||||
{
|
||||
update_spacings (GTK_DIALOG (widget));
|
||||
}
|
||||
|
||||
GtkWidget*
|
||||
gtk_dialog_new (void)
|
||||
{
|
||||
|
|
@ -444,7 +502,7 @@ gtk_dialog_add_action_widget (GtkDialog *dialog,
|
|||
|
||||
gtk_box_pack_end (GTK_BOX (dialog->action_area),
|
||||
child,
|
||||
FALSE, TRUE, 5);
|
||||
FALSE, TRUE, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -30,10 +30,14 @@
|
|||
#include "gtkimage.h"
|
||||
#include "gtkstock.h"
|
||||
#include "gtkiconfactory.h"
|
||||
#include "gtkintl.h"
|
||||
|
||||
static void gtk_message_dialog_class_init (GtkMessageDialogClass *klass);
|
||||
static void gtk_message_dialog_init (GtkMessageDialog *dialog);
|
||||
static void gtk_message_dialog_style_set (GtkWidget *widget,
|
||||
GtkStyle *prev_style);
|
||||
|
||||
static gpointer parent_class;
|
||||
|
||||
GtkType
|
||||
gtk_message_dialog_get_type (void)
|
||||
|
|
@ -63,6 +67,22 @@ gtk_message_dialog_get_type (void)
|
|||
static void
|
||||
gtk_message_dialog_class_init (GtkMessageDialogClass *class)
|
||||
{
|
||||
GtkWidgetClass *widget_class;
|
||||
|
||||
widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
parent_class = g_type_class_peek_parent (class);
|
||||
|
||||
widget_class->style_set = gtk_message_dialog_style_set;
|
||||
|
||||
gtk_widget_class_install_style_property (widget_class,
|
||||
g_param_spec_int ("message_border",
|
||||
_("Image/label border"),
|
||||
_("Width of border around the label and image in the message dialog"),
|
||||
0,
|
||||
G_MAXINT,
|
||||
8,
|
||||
G_PARAM_READABLE));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -75,19 +95,17 @@ gtk_message_dialog_init (GtkMessageDialog *dialog)
|
|||
|
||||
gtk_label_set_line_wrap (GTK_LABEL (dialog->label), TRUE);
|
||||
|
||||
hbox = gtk_hbox_new (FALSE, 10);
|
||||
hbox = gtk_hbox_new (FALSE, 6);
|
||||
|
||||
gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (hbox), dialog->image,
|
||||
FALSE, FALSE, 2);
|
||||
FALSE, FALSE, 0);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (hbox), dialog->label,
|
||||
TRUE, TRUE, 2);
|
||||
TRUE, TRUE, 0);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
|
||||
hbox,
|
||||
FALSE, FALSE, 10);
|
||||
FALSE, FALSE, 0);
|
||||
|
||||
gtk_widget_show_all (hbox);
|
||||
}
|
||||
|
|
@ -247,3 +265,25 @@ gtk_message_dialog_new (GtkWindow *parent,
|
|||
|
||||
return widget;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_message_dialog_style_set (GtkWidget *widget,
|
||||
GtkStyle *prev_style)
|
||||
{
|
||||
GtkWidget *parent;
|
||||
gint border_width = 0;
|
||||
|
||||
parent = GTK_WIDGET (GTK_MESSAGE_DIALOG (widget)->image->parent);
|
||||
|
||||
if (parent)
|
||||
{
|
||||
gtk_widget_style_get (widget, "message_border",
|
||||
&border_width, NULL);
|
||||
|
||||
gtk_container_set_border_width (GTK_CONTAINER (parent),
|
||||
border_width);
|
||||
}
|
||||
|
||||
if (GTK_WIDGET_CLASS (parent_class)->style_set)
|
||||
(GTK_WIDGET_CLASS (parent_class)->style_set) (widget, prev_style);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -277,7 +277,8 @@ GtkTextTag *gtk_text_buffer_create_tag (GtkTextBuffer *buffer,
|
|||
...);
|
||||
|
||||
/* Obtain iterators pointed at various places, then you can move the
|
||||
iterator around using the GtkTextIter operators */
|
||||
* iterator around using the GtkTextIter operators
|
||||
*/
|
||||
void gtk_text_buffer_get_iter_at_line_offset (GtkTextBuffer *buffer,
|
||||
GtkTextIter *iter,
|
||||
gint line_number,
|
||||
|
|
|
|||
|
|
@ -739,66 +739,71 @@ gtk_text_layout_draw (GtkTextLayout *layout,
|
|||
GtkTextLine *line = tmp_list->data;
|
||||
|
||||
line_display = gtk_text_layout_get_line_display (layout, line, FALSE);
|
||||
|
||||
if (have_selection)
|
||||
|
||||
if (line_display->height > 0)
|
||||
{
|
||||
GtkTextIter line_start, line_end;
|
||||
gint byte_count;
|
||||
|
||||
gtk_text_layout_get_iter_at_line (layout,
|
||||
&line_start,
|
||||
line, 0);
|
||||
byte_count = gtk_text_iter_get_bytes_in_line (&line_start);
|
||||
g_assert (line_display->layout != NULL);
|
||||
|
||||
/* FIXME the -1 assumes a newline I think */
|
||||
gtk_text_layout_get_iter_at_line (layout,
|
||||
&line_end,
|
||||
line, byte_count - 1);
|
||||
|
||||
if (gtk_text_iter_compare (&selection_start, &line_end) < 0 &&
|
||||
gtk_text_iter_compare (&selection_end, &line_start) > 0)
|
||||
if (have_selection)
|
||||
{
|
||||
if (gtk_text_iter_compare (&selection_start, &line_start) >= 0)
|
||||
selection_start_index = gtk_text_iter_get_line_index (&selection_start);
|
||||
else
|
||||
selection_start_index = -1;
|
||||
GtkTextIter line_start, line_end;
|
||||
gint byte_count;
|
||||
|
||||
if (gtk_text_iter_compare (&selection_end, &line_end) <= 0)
|
||||
selection_end_index = gtk_text_iter_get_line_index (&selection_end);
|
||||
else
|
||||
selection_end_index = byte_count;
|
||||
gtk_text_layout_get_iter_at_line (layout,
|
||||
&line_start,
|
||||
line, 0);
|
||||
byte_count = gtk_text_iter_get_bytes_in_line (&line_start);
|
||||
|
||||
/* FIXME the -1 assumes a newline I think */
|
||||
gtk_text_layout_get_iter_at_line (layout,
|
||||
&line_end,
|
||||
line, byte_count - 1);
|
||||
|
||||
if (gtk_text_iter_compare (&selection_start, &line_end) < 0 &&
|
||||
gtk_text_iter_compare (&selection_end, &line_start) > 0)
|
||||
{
|
||||
if (gtk_text_iter_compare (&selection_start, &line_start) >= 0)
|
||||
selection_start_index = gtk_text_iter_get_line_index (&selection_start);
|
||||
else
|
||||
selection_start_index = -1;
|
||||
|
||||
if (gtk_text_iter_compare (&selection_end, &line_end) <= 0)
|
||||
selection_end_index = gtk_text_iter_get_line_index (&selection_end);
|
||||
else
|
||||
selection_end_index = byte_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render_para (drawable, render_state, line_display,
|
||||
- x_offset,
|
||||
current_y,
|
||||
selection_start_index, selection_end_index);
|
||||
render_para (drawable, render_state, line_display,
|
||||
- x_offset,
|
||||
current_y,
|
||||
selection_start_index, selection_end_index);
|
||||
|
||||
|
||||
/* We paint the cursors last, because they overlap another chunk
|
||||
/* We paint the cursors last, because they overlap another chunk
|
||||
and need to appear on top. */
|
||||
|
||||
cursor_list = line_display->cursors;
|
||||
while (cursor_list)
|
||||
{
|
||||
GtkTextCursorDisplay *cursor = cursor_list->data;
|
||||
GdkGC *gc;
|
||||
cursor_list = line_display->cursors;
|
||||
while (cursor_list)
|
||||
{
|
||||
GtkTextCursorDisplay *cursor = cursor_list->data;
|
||||
GdkGC *gc;
|
||||
|
||||
if (cursor->is_strong)
|
||||
gc = widget->style->base_gc[GTK_STATE_SELECTED];
|
||||
else
|
||||
gc = widget->style->text_gc[GTK_STATE_NORMAL];
|
||||
if (cursor->is_strong)
|
||||
gc = widget->style->base_gc[GTK_STATE_SELECTED];
|
||||
else
|
||||
gc = widget->style->text_gc[GTK_STATE_NORMAL];
|
||||
|
||||
gdk_draw_line (drawable, gc,
|
||||
line_display->x_offset + cursor->x - x_offset,
|
||||
current_y + line_display->top_margin + cursor->y,
|
||||
line_display->x_offset + cursor->x - x_offset,
|
||||
current_y + line_display->top_margin + cursor->y + cursor->height - 1);
|
||||
|
||||
cursor_list = cursor_list->next;
|
||||
}
|
||||
gdk_draw_line (drawable, gc,
|
||||
line_display->x_offset + cursor->x - x_offset,
|
||||
current_y + line_display->top_margin + cursor->y,
|
||||
line_display->x_offset + cursor->x - x_offset,
|
||||
current_y + line_display->top_margin + cursor->y + cursor->height - 1);
|
||||
|
||||
cursor_list = cursor_list->next;
|
||||
}
|
||||
} /* line_display->height > 0 */
|
||||
|
||||
current_y += line_display->height;
|
||||
gtk_text_layout_free_line_display (layout, line_display);
|
||||
render_state->last_appearance = NULL;
|
||||
|
|
|
|||
|
|
@ -650,7 +650,6 @@ gtk_text_iter_get_line (const GtkTextIter *iter)
|
|||
gint
|
||||
gtk_text_iter_get_line_offset (const GtkTextIter *iter)
|
||||
{
|
||||
|
||||
GtkTextRealIter *real;
|
||||
|
||||
g_return_val_if_fail (iter != NULL, 0);
|
||||
|
|
@ -683,7 +682,7 @@ gint
|
|||
gtk_text_iter_get_line_index (const GtkTextIter *iter)
|
||||
{
|
||||
GtkTextRealIter *real;
|
||||
|
||||
|
||||
g_return_val_if_fail (iter != NULL, 0);
|
||||
|
||||
real = gtk_text_iter_make_surreal (iter);
|
||||
|
|
@ -698,6 +697,108 @@ gtk_text_iter_get_line_index (const GtkTextIter *iter)
|
|||
return real->line_byte_offset;
|
||||
}
|
||||
|
||||
gint
|
||||
gtk_text_iter_get_visible_line_offset (const GtkTextIter *iter)
|
||||
{
|
||||
GtkTextRealIter *real;
|
||||
gint vis_offset;
|
||||
GtkTextLineSegment *seg;
|
||||
GtkTextIter pos;
|
||||
|
||||
g_return_val_if_fail (iter != NULL, 0);
|
||||
|
||||
real = gtk_text_iter_make_real (iter);
|
||||
|
||||
if (real == NULL)
|
||||
return 0;
|
||||
|
||||
ensure_char_offsets (real);
|
||||
|
||||
check_invariants (iter);
|
||||
|
||||
vis_offset = real->line_char_offset;
|
||||
|
||||
_gtk_text_btree_get_iter_at_line (real->tree,
|
||||
&pos,
|
||||
real->line,
|
||||
0);
|
||||
|
||||
seg = _gtk_text_iter_get_indexable_segment (&pos);
|
||||
|
||||
while (seg != real->segment)
|
||||
{
|
||||
/* This is a pretty expensive call, making the
|
||||
* whole function pretty lame; we could keep track
|
||||
* of current invisibility state by looking at toggle
|
||||
* segments as we loop, and then call this function
|
||||
* only once per line, in order to speed up the loop
|
||||
* quite a lot.
|
||||
*/
|
||||
if (_gtk_text_btree_char_is_invisible (&pos))
|
||||
vis_offset -= seg->char_count;
|
||||
|
||||
_gtk_text_iter_forward_indexable_segment (&pos);
|
||||
|
||||
seg = _gtk_text_iter_get_indexable_segment (&pos);
|
||||
}
|
||||
|
||||
if (_gtk_text_btree_char_is_invisible (&pos))
|
||||
vis_offset -= real->segment_char_offset;
|
||||
|
||||
return vis_offset;
|
||||
}
|
||||
|
||||
gint
|
||||
gtk_text_iter_get_visible_line_index (const GtkTextIter *iter)
|
||||
{
|
||||
GtkTextRealIter *real;
|
||||
gint vis_offset;
|
||||
GtkTextLineSegment *seg;
|
||||
GtkTextIter pos;
|
||||
|
||||
g_return_val_if_fail (iter != NULL, 0);
|
||||
|
||||
real = gtk_text_iter_make_real (iter);
|
||||
|
||||
if (real == NULL)
|
||||
return 0;
|
||||
|
||||
ensure_char_offsets (real);
|
||||
|
||||
check_invariants (iter);
|
||||
|
||||
vis_offset = real->line_byte_offset;
|
||||
|
||||
_gtk_text_btree_get_iter_at_line (real->tree,
|
||||
&pos,
|
||||
real->line,
|
||||
0);
|
||||
|
||||
seg = _gtk_text_iter_get_indexable_segment (&pos);
|
||||
|
||||
while (seg != real->segment)
|
||||
{
|
||||
/* This is a pretty expensive call, making the
|
||||
* whole function pretty lame; we could keep track
|
||||
* of current invisibility state by looking at toggle
|
||||
* segments as we loop, and then call this function
|
||||
* only once per line, in order to speed up the loop
|
||||
* quite a lot.
|
||||
*/
|
||||
if (_gtk_text_btree_char_is_invisible (&pos))
|
||||
vis_offset -= seg->byte_count;
|
||||
|
||||
_gtk_text_iter_forward_indexable_segment (&pos);
|
||||
|
||||
seg = _gtk_text_iter_get_indexable_segment (&pos);
|
||||
}
|
||||
|
||||
if (_gtk_text_btree_char_is_invisible (&pos))
|
||||
vis_offset -= real->segment_byte_offset;
|
||||
|
||||
return vis_offset;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dereferencing
|
||||
*/
|
||||
|
|
@ -3276,6 +3377,97 @@ gtk_text_iter_set_line_index (GtkTextIter *iter,
|
|||
check_invariants (iter);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gtk_text_iter_set_visible_line_offset:
|
||||
* @iter: a #GtkTextIter
|
||||
* @char_on_line: a character offset
|
||||
*
|
||||
* Like gtk_text_iter_set_line_offset(), but the offset is in visible
|
||||
* characters, i.e. text with a tag making it invisible is not
|
||||
* counted in the offset.
|
||||
**/
|
||||
void
|
||||
gtk_text_iter_set_visible_line_offset (GtkTextIter *iter,
|
||||
gint char_on_line)
|
||||
{
|
||||
gint chars_seen = 0;
|
||||
GtkTextIter pos;
|
||||
|
||||
g_return_if_fail (iter != NULL);
|
||||
|
||||
pos = *iter;
|
||||
|
||||
/* For now we use a ludicrously slow implementation */
|
||||
while (chars_seen < char_on_line)
|
||||
{
|
||||
if (!_gtk_text_btree_char_is_invisible (&pos))
|
||||
++chars_seen;
|
||||
|
||||
if (!gtk_text_iter_forward_char (&pos))
|
||||
break;
|
||||
|
||||
if (chars_seen == char_on_line)
|
||||
break;
|
||||
}
|
||||
|
||||
if (_gtk_text_iter_get_text_line (&pos) == _gtk_text_iter_get_text_line (iter))
|
||||
*iter = pos;
|
||||
else
|
||||
gtk_text_iter_forward_line (iter);
|
||||
}
|
||||
|
||||
static gint
|
||||
bytes_in_char (GtkTextIter *iter)
|
||||
{
|
||||
return g_unichar_to_utf8 (gtk_text_iter_get_char (iter), NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_text_iter_set_visible_line_index:
|
||||
* @iter: a #GtkTextIter
|
||||
* @byte_on_line: a byte index
|
||||
*
|
||||
* Like gtk_text_iter_set_line_index(), but the index is in visible
|
||||
* bytes, i.e. text with a tag making it invisible is not counted
|
||||
* in the index.
|
||||
**/
|
||||
void
|
||||
gtk_text_iter_set_visible_line_index (GtkTextIter *iter,
|
||||
gint byte_on_line)
|
||||
{
|
||||
gint bytes_seen = 0;
|
||||
GtkTextIter pos;
|
||||
|
||||
g_return_if_fail (iter != NULL);
|
||||
|
||||
pos = *iter;
|
||||
|
||||
/* For now we use a ludicrously slow implementation */
|
||||
while (bytes_seen < byte_on_line)
|
||||
{
|
||||
if (!_gtk_text_btree_char_is_invisible (&pos))
|
||||
bytes_seen += bytes_in_char (&pos);
|
||||
|
||||
if (!gtk_text_iter_forward_char (&pos))
|
||||
break;
|
||||
|
||||
if (bytes_seen >= byte_on_line)
|
||||
break;
|
||||
}
|
||||
|
||||
if (bytes_seen > byte_on_line)
|
||||
g_warning ("%s: Incorrect visible byte index %d falls in the middle of a UTF-8 "
|
||||
"character; this will crash the text buffer. "
|
||||
"Byte indexes must refer to the start of a character.",
|
||||
G_STRLOC, byte_on_line);
|
||||
|
||||
if (_gtk_text_iter_get_text_line (&pos) == _gtk_text_iter_get_text_line (iter))
|
||||
*iter = pos;
|
||||
else
|
||||
gtk_text_iter_forward_line (iter);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_text_iter_set_line:
|
||||
* @iter: a #GtkTextIter
|
||||
|
|
|
|||
|
|
@ -78,6 +78,9 @@ gint gtk_text_iter_get_line (const GtkTextIter *iter);
|
|||
gint gtk_text_iter_get_line_offset (const GtkTextIter *iter);
|
||||
gint gtk_text_iter_get_line_index (const GtkTextIter *iter);
|
||||
|
||||
gint gtk_text_iter_get_visible_line_offset (const GtkTextIter *iter);
|
||||
gint gtk_text_iter_get_visible_line_index (const GtkTextIter *iter);
|
||||
|
||||
|
||||
/*
|
||||
* "Dereference" operators
|
||||
|
|
@ -197,6 +200,10 @@ void gtk_text_iter_set_line_index (GtkTextIter *iter,
|
|||
void gtk_text_iter_forward_to_end (GtkTextIter *iter);
|
||||
gboolean gtk_text_iter_forward_to_line_end (GtkTextIter *iter);
|
||||
|
||||
void gtk_text_iter_set_visible_line_offset (GtkTextIter *iter,
|
||||
gint char_on_line);
|
||||
void gtk_text_iter_set_visible_line_index (GtkTextIter *iter,
|
||||
gint byte_on_line);
|
||||
|
||||
/* returns TRUE if a toggle was found; NULL for the tag pointer
|
||||
* means "any tag toggle", otherwise the next toggle of the
|
||||
|
|
|
|||
|
|
@ -994,14 +994,16 @@ totally_invisible_line (GtkTextLayout *layout,
|
|||
int bytes = 0;
|
||||
|
||||
/* If we have a cached style, then we know it does actually apply
|
||||
and we can just see if it is invisible. */
|
||||
* and we can just see if it is invisible.
|
||||
*/
|
||||
if (layout->one_style_cache &&
|
||||
!layout->one_style_cache->invisible)
|
||||
return FALSE;
|
||||
/* Without the cache, we check if the first char is visible, if so
|
||||
we are partially visible. Note that we have to check this since
|
||||
we don't know the current invisible/noninvisible toggle state; this
|
||||
function can use the whole btree to get it right. */
|
||||
* we are partially visible. Note that we have to check this since
|
||||
* we don't know the current invisible/noninvisible toggle state; this
|
||||
* function can use the whole btree to get it right.
|
||||
*/
|
||||
else
|
||||
{
|
||||
_gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
|
||||
|
|
@ -1020,10 +1022,11 @@ totally_invisible_line (GtkTextLayout *layout,
|
|||
bytes += seg->byte_count;
|
||||
|
||||
/* Note that these two tests can cause us to bail out
|
||||
when we shouldn't, because a higher-priority tag
|
||||
may override these settings. However the important
|
||||
thing is to only invisible really-invisible lines, rather
|
||||
than to invisible all really-invisible lines. */
|
||||
* when we shouldn't, because a higher-priority tag
|
||||
* may override these settings. However the important
|
||||
* thing is to only invisible really-invisible lines, rather
|
||||
* than to invisible all really-invisible lines.
|
||||
*/
|
||||
|
||||
else if (seg->type == >k_text_toggle_on_type)
|
||||
{
|
||||
|
|
@ -1478,8 +1481,6 @@ allocate_child_widgets (GtkTextLayout *text_layout,
|
|||
pango_layout_iter_get_run_extents (iter,
|
||||
NULL,
|
||||
&extents);
|
||||
|
||||
g_print ("extents at %d,%d\n", extents.x, extents.y);
|
||||
|
||||
g_signal_emit (G_OBJECT (text_layout),
|
||||
signals[ALLOCATE_CHILD],
|
||||
|
|
@ -1593,7 +1594,7 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
|
|||
GtkTextAttributes *style;
|
||||
gchar *text;
|
||||
PangoAttrList *attrs;
|
||||
gint byte_count, layout_byte_offset, layout_only_bytes;
|
||||
gint text_allocated, layout_byte_offset, buffer_byte_offset;
|
||||
gdouble align;
|
||||
PangoRectangle extents;
|
||||
gboolean para_values_set = FALSE;
|
||||
|
|
@ -1635,14 +1636,14 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
|
|||
|
||||
/* Allocate space for flat text for buffer
|
||||
*/
|
||||
byte_count = _gtk_text_line_byte_count (line);
|
||||
text = g_malloc (byte_count);
|
||||
text_allocated = _gtk_text_line_byte_count (line);
|
||||
text = g_malloc (text_allocated);
|
||||
|
||||
attrs = pango_attr_list_new ();
|
||||
|
||||
/* Iterate over segments, creating display chunks for them. */
|
||||
layout_byte_offset = 0; /* current length of layout text (includes preedit) */
|
||||
layout_only_bytes = 0; /* bytes in layout_byte_offset not in buffer */
|
||||
layout_byte_offset = 0; /* current length of layout text (includes preedit, does not include invisible text) */
|
||||
buffer_byte_offset = 0; /* position in the buffer line */
|
||||
seg = _gtk_text_iter_get_any_segment (&iter);
|
||||
while (seg != NULL)
|
||||
{
|
||||
|
|
@ -1653,7 +1654,7 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
|
|||
{
|
||||
_gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
|
||||
&iter, line,
|
||||
layout_byte_offset - layout_only_bytes);
|
||||
buffer_byte_offset);
|
||||
style = get_style (layout, &iter);
|
||||
|
||||
/* We have to delay setting the paragraph values until we
|
||||
|
|
@ -1692,6 +1693,7 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
|
|||
{
|
||||
memcpy (text + layout_byte_offset, seg->body.chars, seg->byte_count);
|
||||
layout_byte_offset += seg->byte_count;
|
||||
buffer_byte_offset += seg->byte_count;
|
||||
bytes += seg->byte_count;
|
||||
}
|
||||
else if (seg->type == >k_text_right_mark_type ||
|
||||
|
|
@ -1739,6 +1741,7 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
|
|||
memcpy (text + layout_byte_offset, gtk_text_unknown_char_utf8,
|
||||
seg->byte_count);
|
||||
layout_byte_offset += seg->byte_count;
|
||||
buffer_byte_offset += seg->byte_count;
|
||||
}
|
||||
else if (seg->type == >k_text_child_type)
|
||||
{
|
||||
|
|
@ -1753,11 +1756,19 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
|
|||
memcpy (text + layout_byte_offset, gtk_text_unknown_char_utf8,
|
||||
seg->byte_count);
|
||||
layout_byte_offset += seg->byte_count;
|
||||
buffer_byte_offset += seg->byte_count;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We don't know this segment type */
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
} /* if (segment was visible) */
|
||||
else
|
||||
{
|
||||
/* Invisible segment */
|
||||
buffer_byte_offset += seg->byte_count;
|
||||
}
|
||||
|
||||
release_style (layout, style);
|
||||
|
|
@ -1787,8 +1798,8 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
|
|||
|
||||
if (layout->preedit_len > 0)
|
||||
{
|
||||
byte_count += layout->preedit_len;
|
||||
text = g_realloc (text, byte_count);
|
||||
text_allocated += layout->preedit_len;
|
||||
text = g_realloc (text, text_allocated);
|
||||
|
||||
style = get_style (layout, &iter);
|
||||
add_preedit_attrs (layout, style, attrs, layout_byte_offset, size_only);
|
||||
|
|
@ -1796,7 +1807,7 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
|
|||
|
||||
memcpy (text + layout_byte_offset, layout->preedit_string, layout->preedit_len);
|
||||
layout_byte_offset += layout->preedit_len;
|
||||
layout_only_bytes += layout->preedit_len;
|
||||
/* DO NOT increment the buffer byte offset for preedit */
|
||||
|
||||
cursor_offset = layout->preedit_cursor - layout->preedit_len;
|
||||
}
|
||||
|
|
@ -1825,8 +1836,6 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
|
|||
set_para_values (layout, style, display, &align);
|
||||
release_style (layout, style);
|
||||
}
|
||||
|
||||
g_assert (layout_byte_offset == byte_count);
|
||||
|
||||
/* Pango doesn't want the trailing paragraph delimiters */
|
||||
|
||||
|
|
@ -1897,7 +1906,8 @@ gtk_text_layout_free_line_display (GtkTextLayout *layout,
|
|||
{
|
||||
if (display != layout->one_display_cache)
|
||||
{
|
||||
g_object_unref (G_OBJECT (display->layout));
|
||||
if (display->layout)
|
||||
g_object_unref (G_OBJECT (display->layout));
|
||||
|
||||
if (display->cursors)
|
||||
{
|
||||
|
|
@ -1911,7 +1921,7 @@ gtk_text_layout_free_line_display (GtkTextLayout *layout,
|
|||
}
|
||||
|
||||
/* Functions to convert iter <=> index for the line of a GtkTextLineDisplay
|
||||
* taking into account the preedit string, if necessary.
|
||||
* taking into account the preedit string and invisible text if necessary.
|
||||
*/
|
||||
static gint
|
||||
line_display_iter_to_index (GtkTextLayout *layout,
|
||||
|
|
@ -1922,8 +1932,8 @@ line_display_iter_to_index (GtkTextLayout *layout,
|
|||
|
||||
g_return_val_if_fail (_gtk_text_iter_get_text_line (iter) == display->line, 0);
|
||||
|
||||
index = gtk_text_iter_get_line_index (iter);
|
||||
|
||||
index = gtk_text_iter_get_visible_line_index (iter);
|
||||
|
||||
if (index >= display->insert_index)
|
||||
index += layout->preedit_len;
|
||||
|
||||
|
|
@ -1937,8 +1947,6 @@ line_display_index_to_iter (GtkTextLayout *layout,
|
|||
gint index,
|
||||
gint trailing)
|
||||
{
|
||||
gint line_len;
|
||||
|
||||
if (index >= display->insert_index + layout->preedit_len)
|
||||
index -= layout->preedit_len;
|
||||
else if (index > display->insert_index)
|
||||
|
|
@ -1946,27 +1954,24 @@ line_display_index_to_iter (GtkTextLayout *layout,
|
|||
index = display->insert_index;
|
||||
trailing = 0;
|
||||
}
|
||||
|
||||
line_len = _gtk_text_line_byte_count (display->line);
|
||||
g_assert (index <= line_len);
|
||||
|
||||
if (index < line_len)
|
||||
_gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
|
||||
iter, display->line, index);
|
||||
else
|
||||
_gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
|
||||
iter, display->line, 0);
|
||||
|
||||
gtk_text_iter_set_visible_line_index (iter, index);
|
||||
|
||||
if (_gtk_text_iter_get_text_line (iter) != display->line)
|
||||
{
|
||||
/* Clamp to end of line - really this clamping should have been done
|
||||
* before here, maybe in Pango, this is a broken band-aid I think
|
||||
*/
|
||||
g_assert (index == line_len);
|
||||
|
||||
_gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
|
||||
iter, display->line, 0);
|
||||
|
||||
if (!gtk_text_iter_ends_line (iter))
|
||||
gtk_text_iter_forward_to_line_end (iter);
|
||||
}
|
||||
|
||||
|
||||
/* FIXME should this be cursor positions? */
|
||||
gtk_text_iter_forward_chars (iter, trailing);
|
||||
}
|
||||
|
|
@ -2414,7 +2419,7 @@ gtk_text_layout_clamp_iter_to_vrange (GtkTextLayout *layout,
|
|||
}
|
||||
|
||||
/**
|
||||
* gtk_text_layout_move_iter_to_next_line:
|
||||
* gtk_text_layout_move_iter_to_previous_line:
|
||||
* @layout: a #GtkLayout
|
||||
* @iter: a #GtkTextIter
|
||||
*
|
||||
|
|
@ -2439,9 +2444,10 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
|
|||
orig = *iter;
|
||||
|
||||
line = _gtk_text_iter_get_text_line (iter);
|
||||
display = gtk_text_layout_get_line_display (layout, line, FALSE);
|
||||
display = gtk_text_layout_get_line_display (layout, line, FALSE);
|
||||
line_byte = line_display_iter_to_index (layout, display, iter);
|
||||
|
||||
/* FIXME can't use layout until we check display->height > 0) */
|
||||
tmp_list = pango_layout_get_lines (display->layout);
|
||||
layout_line = tmp_list->data;
|
||||
|
||||
|
|
@ -2449,6 +2455,8 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
|
|||
{
|
||||
GtkTextLine *prev_line = _gtk_text_line_previous (line);
|
||||
|
||||
/* FIXME keep going back while display->height == 0 */
|
||||
|
||||
if (prev_line)
|
||||
{
|
||||
gtk_text_layout_free_line_display (layout, display);
|
||||
|
|
|
|||
|
|
@ -2236,7 +2236,7 @@ test_init ()
|
|||
if (file_exists ("../gdk-pixbuf/.libs/libpixbufloader-pnm.so"))
|
||||
{
|
||||
putenv ("GDK_PIXBUF_MODULEDIR=../gdk-pixbuf/.libs");
|
||||
putenv ("GTK_IM_MODULE_FILE=./gtk.immodules");
|
||||
putenv ("GTK_IM_MODULE_FILE=../gtk/gtk.immodules");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue