New function.
Sat Aug 14 17:56:33 2004 Soeren Sandmann <sandmann@daimi.au.dk> * gtk/gtkentry.c (gtk_entry_get_pixel_ranges): New function. * gtk/gtkentry.c (in_selection): New function using gtk_entry_get_pixel_ranges() to determine whether a click is in the selection. Improve entry behavior wrt. dragging and selecting. Bug #143249. Sat Aug 14 17:53:46 2004 Soeren Sandmann <sandmann@daimi.au.dk> * configure.in: Require glib 2.5.2 * gtk/gtksequence.[ch]: New internal data structure. * gtk/gtkliststore.[hc]: Reimplement in terms of new data structure * tests/Makefile.am (testtreemodel_SOURCES): * tests/testtreemodel.c: New test program written by Matthias.
This commit is contained in:
committed by
Søren Sandmann Pedersen
parent
766d78659c
commit
15ed3634a9
21
ChangeLog
21
ChangeLog
@ -1,3 +1,24 @@
|
|||||||
|
Sat Aug 14 17:56:33 2004 Soeren Sandmann <sandmann@daimi.au.dk>
|
||||||
|
|
||||||
|
* gtk/gtkentry.c (gtk_entry_get_pixel_ranges): New function.
|
||||||
|
|
||||||
|
* gtk/gtkentry.c (in_selection): New function using
|
||||||
|
gtk_entry_get_pixel_ranges() to determine whether a click is in
|
||||||
|
the selection. Improve entry behavior wrt. dragging and
|
||||||
|
selecting. Bug #143249.
|
||||||
|
|
||||||
|
Sat Aug 14 17:53:46 2004 Soeren Sandmann <sandmann@daimi.au.dk>
|
||||||
|
|
||||||
|
* configure.in: Require glib 2.5.2
|
||||||
|
|
||||||
|
* gtk/gtksequence.[ch]: New internal data structure.
|
||||||
|
|
||||||
|
* gtk/gtkliststore.[hc]: Reimplement in terms of new data
|
||||||
|
structure
|
||||||
|
|
||||||
|
* tests/Makefile.am (testtreemodel_SOURCES):
|
||||||
|
* tests/testtreemodel.c: New test program written by Matthias.
|
||||||
|
|
||||||
2004-08-13 Matthias Clasen <mclasen@redhat.com>
|
2004-08-13 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
* gtk/gtkfilechooserdefault.c (gtk_file_chooser_default_style_set):
|
* gtk/gtkfilechooserdefault.c (gtk_file_chooser_default_style_set):
|
||||||
|
|||||||
@ -1,3 +1,24 @@
|
|||||||
|
Sat Aug 14 17:56:33 2004 Soeren Sandmann <sandmann@daimi.au.dk>
|
||||||
|
|
||||||
|
* gtk/gtkentry.c (gtk_entry_get_pixel_ranges): New function.
|
||||||
|
|
||||||
|
* gtk/gtkentry.c (in_selection): New function using
|
||||||
|
gtk_entry_get_pixel_ranges() to determine whether a click is in
|
||||||
|
the selection. Improve entry behavior wrt. dragging and
|
||||||
|
selecting. Bug #143249.
|
||||||
|
|
||||||
|
Sat Aug 14 17:53:46 2004 Soeren Sandmann <sandmann@daimi.au.dk>
|
||||||
|
|
||||||
|
* configure.in: Require glib 2.5.2
|
||||||
|
|
||||||
|
* gtk/gtksequence.[ch]: New internal data structure.
|
||||||
|
|
||||||
|
* gtk/gtkliststore.[hc]: Reimplement in terms of new data
|
||||||
|
structure
|
||||||
|
|
||||||
|
* tests/Makefile.am (testtreemodel_SOURCES):
|
||||||
|
* tests/testtreemodel.c: New test program written by Matthias.
|
||||||
|
|
||||||
2004-08-13 Matthias Clasen <mclasen@redhat.com>
|
2004-08-13 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
* gtk/gtkfilechooserdefault.c (gtk_file_chooser_default_style_set):
|
* gtk/gtkfilechooserdefault.c (gtk_file_chooser_default_style_set):
|
||||||
|
|||||||
@ -1,3 +1,24 @@
|
|||||||
|
Sat Aug 14 17:56:33 2004 Soeren Sandmann <sandmann@daimi.au.dk>
|
||||||
|
|
||||||
|
* gtk/gtkentry.c (gtk_entry_get_pixel_ranges): New function.
|
||||||
|
|
||||||
|
* gtk/gtkentry.c (in_selection): New function using
|
||||||
|
gtk_entry_get_pixel_ranges() to determine whether a click is in
|
||||||
|
the selection. Improve entry behavior wrt. dragging and
|
||||||
|
selecting. Bug #143249.
|
||||||
|
|
||||||
|
Sat Aug 14 17:53:46 2004 Soeren Sandmann <sandmann@daimi.au.dk>
|
||||||
|
|
||||||
|
* configure.in: Require glib 2.5.2
|
||||||
|
|
||||||
|
* gtk/gtksequence.[ch]: New internal data structure.
|
||||||
|
|
||||||
|
* gtk/gtkliststore.[hc]: Reimplement in terms of new data
|
||||||
|
structure
|
||||||
|
|
||||||
|
* tests/Makefile.am (testtreemodel_SOURCES):
|
||||||
|
* tests/testtreemodel.c: New test program written by Matthias.
|
||||||
|
|
||||||
2004-08-13 Matthias Clasen <mclasen@redhat.com>
|
2004-08-13 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
* gtk/gtkfilechooserdefault.c (gtk_file_chooser_default_style_set):
|
* gtk/gtkfilechooserdefault.c (gtk_file_chooser_default_style_set):
|
||||||
|
|||||||
@ -1,3 +1,24 @@
|
|||||||
|
Sat Aug 14 17:56:33 2004 Soeren Sandmann <sandmann@daimi.au.dk>
|
||||||
|
|
||||||
|
* gtk/gtkentry.c (gtk_entry_get_pixel_ranges): New function.
|
||||||
|
|
||||||
|
* gtk/gtkentry.c (in_selection): New function using
|
||||||
|
gtk_entry_get_pixel_ranges() to determine whether a click is in
|
||||||
|
the selection. Improve entry behavior wrt. dragging and
|
||||||
|
selecting. Bug #143249.
|
||||||
|
|
||||||
|
Sat Aug 14 17:53:46 2004 Soeren Sandmann <sandmann@daimi.au.dk>
|
||||||
|
|
||||||
|
* configure.in: Require glib 2.5.2
|
||||||
|
|
||||||
|
* gtk/gtksequence.[ch]: New internal data structure.
|
||||||
|
|
||||||
|
* gtk/gtkliststore.[hc]: Reimplement in terms of new data
|
||||||
|
structure
|
||||||
|
|
||||||
|
* tests/Makefile.am (testtreemodel_SOURCES):
|
||||||
|
* tests/testtreemodel.c: New test program written by Matthias.
|
||||||
|
|
||||||
2004-08-13 Matthias Clasen <mclasen@redhat.com>
|
2004-08-13 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
* gtk/gtkfilechooserdefault.c (gtk_file_chooser_default_style_set):
|
* gtk/gtkfilechooserdefault.c (gtk_file_chooser_default_style_set):
|
||||||
|
|||||||
@ -29,7 +29,7 @@ m4_define([gtk_api_version], [2.0])
|
|||||||
m4_define([gtk_binary_version], [2.4.0])
|
m4_define([gtk_binary_version], [2.4.0])
|
||||||
|
|
||||||
# required versions of other packages
|
# required versions of other packages
|
||||||
m4_define([glib_required_version], [2.4.0])
|
m4_define([glib_required_version], [2.5.2])
|
||||||
m4_define([pango_required_version], [1.5.1])
|
m4_define([pango_required_version], [1.5.1])
|
||||||
m4_define([atk_required_version], [1.0.1])
|
m4_define([atk_required_version], [1.0.1])
|
||||||
|
|
||||||
|
|||||||
@ -285,7 +285,7 @@ gtk_semi_private_h_sources = \
|
|||||||
gtkfilesystem.h
|
gtkfilesystem.h
|
||||||
|
|
||||||
# GTK+ header files that don't get installed
|
# GTK+ header files that don't get installed
|
||||||
gtk_private_h_sources = \
|
gtk_private_h_sources = \
|
||||||
gtkentryprivate.h \
|
gtkentryprivate.h \
|
||||||
gtkfilechooserembed.h \
|
gtkfilechooserembed.h \
|
||||||
gtkfilechooserentry.h \
|
gtkfilechooserentry.h \
|
||||||
@ -296,9 +296,10 @@ gtk_private_h_sources = \
|
|||||||
gtkfilesystemmodel.h \
|
gtkfilesystemmodel.h \
|
||||||
gtkinternals.h \
|
gtkinternals.h \
|
||||||
gtkpathbar.h \
|
gtkpathbar.h \
|
||||||
gtkrbtree.h \
|
gtkrbtree.h \
|
||||||
|
gtksequence.h \
|
||||||
gtktextbtree.h \
|
gtktextbtree.h \
|
||||||
gtktextchildprivate.h \
|
gtktextchildprivate.h \
|
||||||
gtktextsegment.h \
|
gtktextsegment.h \
|
||||||
gtktexttypes.h \
|
gtktexttypes.h \
|
||||||
gtktextutil.h \
|
gtktextutil.h \
|
||||||
@ -441,6 +442,7 @@ gtk_c_sources = \
|
|||||||
gtkscale.c \
|
gtkscale.c \
|
||||||
gtkscrollbar.c \
|
gtkscrollbar.c \
|
||||||
gtkscrolledwindow.c \
|
gtkscrolledwindow.c \
|
||||||
|
gtksequence.c \
|
||||||
gtkselection.c \
|
gtkselection.c \
|
||||||
gtkseparator.c \
|
gtkseparator.c \
|
||||||
gtkseparatormenuitem.c \
|
gtkseparatormenuitem.c \
|
||||||
|
|||||||
@ -1400,6 +1400,70 @@ gtk_entry_expose (GtkWidget *widget,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_entry_get_pixel_ranges (GtkEntry *entry,
|
||||||
|
gint **ranges,
|
||||||
|
gint *n_ranges)
|
||||||
|
{
|
||||||
|
gint start_char, end_char;
|
||||||
|
|
||||||
|
if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start_char, &end_char))
|
||||||
|
{
|
||||||
|
PangoLayout *layout = gtk_entry_ensure_layout (entry, TRUE);
|
||||||
|
PangoLayoutLine *line = pango_layout_get_lines (layout)->data;
|
||||||
|
const char *text = pango_layout_get_text (layout);
|
||||||
|
gint start_index = g_utf8_offset_to_pointer (text, start_char) - text;
|
||||||
|
gint end_index = g_utf8_offset_to_pointer (text, end_char) - text;
|
||||||
|
gint real_n_ranges, i;
|
||||||
|
|
||||||
|
pango_layout_line_get_x_ranges (line, start_index, end_index, ranges, &real_n_ranges);
|
||||||
|
|
||||||
|
if (ranges)
|
||||||
|
{
|
||||||
|
gint *r = *ranges;
|
||||||
|
|
||||||
|
for (i = 0; i < real_n_ranges; ++i)
|
||||||
|
{
|
||||||
|
r[2 * i + 1] = (r[2 * i + 1] - r[2 * i]) / PANGO_SCALE;
|
||||||
|
r[2 * i] = r[2 * i] / PANGO_SCALE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n_ranges)
|
||||||
|
*n_ranges = real_n_ranges;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (n_ranges)
|
||||||
|
*n_ranges = 0;
|
||||||
|
if (ranges)
|
||||||
|
*ranges = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
in_selection (GtkEntry *entry,
|
||||||
|
gint x)
|
||||||
|
{
|
||||||
|
gint *ranges;
|
||||||
|
gint n_ranges, i;
|
||||||
|
gint retval = FALSE;
|
||||||
|
|
||||||
|
gtk_entry_get_pixel_ranges (entry, &ranges, &n_ranges);
|
||||||
|
|
||||||
|
for (i = 0; i < n_ranges; ++i)
|
||||||
|
{
|
||||||
|
if (x >= ranges[2 * i] && x < ranges[2 * i] + ranges[2 * i + 1])
|
||||||
|
{
|
||||||
|
retval = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (ranges);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
gtk_entry_button_press (GtkWidget *widget,
|
gtk_entry_button_press (GtkWidget *widget,
|
||||||
GdkEventButton *event)
|
GdkEventButton *event)
|
||||||
@ -1491,21 +1555,18 @@ gtk_entry_button_press (GtkWidget *widget,
|
|||||||
switch (event->type)
|
switch (event->type)
|
||||||
{
|
{
|
||||||
case GDK_BUTTON_PRESS:
|
case GDK_BUTTON_PRESS:
|
||||||
if (have_selection && tmp_pos >= sel_start && tmp_pos <= sel_end)
|
if (in_selection (entry, event->x + entry->scroll_offset))
|
||||||
{
|
{
|
||||||
/* Click inside the selection - we'll either start a drag, or
|
/* Click inside the selection - we'll either start a drag, or
|
||||||
* clear the selection
|
* clear the selection
|
||||||
*/
|
*/
|
||||||
|
|
||||||
entry->in_drag = TRUE;
|
entry->in_drag = TRUE;
|
||||||
entry->drag_start_x = event->x + entry->scroll_offset;
|
entry->drag_start_x = event->x + entry->scroll_offset;
|
||||||
entry->drag_start_y = event->y + entry->scroll_offset;
|
entry->drag_start_y = event->y + entry->scroll_offset;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
gtk_editable_set_position (editable, tmp_pos);
|
gtk_editable_set_position (editable, tmp_pos);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case GDK_2BUTTON_PRESS:
|
case GDK_2BUTTON_PRESS:
|
||||||
/* We ALWAYS receive a GDK_BUTTON_PRESS immediately before
|
/* We ALWAYS receive a GDK_BUTTON_PRESS immediately before
|
||||||
@ -2997,7 +3058,6 @@ static void
|
|||||||
gtk_entry_draw_text (GtkEntry *entry)
|
gtk_entry_draw_text (GtkEntry *entry)
|
||||||
{
|
{
|
||||||
GtkWidget *widget;
|
GtkWidget *widget;
|
||||||
PangoLayoutLine *line;
|
|
||||||
|
|
||||||
if (!entry->visible && entry->invisible_char == 0)
|
if (!entry->visible && entry->invisible_char == 0)
|
||||||
return;
|
return;
|
||||||
@ -3021,19 +3081,12 @@ gtk_entry_draw_text (GtkEntry *entry)
|
|||||||
gint *ranges;
|
gint *ranges;
|
||||||
gint n_ranges, i;
|
gint n_ranges, i;
|
||||||
PangoRectangle logical_rect;
|
PangoRectangle logical_rect;
|
||||||
const gchar *text = pango_layout_get_text (layout);
|
GdkGC *selection_gc, *text_gc;
|
||||||
gint start_index = g_utf8_offset_to_pointer (text, start_pos) - text;
|
GdkRegion *clip_region;
|
||||||
gint end_index = g_utf8_offset_to_pointer (text, end_pos) - text;
|
|
||||||
GdkRegion *clip_region = gdk_region_new ();
|
|
||||||
GdkGC *text_gc;
|
|
||||||
GdkGC *selection_gc;
|
|
||||||
|
|
||||||
line = pango_layout_get_lines (layout)->data;
|
pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
|
||||||
|
gtk_entry_get_pixel_ranges (entry, &ranges, &n_ranges);
|
||||||
pango_layout_line_get_x_ranges (line, start_index, end_index, &ranges, &n_ranges);
|
|
||||||
|
|
||||||
pango_layout_get_extents (layout, NULL, &logical_rect);
|
|
||||||
|
|
||||||
if (GTK_WIDGET_HAS_FOCUS (entry))
|
if (GTK_WIDGET_HAS_FOCUS (entry))
|
||||||
{
|
{
|
||||||
selection_gc = widget->style->base_gc [GTK_STATE_SELECTED];
|
selection_gc = widget->style->base_gc [GTK_STATE_SELECTED];
|
||||||
@ -3045,21 +3098,22 @@ gtk_entry_draw_text (GtkEntry *entry)
|
|||||||
text_gc = widget->style->text_gc [GTK_STATE_ACTIVE];
|
text_gc = widget->style->text_gc [GTK_STATE_ACTIVE];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i < n_ranges; i++)
|
clip_region = gdk_region_new ();
|
||||||
|
for (i = 0; i < n_ranges; ++i)
|
||||||
{
|
{
|
||||||
GdkRectangle rect;
|
GdkRectangle rect;
|
||||||
|
|
||||||
rect.x = INNER_BORDER - entry->scroll_offset + ranges[2*i] / PANGO_SCALE;
|
rect.x = INNER_BORDER - entry->scroll_offset + ranges[2 * i];
|
||||||
rect.y = y;
|
rect.y = y;
|
||||||
rect.width = (ranges[2*i + 1] - ranges[2*i]) / PANGO_SCALE;
|
rect.width = ranges[2 * i + 1];
|
||||||
rect.height = logical_rect.height / PANGO_SCALE;
|
rect.height = logical_rect.height;
|
||||||
|
|
||||||
gdk_draw_rectangle (entry->text_area, selection_gc, TRUE,
|
gdk_draw_rectangle (entry->text_area, selection_gc, TRUE,
|
||||||
rect.x, rect.y, rect.width, rect.height);
|
rect.x, rect.y, rect.width, rect.height);
|
||||||
|
|
||||||
gdk_region_union_with_rect (clip_region, &rect);
|
gdk_region_union_with_rect (clip_region, &rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
gdk_gc_set_clip_region (text_gc, clip_region);
|
gdk_gc_set_clip_region (text_gc, clip_region);
|
||||||
gdk_draw_layout (entry->text_area, text_gc,
|
gdk_draw_layout (entry->text_area, text_gc,
|
||||||
x, y,
|
x, y,
|
||||||
|
|||||||
1080
gtk/gtkliststore.c
1080
gtk/gtkliststore.c
File diff suppressed because it is too large
Load Diff
@ -43,14 +43,14 @@ struct _GtkListStore
|
|||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
gint stamp;
|
gint stamp;
|
||||||
gpointer root;
|
gpointer seq; /* head of the list */
|
||||||
gpointer tail;
|
gpointer _gtk_reserved1;
|
||||||
GList *sort_list;
|
GList *sort_list;
|
||||||
gint n_columns;
|
gint n_columns;
|
||||||
gint sort_column_id;
|
gint sort_column_id;
|
||||||
GtkSortType order;
|
GtkSortType order;
|
||||||
GType *column_headers;
|
GType *column_headers;
|
||||||
gint length;
|
gint _gtk_reserved2;
|
||||||
GtkTreeIterCompareFunc default_sort_func;
|
GtkTreeIterCompareFunc default_sort_func;
|
||||||
gpointer default_sort_data;
|
gpointer default_sort_data;
|
||||||
GtkDestroyNotify default_sort_destroy;
|
GtkDestroyNotify default_sort_destroy;
|
||||||
|
|||||||
1104
gtk/gtksequence.c
Normal file
1104
gtk/gtksequence.c
Normal file
File diff suppressed because it is too large
Load Diff
104
gtk/gtksequence.h
Normal file
104
gtk/gtksequence.h
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
/* GLIB - Library of useful routines for C programming
|
||||||
|
* Copyright (C) 2002 Soeren Sandmann (sandmann@daimi.au.dk)
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#ifndef __GSEQUENCE_H__
|
||||||
|
#define __GSEQUENCE_H__
|
||||||
|
|
||||||
|
|
||||||
|
/* Warning
|
||||||
|
*
|
||||||
|
* Do not use this API. It is here, internal to gtk+, for 2.6 only.
|
||||||
|
* In 2.8 the plan is to add a similar data structure to GLib.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct _GtkSequence GtkSequence;
|
||||||
|
typedef struct _GtkSequenceNode *GtkSequencePtr;
|
||||||
|
|
||||||
|
/* GtkSequence */
|
||||||
|
GtkSequence * _gtk_sequence_new (GDestroyNotify data_destroy);
|
||||||
|
void _gtk_sequence_free (GtkSequence *seq);
|
||||||
|
void _gtk_sequence_sort (GtkSequence *seq,
|
||||||
|
GCompareDataFunc cmp_func,
|
||||||
|
gpointer cmp_data);
|
||||||
|
void _gtk_sequence_append (GtkSequence *seq,
|
||||||
|
gpointer data);
|
||||||
|
void _gtk_sequence_prepend (GtkSequence *seq,
|
||||||
|
gpointer data);
|
||||||
|
GtkSequencePtr _gtk_sequence_insert (GtkSequencePtr ptr,
|
||||||
|
gpointer data);
|
||||||
|
void _gtk_sequence_remove (GtkSequencePtr ptr);
|
||||||
|
void _gtk_sequence_move (GtkSequencePtr ptr,
|
||||||
|
GtkSequencePtr pos);
|
||||||
|
void _gtk_sequence_swap (GtkSequencePtr a,
|
||||||
|
GtkSequencePtr b);
|
||||||
|
GtkSequencePtr _gtk_sequence_insert_sorted (GtkSequence *seq,
|
||||||
|
gpointer data,
|
||||||
|
GCompareDataFunc cmp_func,
|
||||||
|
gpointer cmp_data);
|
||||||
|
void _gtk_sequence_set (GtkSequencePtr ptr,
|
||||||
|
gpointer data);
|
||||||
|
void _gtk_sequence_insert_sequence (GtkSequencePtr ptr,
|
||||||
|
GtkSequence *other_seq);
|
||||||
|
void _gtk_sequence_concatenate (GtkSequence *seq1,
|
||||||
|
GtkSequence *seq);
|
||||||
|
void _gtk_sequence_remove_range (GtkSequencePtr begin,
|
||||||
|
GtkSequencePtr end,
|
||||||
|
GtkSequence **removed);
|
||||||
|
gint _gtk_sequence_get_length (GtkSequence *seq);
|
||||||
|
GtkSequencePtr _gtk_sequence_get_end_ptr (GtkSequence *seq);
|
||||||
|
GtkSequencePtr _gtk_sequence_get_begin_ptr (GtkSequence *seq);
|
||||||
|
GtkSequencePtr _gtk_sequence_get_ptr_at_pos (GtkSequence *seq,
|
||||||
|
gint pos);
|
||||||
|
void _gtk_sequence_sort_changed (GtkSequencePtr ptr,
|
||||||
|
GCompareDataFunc cmp_func,
|
||||||
|
gpointer cmp_data);
|
||||||
|
void _gtk_sequence_foreach (GtkSequence *seq,
|
||||||
|
GFunc func,
|
||||||
|
gpointer data);
|
||||||
|
|
||||||
|
/* GtkSequencePtr */
|
||||||
|
gboolean _gtk_sequence_ptr_is_end (GtkSequencePtr ptr);
|
||||||
|
gboolean _gtk_sequence_ptr_is_begin (GtkSequencePtr ptr);
|
||||||
|
gint _gtk_sequence_ptr_get_position (GtkSequencePtr ptr);
|
||||||
|
GtkSequencePtr _gtk_sequence_ptr_next (GtkSequencePtr ptr);
|
||||||
|
GtkSequencePtr _gtk_sequence_ptr_prev (GtkSequencePtr ptr);
|
||||||
|
GtkSequencePtr _gtk_sequence_ptr_move (GtkSequencePtr ptr,
|
||||||
|
guint leap);
|
||||||
|
gpointer _gtk_sequence_ptr_get_data (GtkSequencePtr ptr);
|
||||||
|
GtkSequence *_gtk_sequence_ptr_get_sequence (GtkSequencePtr ptr);
|
||||||
|
|
||||||
|
/* search */
|
||||||
|
|
||||||
|
/* return TRUE if you want to be called again with two
|
||||||
|
* smaller segments
|
||||||
|
*/
|
||||||
|
typedef gboolean (* GtkSequenceSearchFunc) (GtkSequencePtr begin,
|
||||||
|
GtkSequencePtr end,
|
||||||
|
gpointer data);
|
||||||
|
|
||||||
|
void _gtk_sequence_search (GtkSequence *seq,
|
||||||
|
GtkSequenceSearchFunc f,
|
||||||
|
gpointer data);
|
||||||
|
|
||||||
|
/* debug */
|
||||||
|
gint _gtk_sequence_calc_tree_height (GtkSequence *seq);
|
||||||
|
|
||||||
|
#endif /* __GSEQUENCE_H__ */
|
||||||
@ -51,6 +51,7 @@ noinst_PROGRAMS = \
|
|||||||
testtoolbar \
|
testtoolbar \
|
||||||
stresstest-toolbar \
|
stresstest-toolbar \
|
||||||
testtreeedit \
|
testtreeedit \
|
||||||
|
testtreemodel \
|
||||||
testtreeview \
|
testtreeview \
|
||||||
testtreefocus \
|
testtreefocus \
|
||||||
testtreeflow \
|
testtreeflow \
|
||||||
@ -88,6 +89,7 @@ testspinbutton_DEPENDENCIES = $(TEST_DEPS)
|
|||||||
testtext_DEPENDENCIES = $(TEST_DEPS)
|
testtext_DEPENDENCIES = $(TEST_DEPS)
|
||||||
testtextbuffer_DEPENDENCIES = $(TEST_DEPS)
|
testtextbuffer_DEPENDENCIES = $(TEST_DEPS)
|
||||||
testtreeedit_DEPENDENCIES = $(DEPS)
|
testtreeedit_DEPENDENCIES = $(DEPS)
|
||||||
|
testtreemodel_DEPENDENCIES = $(DEPS)
|
||||||
testtreeview_DEPENDENCIES = $(DEPS)
|
testtreeview_DEPENDENCIES = $(DEPS)
|
||||||
testtreefocus_DEPENDENCIES = $(DEPS)
|
testtreefocus_DEPENDENCIES = $(DEPS)
|
||||||
testtreeflow_DEPENDENCIES = $(DEPS)
|
testtreeflow_DEPENDENCIES = $(DEPS)
|
||||||
@ -122,6 +124,7 @@ testtextbuffer_LDADD = $(LDADDS)
|
|||||||
testtoolbar_LDADD = $(LDADDS)
|
testtoolbar_LDADD = $(LDADDS)
|
||||||
stresstest_toolbar_LDADD = $(LDADDS)
|
stresstest_toolbar_LDADD = $(LDADDS)
|
||||||
testtreeedit_LDADD = $(LDADDS)
|
testtreeedit_LDADD = $(LDADDS)
|
||||||
|
testtreemodel_LDADD = $(LDADDS)
|
||||||
testtreeview_LDADD = $(LDADDS)
|
testtreeview_LDADD = $(LDADDS)
|
||||||
testtreefocus_LDADD = $(LDADDS)
|
testtreefocus_LDADD = $(LDADDS)
|
||||||
testtreeflow_LDADD = $(LDADDS)
|
testtreeflow_LDADD = $(LDADDS)
|
||||||
@ -148,6 +151,9 @@ testgtk_SOURCES = \
|
|||||||
testtreeedit_SOURCES = \
|
testtreeedit_SOURCES = \
|
||||||
testtreeedit.c
|
testtreeedit.c
|
||||||
|
|
||||||
|
testtreemodel_SOURCES = \
|
||||||
|
testtreemodel.c
|
||||||
|
|
||||||
testtreeview_SOURCES = \
|
testtreeview_SOURCES = \
|
||||||
prop-editor.c \
|
prop-editor.c \
|
||||||
testtreeview.c
|
testtreeview.c
|
||||||
|
|||||||
305
tests/testtreemodel.c
Normal file
305
tests/testtreemodel.c
Normal file
@ -0,0 +1,305 @@
|
|||||||
|
#include <malloc.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
static gint repeats = 2;
|
||||||
|
static gint max_size = 8;
|
||||||
|
|
||||||
|
static GOptionEntry entries[] = {
|
||||||
|
{ "repeats", 'r', 0, G_OPTION_ARG_INT, &repeats, "Average over N repetitions", "N" },
|
||||||
|
{ "max-size", 'm', 0, G_OPTION_ARG_INT, &max_size, "Test up to 2^M items", "M" },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef void (ClearFunc)(GtkTreeModel *model);
|
||||||
|
typedef void (InsertFunc)(GtkTreeModel *model,
|
||||||
|
gint items,
|
||||||
|
gint i);
|
||||||
|
|
||||||
|
static void
|
||||||
|
list_store_append (GtkTreeModel *model,
|
||||||
|
gint items,
|
||||||
|
gint i)
|
||||||
|
{
|
||||||
|
GtkListStore *store = GTK_LIST_STORE (model);
|
||||||
|
GtkTreeIter iter;
|
||||||
|
gchar *text;
|
||||||
|
|
||||||
|
text = g_strdup_printf ("row %d", i);
|
||||||
|
gtk_list_store_append (store, &iter);
|
||||||
|
gtk_list_store_set (store, &iter, 0, i, 1, text, -1);
|
||||||
|
g_free (text);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
list_store_prepend (GtkTreeModel *model,
|
||||||
|
gint items,
|
||||||
|
gint i)
|
||||||
|
{
|
||||||
|
GtkListStore *store = GTK_LIST_STORE (model);
|
||||||
|
GtkTreeIter iter;
|
||||||
|
gchar *text;
|
||||||
|
|
||||||
|
text = g_strdup_printf ("row %d", i);
|
||||||
|
gtk_list_store_prepend (store, &iter);
|
||||||
|
gtk_list_store_set (store, &iter, 0, i, 1, text, -1);
|
||||||
|
g_free (text);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
list_store_insert (GtkTreeModel *model,
|
||||||
|
gint items,
|
||||||
|
gint i)
|
||||||
|
{
|
||||||
|
GtkListStore *store = GTK_LIST_STORE (model);
|
||||||
|
GtkTreeIter iter;
|
||||||
|
gchar *text;
|
||||||
|
gint n;
|
||||||
|
|
||||||
|
text = g_strdup_printf ("row %d", i);
|
||||||
|
n = g_random_int_range (0, i + 1);
|
||||||
|
gtk_list_store_insert (store, &iter, n);
|
||||||
|
gtk_list_store_set (store, &iter, 0, i, 1, text, -1);
|
||||||
|
g_free (text);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gint
|
||||||
|
compare (GtkTreeModel *model,
|
||||||
|
GtkTreeIter *a,
|
||||||
|
GtkTreeIter *b,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
gchar *str_a, *str_b;
|
||||||
|
gint result;
|
||||||
|
|
||||||
|
gtk_tree_model_get (model, a, 1, &str_a, -1);
|
||||||
|
gtk_tree_model_get (model, b, 1, &str_b, -1);
|
||||||
|
|
||||||
|
result = strcmp (str_a, str_b);
|
||||||
|
|
||||||
|
g_free (str_a);
|
||||||
|
g_free (str_b);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tree_store_append (GtkTreeModel *model,
|
||||||
|
gint items,
|
||||||
|
gint i)
|
||||||
|
{
|
||||||
|
GtkTreeStore *store = GTK_TREE_STORE (model);
|
||||||
|
GtkTreeIter iter;
|
||||||
|
gchar *text;
|
||||||
|
|
||||||
|
text = g_strdup_printf ("row %d", i);
|
||||||
|
gtk_tree_store_append (store, &iter, NULL);
|
||||||
|
gtk_tree_store_set (store, &iter, 0, i, 1, text, -1);
|
||||||
|
g_free (text);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tree_store_prepend (GtkTreeModel *model,
|
||||||
|
gint items,
|
||||||
|
gint i)
|
||||||
|
{
|
||||||
|
GtkTreeStore *store = GTK_TREE_STORE (model);
|
||||||
|
GtkTreeIter iter;
|
||||||
|
gchar *text;
|
||||||
|
|
||||||
|
text = g_strdup_printf ("row %d", i);
|
||||||
|
gtk_tree_store_prepend (store, &iter, NULL);
|
||||||
|
gtk_tree_store_set (store, &iter, 0, i, 1, text, -1);
|
||||||
|
g_free (text);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tree_store_insert_flat (GtkTreeModel *model,
|
||||||
|
gint items,
|
||||||
|
gint i)
|
||||||
|
{
|
||||||
|
GtkTreeStore *store = GTK_TREE_STORE (model);
|
||||||
|
GtkTreeIter iter;
|
||||||
|
gchar *text;
|
||||||
|
gint n;
|
||||||
|
|
||||||
|
text = g_strdup_printf ("row %d", i);
|
||||||
|
n = g_random_int_range (0, i + 1);
|
||||||
|
gtk_tree_store_insert (store, &iter, NULL, n);
|
||||||
|
gtk_tree_store_set (store, &iter, 0, i, 1, text, -1);
|
||||||
|
g_free (text);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
gint i;
|
||||||
|
gint n;
|
||||||
|
gboolean found;
|
||||||
|
GtkTreeIter iter;
|
||||||
|
} FindData;
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
find_nth (GtkTreeModel *model,
|
||||||
|
GtkTreePath *path,
|
||||||
|
GtkTreeIter *iter,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
FindData *fdata = (FindData *)data;
|
||||||
|
|
||||||
|
if (fdata->i >= fdata->n)
|
||||||
|
{
|
||||||
|
fdata->iter = *iter;
|
||||||
|
fdata->found = TRUE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fdata->i++;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tree_store_insert_deep (GtkTreeModel *model,
|
||||||
|
gint items,
|
||||||
|
gint i)
|
||||||
|
{
|
||||||
|
GtkTreeStore *store = GTK_TREE_STORE (model);
|
||||||
|
GtkTreeIter iter;
|
||||||
|
gchar *text;
|
||||||
|
FindData data;
|
||||||
|
gint n;
|
||||||
|
|
||||||
|
text = g_strdup_printf ("row %d", i);
|
||||||
|
data.n = g_random_int_range (0, items);
|
||||||
|
data.i = 0;
|
||||||
|
data.found = FALSE;
|
||||||
|
if (data.n < i)
|
||||||
|
gtk_tree_model_foreach (model, find_nth, &data);
|
||||||
|
gtk_tree_store_insert (store, &iter, data.found ? &(data.iter) : NULL, n);
|
||||||
|
gtk_tree_store_set (store, &iter, 0, i, 1, text, -1);
|
||||||
|
g_free (text);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_run (gchar *title,
|
||||||
|
GtkTreeModel *store,
|
||||||
|
ClearFunc *clear,
|
||||||
|
InsertFunc *insert)
|
||||||
|
{
|
||||||
|
GtkTreeIter iter;
|
||||||
|
gint i, k, d, items;
|
||||||
|
gchar *text;
|
||||||
|
GTimer *timer;
|
||||||
|
gdouble elapsed;
|
||||||
|
int uordblks_before;
|
||||||
|
|
||||||
|
g_print ("%s (average over %d runs, time in milliseconds)\n"
|
||||||
|
"items \ttime \ttime/item \tused memory\n", title, repeats);
|
||||||
|
|
||||||
|
timer = g_timer_new ();
|
||||||
|
|
||||||
|
for (k = 0; k < max_size; k++)
|
||||||
|
{
|
||||||
|
items = 1 << k;
|
||||||
|
elapsed = 0.0;
|
||||||
|
for (d = 0; d < repeats; d++)
|
||||||
|
{
|
||||||
|
(*clear)(store);
|
||||||
|
uordblks_before = mallinfo().uordblks;
|
||||||
|
g_timer_reset (timer);
|
||||||
|
g_timer_start (timer);
|
||||||
|
for (i = 0; i < items; i++)
|
||||||
|
(*insert) (store, items, i);
|
||||||
|
g_timer_stop (timer);
|
||||||
|
elapsed += g_timer_elapsed (timer, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
elapsed = elapsed * 1000 / repeats;
|
||||||
|
g_print ("%d \t%lf \t%lf \t%ldk\n",
|
||||||
|
items, elapsed, elapsed/items, (mallinfo().uordblks - uordblks_before) / 1024);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
GtkTreeModel *model;
|
||||||
|
GOptionContext *context;
|
||||||
|
|
||||||
|
gtk_init (&argc, &argv);
|
||||||
|
|
||||||
|
context = g_option_context_new ("");
|
||||||
|
g_option_context_add_main_entries (context, entries, "");
|
||||||
|
g_option_context_parse (context, &argc, &argv, NULL);
|
||||||
|
g_option_context_free (context);
|
||||||
|
|
||||||
|
model = GTK_TREE_MODEL (gtk_list_store_new (2, G_TYPE_INT, G_TYPE_STRING));
|
||||||
|
|
||||||
|
test_run ("list store append",
|
||||||
|
model,
|
||||||
|
(ClearFunc*)gtk_list_store_clear,
|
||||||
|
(InsertFunc*)list_store_append);
|
||||||
|
|
||||||
|
test_run ("list store prepend",
|
||||||
|
model,
|
||||||
|
(ClearFunc*)gtk_list_store_clear,
|
||||||
|
(InsertFunc*)list_store_prepend);
|
||||||
|
|
||||||
|
test_run ("list store insert",
|
||||||
|
model,
|
||||||
|
(ClearFunc*)gtk_list_store_clear,
|
||||||
|
(InsertFunc*)list_store_insert);
|
||||||
|
|
||||||
|
gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (model),
|
||||||
|
compare, NULL, NULL);
|
||||||
|
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
|
||||||
|
GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
|
||||||
|
GTK_SORT_ASCENDING);
|
||||||
|
|
||||||
|
test_run ("list store insert (sorted)",
|
||||||
|
model,
|
||||||
|
(ClearFunc*)gtk_list_store_clear,
|
||||||
|
(InsertFunc*)list_store_insert);
|
||||||
|
|
||||||
|
g_object_unref (model);
|
||||||
|
|
||||||
|
model = GTK_TREE_MODEL (gtk_tree_store_new (2, G_TYPE_INT, G_TYPE_STRING));
|
||||||
|
|
||||||
|
test_run ("tree store append",
|
||||||
|
model,
|
||||||
|
(ClearFunc*)gtk_tree_store_clear,
|
||||||
|
(InsertFunc*)tree_store_append);
|
||||||
|
|
||||||
|
test_run ("tree store prepend",
|
||||||
|
model,
|
||||||
|
(ClearFunc*)gtk_tree_store_clear,
|
||||||
|
(InsertFunc*)tree_store_prepend);
|
||||||
|
|
||||||
|
test_run ("tree store insert (flat)",
|
||||||
|
model,
|
||||||
|
(ClearFunc*)gtk_tree_store_clear,
|
||||||
|
(InsertFunc*)tree_store_insert_flat);
|
||||||
|
|
||||||
|
test_run ("tree store insert (deep)",
|
||||||
|
model,
|
||||||
|
(ClearFunc*)gtk_tree_store_clear,
|
||||||
|
(InsertFunc*)tree_store_insert_deep);
|
||||||
|
|
||||||
|
gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (model),
|
||||||
|
compare, NULL, NULL);
|
||||||
|
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
|
||||||
|
GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
|
||||||
|
GTK_SORT_ASCENDING);
|
||||||
|
|
||||||
|
test_run ("tree store insert (flat, sorted)",
|
||||||
|
model,
|
||||||
|
(ClearFunc*)gtk_tree_store_clear,
|
||||||
|
(InsertFunc*)tree_store_insert_flat);
|
||||||
|
|
||||||
|
test_run ("tree store insert (deep, sorted)",
|
||||||
|
model,
|
||||||
|
(ClearFunc*)gtk_tree_store_clear,
|
||||||
|
(InsertFunc*)tree_store_insert_deep);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user