summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Hamann <lars@src.gnome.org>1998-07-15 23:40:00 +0000
committerLars Hamann <lars@src.gnome.org>1998-07-15 23:40:00 +0000
commit8b9b7b9d04c1f11118f28a9ec7b4c65a7a3f967c (patch)
treec85c8864d97e7306662c535a3680878f103376cc
parentb6656088162e00c77f9d84f96e5721c0b84dd5ec (diff)
downloadgdk-pixbuf-8b9b7b9d04c1f11118f28a9ec7b4c65a7a3f967c.tar.gz
Added focus handling, horizontal and vertical autoscrolling, extended
* gtk/gtkctree.h : * gtk/gtkctree.c : Added focus handling, horizontal and vertical autoscrolling, extended Selection Mode, key bindings Added gtk_ctree_toggle_expansion & gtk_ctree_toggle_expansion_recursive Changed gtk_ctree_scroll_to to gtk_ctree_moveto. Removed gtk_ctree_clear. * gtk/gtkclist.h : * gtk/gtkclist.c : Added focus handling, horizontal and vertical autoscrolling, extended Selection Mode, key bindings
-rw-r--r--ChangeLog16
-rw-r--r--ChangeLog.pre-2-016
-rw-r--r--ChangeLog.pre-2-1016
-rw-r--r--ChangeLog.pre-2-216
-rw-r--r--ChangeLog.pre-2-416
-rw-r--r--ChangeLog.pre-2-616
-rw-r--r--ChangeLog.pre-2-816
-rw-r--r--TODO8
-rw-r--r--gtk/gtkclist.c2833
-rw-r--r--gtk/gtkclist.h91
-rw-r--r--gtk/gtkctree.c1226
-rw-r--r--gtk/gtkctree.h24
-rw-r--r--gtk/testgtk.c239
-rw-r--r--tests/testgtk.c239
14 files changed, 3944 insertions, 828 deletions
diff --git a/ChangeLog b/ChangeLog
index 753c024af..43a7f540c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+Thu Jul 16 01:10:02 1998 Lars Hamann <lars@gtk.org>
+
+ * gtk/gtkctree.h :
+ * gtk/gtkctree.c :
+ Added focus handling, horizontal and vertical autoscrolling,
+ extended Selection Mode, key bindings
+ Added gtk_ctree_toggle_expansion & gtk_ctree_toggle_expansion_recursive
+ Changed gtk_ctree_scroll_to to gtk_ctree_moveto.
+ Removed gtk_ctree_clear.
+
+ * gtk/gtkclist.h :
+ * gtk/gtkclist.c :
+ Added focus handling, horizontal and vertical autoscrolling,
+ extended Selection Mode, key bindings
+
Wed Jul 15 12:39:27 1998 Raph Levien <raph@acm.org>
* This checkin integrates GdkRgb version 0.0.3 into the Gtk 1.1
@@ -30,6 +45,7 @@ Tue Jul 14 19:12:12 1998 Tim Janik <timj@gtk.org>
* gtk/gtkbutton.c (gtk_button_set_arg): don't destroy a buttons
child if it isn't a label.
+>>>>>>> 1.520
Tue Jul 14 11:41:38 1998 Tim Janik <timj@gtk.org>
* gtk/gtkdialog.h:
diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0
index 753c024af..43a7f540c 100644
--- a/ChangeLog.pre-2-0
+++ b/ChangeLog.pre-2-0
@@ -1,3 +1,18 @@
+Thu Jul 16 01:10:02 1998 Lars Hamann <lars@gtk.org>
+
+ * gtk/gtkctree.h :
+ * gtk/gtkctree.c :
+ Added focus handling, horizontal and vertical autoscrolling,
+ extended Selection Mode, key bindings
+ Added gtk_ctree_toggle_expansion & gtk_ctree_toggle_expansion_recursive
+ Changed gtk_ctree_scroll_to to gtk_ctree_moveto.
+ Removed gtk_ctree_clear.
+
+ * gtk/gtkclist.h :
+ * gtk/gtkclist.c :
+ Added focus handling, horizontal and vertical autoscrolling,
+ extended Selection Mode, key bindings
+
Wed Jul 15 12:39:27 1998 Raph Levien <raph@acm.org>
* This checkin integrates GdkRgb version 0.0.3 into the Gtk 1.1
@@ -30,6 +45,7 @@ Tue Jul 14 19:12:12 1998 Tim Janik <timj@gtk.org>
* gtk/gtkbutton.c (gtk_button_set_arg): don't destroy a buttons
child if it isn't a label.
+>>>>>>> 1.520
Tue Jul 14 11:41:38 1998 Tim Janik <timj@gtk.org>
* gtk/gtkdialog.h:
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index 753c024af..43a7f540c 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,3 +1,18 @@
+Thu Jul 16 01:10:02 1998 Lars Hamann <lars@gtk.org>
+
+ * gtk/gtkctree.h :
+ * gtk/gtkctree.c :
+ Added focus handling, horizontal and vertical autoscrolling,
+ extended Selection Mode, key bindings
+ Added gtk_ctree_toggle_expansion & gtk_ctree_toggle_expansion_recursive
+ Changed gtk_ctree_scroll_to to gtk_ctree_moveto.
+ Removed gtk_ctree_clear.
+
+ * gtk/gtkclist.h :
+ * gtk/gtkclist.c :
+ Added focus handling, horizontal and vertical autoscrolling,
+ extended Selection Mode, key bindings
+
Wed Jul 15 12:39:27 1998 Raph Levien <raph@acm.org>
* This checkin integrates GdkRgb version 0.0.3 into the Gtk 1.1
@@ -30,6 +45,7 @@ Tue Jul 14 19:12:12 1998 Tim Janik <timj@gtk.org>
* gtk/gtkbutton.c (gtk_button_set_arg): don't destroy a buttons
child if it isn't a label.
+>>>>>>> 1.520
Tue Jul 14 11:41:38 1998 Tim Janik <timj@gtk.org>
* gtk/gtkdialog.h:
diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2
index 753c024af..43a7f540c 100644
--- a/ChangeLog.pre-2-2
+++ b/ChangeLog.pre-2-2
@@ -1,3 +1,18 @@
+Thu Jul 16 01:10:02 1998 Lars Hamann <lars@gtk.org>
+
+ * gtk/gtkctree.h :
+ * gtk/gtkctree.c :
+ Added focus handling, horizontal and vertical autoscrolling,
+ extended Selection Mode, key bindings
+ Added gtk_ctree_toggle_expansion & gtk_ctree_toggle_expansion_recursive
+ Changed gtk_ctree_scroll_to to gtk_ctree_moveto.
+ Removed gtk_ctree_clear.
+
+ * gtk/gtkclist.h :
+ * gtk/gtkclist.c :
+ Added focus handling, horizontal and vertical autoscrolling,
+ extended Selection Mode, key bindings
+
Wed Jul 15 12:39:27 1998 Raph Levien <raph@acm.org>
* This checkin integrates GdkRgb version 0.0.3 into the Gtk 1.1
@@ -30,6 +45,7 @@ Tue Jul 14 19:12:12 1998 Tim Janik <timj@gtk.org>
* gtk/gtkbutton.c (gtk_button_set_arg): don't destroy a buttons
child if it isn't a label.
+>>>>>>> 1.520
Tue Jul 14 11:41:38 1998 Tim Janik <timj@gtk.org>
* gtk/gtkdialog.h:
diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4
index 753c024af..43a7f540c 100644
--- a/ChangeLog.pre-2-4
+++ b/ChangeLog.pre-2-4
@@ -1,3 +1,18 @@
+Thu Jul 16 01:10:02 1998 Lars Hamann <lars@gtk.org>
+
+ * gtk/gtkctree.h :
+ * gtk/gtkctree.c :
+ Added focus handling, horizontal and vertical autoscrolling,
+ extended Selection Mode, key bindings
+ Added gtk_ctree_toggle_expansion & gtk_ctree_toggle_expansion_recursive
+ Changed gtk_ctree_scroll_to to gtk_ctree_moveto.
+ Removed gtk_ctree_clear.
+
+ * gtk/gtkclist.h :
+ * gtk/gtkclist.c :
+ Added focus handling, horizontal and vertical autoscrolling,
+ extended Selection Mode, key bindings
+
Wed Jul 15 12:39:27 1998 Raph Levien <raph@acm.org>
* This checkin integrates GdkRgb version 0.0.3 into the Gtk 1.1
@@ -30,6 +45,7 @@ Tue Jul 14 19:12:12 1998 Tim Janik <timj@gtk.org>
* gtk/gtkbutton.c (gtk_button_set_arg): don't destroy a buttons
child if it isn't a label.
+>>>>>>> 1.520
Tue Jul 14 11:41:38 1998 Tim Janik <timj@gtk.org>
* gtk/gtkdialog.h:
diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6
index 753c024af..43a7f540c 100644
--- a/ChangeLog.pre-2-6
+++ b/ChangeLog.pre-2-6
@@ -1,3 +1,18 @@
+Thu Jul 16 01:10:02 1998 Lars Hamann <lars@gtk.org>
+
+ * gtk/gtkctree.h :
+ * gtk/gtkctree.c :
+ Added focus handling, horizontal and vertical autoscrolling,
+ extended Selection Mode, key bindings
+ Added gtk_ctree_toggle_expansion & gtk_ctree_toggle_expansion_recursive
+ Changed gtk_ctree_scroll_to to gtk_ctree_moveto.
+ Removed gtk_ctree_clear.
+
+ * gtk/gtkclist.h :
+ * gtk/gtkclist.c :
+ Added focus handling, horizontal and vertical autoscrolling,
+ extended Selection Mode, key bindings
+
Wed Jul 15 12:39:27 1998 Raph Levien <raph@acm.org>
* This checkin integrates GdkRgb version 0.0.3 into the Gtk 1.1
@@ -30,6 +45,7 @@ Tue Jul 14 19:12:12 1998 Tim Janik <timj@gtk.org>
* gtk/gtkbutton.c (gtk_button_set_arg): don't destroy a buttons
child if it isn't a label.
+>>>>>>> 1.520
Tue Jul 14 11:41:38 1998 Tim Janik <timj@gtk.org>
* gtk/gtkdialog.h:
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index 753c024af..43a7f540c 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,3 +1,18 @@
+Thu Jul 16 01:10:02 1998 Lars Hamann <lars@gtk.org>
+
+ * gtk/gtkctree.h :
+ * gtk/gtkctree.c :
+ Added focus handling, horizontal and vertical autoscrolling,
+ extended Selection Mode, key bindings
+ Added gtk_ctree_toggle_expansion & gtk_ctree_toggle_expansion_recursive
+ Changed gtk_ctree_scroll_to to gtk_ctree_moveto.
+ Removed gtk_ctree_clear.
+
+ * gtk/gtkclist.h :
+ * gtk/gtkclist.c :
+ Added focus handling, horizontal and vertical autoscrolling,
+ extended Selection Mode, key bindings
+
Wed Jul 15 12:39:27 1998 Raph Levien <raph@acm.org>
* This checkin integrates GdkRgb version 0.0.3 into the Gtk 1.1
@@ -30,6 +45,7 @@ Tue Jul 14 19:12:12 1998 Tim Janik <timj@gtk.org>
* gtk/gtkbutton.c (gtk_button_set_arg): don't destroy a buttons
child if it isn't a label.
+>>>>>>> 1.520
Tue Jul 14 11:41:38 1998 Tim Janik <timj@gtk.org>
* gtk/gtkdialog.h:
diff --git a/TODO b/TODO
index 1e66fee7a..7be80a442 100644
--- a/TODO
+++ b/TODO
@@ -5,14 +5,6 @@ For 1.2.0 release:
non-functional ones.
Bugs:
- * gtk_ctree_set_selection_mode should be a mere alias of
- gtk_clist_set_selection_mode, and clist should implement a new member
- function `set_selection_mode' (doesn't need to have a gtk_signal_new
- declaration) that can be overridden by ctree, this
- is needed for proper widget argument support on GtkCList basis.
- this applies similarly to `gtk_ctree_clear', one should be able to
- get the same effect by invoking gtk_clist_clear (GTK_CLIST (ctree));
-
* Widget redrawing when the window resizes sometimes messes up.
GtkLabels sometimes redraw without clearing up the underlying background on
window resizes.
diff --git a/gtk/gtkclist.c b/gtk/gtkclist.c
index 99674ee2c..f8cbe3326 100644
--- a/gtk/gtkclist.c
+++ b/gtk/gtkclist.c
@@ -18,8 +18,12 @@
* Boston, MA 02111-1307, USA.
*/
#include <stdlib.h>
+#include <string.h>
#include "../config.h"
+#include "gtkmain.h"
#include "gtkclist.h"
+#include "gtkbindings.h"
+#include <gdk/gdkkeysyms.h>
/* the number rows memchunk expands at a time */
#define CLIST_OPTIMUM_SIZE 512
@@ -36,6 +40,9 @@
/* added the horizontal space at the beginning and end of a row*/
#define COLUMN_INSET 3
+/* used for auto-scrolling */
+#define SCROLL_TIME 100
+
/* scrollbar spacing class macro */
#define SCROLLBAR_SPACING(w) (GTK_CLIST_CLASS (GTK_OBJECT (w)->klass)->scrollbar_spacing)
@@ -52,7 +59,7 @@
/* gives the left pixel of the given column in context of
* the clist's hoffset */
-#define COLUMN_LEFT_XPIXEL(clist, column) ((clist)->column[(column)].area.x + \
+#define COLUMN_LEFT_XPIXEL(clist, colnum) ((clist)->column[(colnum)].area.x + \
(clist)->hoffset)
/* returns the column index from a x pixel location in the
@@ -82,7 +89,7 @@ COLUMN_FROM_XPIXEL (GtkCList * clist,
/* returns the left pixel of the given column in the context of
* the list width */
-#define COLUMN_LEFT(clist, column) ((clist)->column[(column)].area.x)
+#define COLUMN_LEFT(clist, colnum) ((clist)->column[(colnum)].area.x)
/* returns the total height of the list */
#define LIST_HEIGHT(clist) (((clist)->row_height * ((clist)->rows)) + \
@@ -94,12 +101,26 @@ COLUMN_FROM_XPIXEL (GtkCList * clist,
COLUMN_INSET + CELL_SPACING)
+#define GTK_CLIST_CLASS_FW(_widget_) GTK_CLIST_CLASS (GTK_OBJECT (_widget_)->klass)
+
+
/* Signals */
enum
{
SELECT_ROW,
UNSELECT_ROW,
CLICK_COLUMN,
+ TOGGLE_FOCUS_ROW,
+ SELECT_ALL,
+ UNSELECT_ALL,
+ UNDO_SELECTION,
+ START_SELECTION,
+ END_SELECTION,
+ TOGGLE_ADD_MODE,
+ EXTEND_SELECTION,
+ SCROLL_VERTICAL,
+ SCROLL_HORIZONTAL,
+ ABORT_COLUMN_RESIZE,
LAST_SIGNAL
};
@@ -113,12 +134,24 @@ enum
typedef void (*GtkCListSignal1) (GtkObject * object,
gint arg1,
gint arg2,
- GdkEventButton * arg3,
+ GdkEvent * arg3,
gpointer data);
-typedef void (*GtkCListSignal2) (GtkObject * object,
+typedef void (*GtkCListSignal2) (GtkObject *object,
+ gpointer data);
+
+typedef void (*GtkCListSignal3) (GtkObject * object,
gint arg1,
gpointer data);
+typedef void (*GtkCListSignal4) (GtkObject * object,
+ gint arg1,
+ gfloat arg2,
+ gpointer data);
+typedef void (*GtkCListSignal5) (GtkObject * object,
+ gint arg1,
+ gfloat arg2,
+ gboolean arg3,
+ gpointer data);
static void sync_selection (GtkCList * clist,
@@ -128,6 +161,7 @@ static void sync_selection (GtkCList * clist,
/* GtkCList Methods */
static void gtk_clist_class_init (GtkCListClass * klass);
static void gtk_clist_init (GtkCList * clist);
+static void real_clear (GtkCList * clist);
/* GtkObject Methods */
static void gtk_clist_destroy (GtkObject * object);
@@ -149,7 +183,6 @@ static gint gtk_clist_button_release (GtkWidget * widget,
GdkEventButton * event);
static gint gtk_clist_motion (GtkWidget * widget,
GdkEventMotion * event);
-
static void gtk_clist_size_request (GtkWidget * widget,
GtkRequisition * requisition);
static void gtk_clist_size_allocate (GtkWidget * widget,
@@ -181,24 +214,42 @@ static void size_allocate_columns (GtkCList * clist);
static void toggle_row (GtkCList * clist,
gint row,
gint column,
- GdkEventButton * event);
+ GdkEvent * event);
static void select_row (GtkCList * clist,
gint row,
gint column,
- GdkEventButton * event);
+ GdkEvent * event);
static void unselect_row (GtkCList * clist,
gint row,
gint column,
- GdkEventButton * event);
-
+ GdkEvent * event);
static void real_select_row (GtkCList * clist,
gint row,
gint column,
- GdkEventButton * event);
+ GdkEvent * event);
static void real_unselect_row (GtkCList * clist,
gint row,
gint column,
- GdkEventButton * event);
+ GdkEvent * event);
+static void update_extended_selection (GtkCList *clist,
+ gint row);
+static GList * selection_find (GtkCList *clist,
+ gint row_number,
+ GList *row_list_element);
+static void real_select_all (GtkCList * clist);
+static void real_unselect_all (GtkCList * clist);
+static void move_vertical (GtkCList *clist,
+ gint row,
+ gfloat align);
+static void move_horizontal (GtkCList *clist,
+ gint diff);
+static void real_undo_selection (GtkCList * clist);
+static void fake_unselect_all (GtkCList *clist,
+ gint row);
+static void fake_toggle_row (GtkCList *clist,
+ gint row);
+static void resync_selection (GtkCList *clist,
+ GdkEvent *event);
/* Resize Columns */
static void draw_xor_line (GtkCList * clist);
@@ -209,6 +260,7 @@ static gint new_column_width (GtkCList * clist,
static void resize_column (GtkCList * clist,
gint column,
gint width);
+static void abort_column_resize (GtkCList *clist);
/* Buttons */
static void column_button_create (GtkCList * clist,
@@ -229,7 +281,6 @@ static void hadjustment_changed (GtkAdjustment * adjustment,
static void hadjustment_value_changed (GtkAdjustment * adjustment,
gpointer data);
-
/* Memory Allocation/Distruction Routines */
static GtkCListColumn *columns_new (GtkCList * clist);
@@ -262,6 +313,44 @@ static void cell_set_pixtext (GtkCList * clist,
GdkPixmap * pixmap,
GdkBitmap * mask);
+/* Focus handling */
+static void gtk_clist_draw_focus (GtkWidget *widget);
+static gint gtk_clist_focus_in (GtkWidget *widget,
+ GdkEventFocus *event);
+static gint gtk_clist_focus_out (GtkWidget *widget,
+ GdkEventFocus *event);
+static gint gtk_clist_focus (GtkContainer *container,
+ GtkDirectionType direction);
+static void gtk_clist_set_focus_child (GtkContainer *container,
+ GtkWidget *child);
+static gint gtk_clist_key_press (GtkWidget *widget,
+ GdkEventKey *event);
+
+/* Selection handling */
+static void set_anchor (GtkCList *clist,
+ gboolean add_mode,
+ gint anchor,
+ gint undo_anchor);
+static void start_selection (GtkCList *clist);
+static void end_selection (GtkCList *clist);
+
+static void toggle_add_mode (GtkCList *clist);
+static void toggle_focus_row (GtkCList *clist);
+static void move_focus_row (GtkCList *clist,
+ GtkScrollType scroll_type,
+ gfloat position);
+static void scroll_horizontal (GtkCList *clist,
+ GtkScrollType scroll_type,
+ gfloat position);
+static void scroll_vertical (GtkCList *clist,
+ GtkScrollType scroll_type,
+ gfloat position);
+static void extend_selection (GtkCList *clist,
+ GtkScrollType scroll_type,
+ gfloat position,
+ gboolean auto_start_selection);
+
+
/* Signals */
static void gtk_clist_marshal_signal_1 (GtkObject * object,
GtkSignalFunc func,
@@ -271,6 +360,20 @@ static void gtk_clist_marshal_signal_2 (GtkObject * object,
GtkSignalFunc func,
gpointer func_data,
GtkArg * args);
+static void gtk_clist_marshal_signal_3 (GtkObject * object,
+ GtkSignalFunc func,
+ gpointer func_data,
+ GtkArg * args);
+static void gtk_clist_marshal_signal_4 (GtkObject * object,
+ GtkSignalFunc func,
+ gpointer func_data,
+ GtkArg * args);
+static void gtk_clist_marshal_signal_5 (GtkObject * object,
+ GtkSignalFunc func,
+ gpointer func_data,
+ GtkArg * args);
+
+
/* Fill in data after widget is realized and has style */
@@ -295,8 +398,8 @@ gtk_clist_get_type (void)
(GtkClassInitFunc) gtk_clist_class_init,
(GtkObjectInitFunc) gtk_clist_init,
/* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
+ /* reserved_2 */ NULL,
+ (GtkClassInitFunc) NULL,
};
clist_type = gtk_type_unique (gtk_container_get_type (), &clist_info);
@@ -337,9 +440,89 @@ gtk_clist_class_init (GtkCListClass * klass)
GTK_RUN_FIRST,
object_class->type,
GTK_SIGNAL_OFFSET (GtkCListClass, click_column),
- gtk_clist_marshal_signal_2,
+ gtk_clist_marshal_signal_3,
GTK_TYPE_NONE, 1, GTK_TYPE_INT);
+ clist_signals[TOGGLE_FOCUS_ROW] =
+ gtk_signal_new ("toggle_focus_row",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (GtkCListClass, toggle_focus_row),
+ gtk_clist_marshal_signal_2,
+ GTK_TYPE_NONE, 0);
+ clist_signals[SELECT_ALL] =
+ gtk_signal_new ("select_all",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (GtkCListClass, select_all),
+ gtk_clist_marshal_signal_2,
+ GTK_TYPE_NONE, 0);
+ clist_signals[UNSELECT_ALL] =
+ gtk_signal_new ("unselect_all",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (GtkCListClass, unselect_all),
+ gtk_clist_marshal_signal_2,
+ GTK_TYPE_NONE, 0);
+ clist_signals[UNDO_SELECTION] =
+ gtk_signal_new ("undo_selection",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (GtkCListClass, undo_selection),
+ gtk_clist_marshal_signal_2,
+ GTK_TYPE_NONE, 0);
+ clist_signals[START_SELECTION] =
+ gtk_signal_new ("start_selection",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (GtkCListClass, start_selection),
+ gtk_clist_marshal_signal_2,
+ GTK_TYPE_NONE, 0);
+ clist_signals[END_SELECTION] =
+ gtk_signal_new ("end_selection",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (GtkCListClass, end_selection),
+ gtk_clist_marshal_signal_2,
+ GTK_TYPE_NONE, 0);
+ clist_signals[TOGGLE_ADD_MODE] =
+ gtk_signal_new ("toggle_add_mode",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (GtkCListClass, toggle_add_mode),
+ gtk_clist_marshal_signal_2,
+ GTK_TYPE_NONE, 0);
+ clist_signals[EXTEND_SELECTION] =
+ gtk_signal_new ("extend_selection",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (GtkCListClass, extend_selection),
+ gtk_clist_marshal_signal_5,
+ GTK_TYPE_NONE, 3,
+ GTK_TYPE_ENUM, GTK_TYPE_FLOAT, GTK_TYPE_BOOL);
+ clist_signals[SCROLL_VERTICAL] =
+ gtk_signal_new ("scroll_vertical",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (GtkCListClass, scroll_vertical),
+ gtk_clist_marshal_signal_4,
+ GTK_TYPE_NONE, 2, GTK_TYPE_ENUM, GTK_TYPE_FLOAT);
+ clist_signals[SCROLL_HORIZONTAL] =
+ gtk_signal_new ("scroll_horizontal",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (GtkCListClass, scroll_horizontal),
+ gtk_clist_marshal_signal_4,
+ GTK_TYPE_NONE, 2, GTK_TYPE_ENUM, GTK_TYPE_FLOAT);
+ clist_signals[ABORT_COLUMN_RESIZE] =
+ gtk_signal_new ("abort_column_resize",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (GtkCListClass, abort_column_resize),
+ gtk_clist_marshal_signal_2,
+ GTK_TYPE_NONE, 0);
+
+
gtk_object_class_add_signals (object_class, clist_signals, LAST_SIGNAL);
object_class->destroy = gtk_clist_destroy;
@@ -356,18 +539,230 @@ gtk_clist_class_init (GtkCListClass * klass)
widget_class->expose_event = gtk_clist_expose;
widget_class->size_request = gtk_clist_size_request;
widget_class->size_allocate = gtk_clist_size_allocate;
+ widget_class->key_press_event = gtk_clist_key_press;
+ widget_class->focus_in_event = gtk_clist_focus_in;
+ widget_class->focus_out_event = gtk_clist_focus_out;
+ widget_class->draw_focus = gtk_clist_draw_focus;
/* container_class->add = NULL; use the default GtkContainerClass warning */
/* container_class->remove = NULL; use the default GtkContainerClass warning */
container_class->foreach = gtk_clist_foreach;
+ container_class->focus = gtk_clist_focus;
+ container_class->set_focus_child = gtk_clist_set_focus_child;
klass->select_row = real_select_row;
klass->unselect_row = real_unselect_row;
+ klass->undo_selection = real_undo_selection;
+ klass->resync_selection = resync_selection;
+ klass->selection_find = selection_find;
klass->click_column = NULL;
-
klass->draw_row = draw_row;
+ klass->clear = real_clear;
+ klass->select_all = real_select_all;
+ klass->unselect_all = real_unselect_all;
+ klass->fake_unselect_all = fake_unselect_all;
+ klass->scroll_horizontal = scroll_horizontal;
+ klass->scroll_vertical = scroll_vertical;
+ klass->extend_selection = extend_selection;
+ klass->toggle_focus_row = toggle_focus_row;
+ klass->toggle_add_mode = toggle_add_mode;
+ klass->start_selection = start_selection;
+ klass->end_selection = end_selection;
+ klass->abort_column_resize = abort_column_resize;
klass->scrollbar_spacing = 5;
+
+ {
+ GtkBindingSet *binding_set;
+
+ binding_set = gtk_binding_set_by_class (klass);
+ gtk_binding_entry_add_signal (binding_set, GDK_Up, 0,
+ "scroll_vertical", 2,
+ GTK_TYPE_ENUM, GTK_SCROLL_STEP_BACKWARD,
+ GTK_TYPE_FLOAT, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_Down, 0,
+ "scroll_vertical", 2,
+ GTK_TYPE_ENUM, GTK_SCROLL_STEP_FORWARD,
+ GTK_TYPE_FLOAT, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_Page_Up, 0,
+ "scroll_vertical", 2,
+ GTK_TYPE_ENUM, GTK_SCROLL_PAGE_BACKWARD,
+ GTK_TYPE_FLOAT, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_Page_Down, 0,
+ "scroll_vertical", 2,
+ GTK_TYPE_ENUM, GTK_SCROLL_PAGE_FORWARD,
+ GTK_TYPE_FLOAT, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_Home, GDK_CONTROL_MASK,
+ "scroll_vertical", 2,
+ GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
+ GTK_TYPE_FLOAT, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_End, GDK_CONTROL_MASK,
+ "scroll_vertical", 2,
+ GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
+ GTK_TYPE_FLOAT, 1.0);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_Up, GDK_SHIFT_MASK,
+ "extend_selection", 3,
+ GTK_TYPE_ENUM, GTK_SCROLL_STEP_BACKWARD,
+ GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
+ gtk_binding_entry_add_signal (binding_set, GDK_Down, GDK_SHIFT_MASK,
+ "extend_selection", 3,
+ GTK_TYPE_ENUM, GTK_SCROLL_STEP_FORWARD,
+ GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
+ gtk_binding_entry_add_signal (binding_set, GDK_Page_Up, GDK_SHIFT_MASK,
+ "extend_selection", 3,
+ GTK_TYPE_ENUM, GTK_SCROLL_PAGE_BACKWARD,
+ GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
+ gtk_binding_entry_add_signal (binding_set, GDK_Page_Down, GDK_SHIFT_MASK,
+ "extend_selection", 3,
+ GTK_TYPE_ENUM, GTK_SCROLL_PAGE_FORWARD,
+ GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
+ gtk_binding_entry_add_signal (binding_set, GDK_Home,
+ GDK_SHIFT_MASK | GDK_CONTROL_MASK,
+ "extend_selection", 3,
+ GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
+ GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
+ gtk_binding_entry_add_signal (binding_set, GDK_End,
+ GDK_SHIFT_MASK | GDK_CONTROL_MASK,
+ "extend_selection", 3,
+ GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
+ GTK_TYPE_FLOAT, 1.0, GTK_TYPE_BOOL, TRUE);
+
+
+ gtk_binding_entry_add_signal (binding_set, GDK_Left, 0,
+ "scroll_horizontal", 2,
+ GTK_TYPE_ENUM, GTK_SCROLL_STEP_BACKWARD,
+ GTK_TYPE_FLOAT, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_Right, 0,
+ "scroll_horizontal", 2,
+ GTK_TYPE_ENUM, GTK_SCROLL_STEP_FORWARD,
+ GTK_TYPE_FLOAT, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_Home, 0,
+ "scroll_horizontal", 2,
+ GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
+ GTK_TYPE_FLOAT, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_End, 0,
+ "scroll_horizontal", 2,
+ GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
+ GTK_TYPE_FLOAT, 1.0);
+
+
+ gtk_binding_entry_add_signal (binding_set, GDK_Escape, 0,
+ "undo_selection", 0);
+ gtk_binding_entry_add_signal (binding_set, GDK_Escape, 0,
+ "abort_column_resize", 0);
+ gtk_binding_entry_add_signal (binding_set, GDK_space, 0,
+ "toggle_focus_row", 0);
+ gtk_binding_entry_add_signal (binding_set, GDK_space, GDK_CONTROL_MASK,
+ "toggle_add_mode", 0);
+ gtk_binding_entry_add_signal (binding_set, '/', GDK_CONTROL_MASK,
+ "select_all", 0);
+ gtk_binding_entry_add_signal (binding_set, '\\', GDK_CONTROL_MASK,
+ "unselect_all", 0);
+ gtk_binding_entry_add_signal (binding_set, GDK_Shift_L,
+ GDK_RELEASE_MASK | GDK_SHIFT_MASK,
+ "end_selection", 0);
+ gtk_binding_entry_add_signal (binding_set, GDK_Shift_R,
+ GDK_RELEASE_MASK | GDK_SHIFT_MASK,
+ "end_selection", 0);
+ }
+
+ /*
+ {
+ GtkBindingSet *binding_set;
+
+ binding_set = gtk_binding_set_by_class (klass);
+ gtk_binding_entry_add_signal (binding_set, GDK_Up, 0,
+ "scroll_vertical", 2,
+ GTK_TYPE_ENUM, GTK_SCROLL_STEP_BACKWARD,
+ GTK_TYPE_FLOAT, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_Down, 0,
+ "scroll_vertical", 2,
+ GTK_TYPE_ENUM, GTK_SCROLL_STEP_FORWARD,
+ GTK_TYPE_FLOAT, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_Page_Up, 0,
+ "scroll_vertical", 2,
+ GTK_TYPE_ENUM, GTK_SCROLL_PAGE_BACKWARD,
+ GTK_TYPE_FLOAT, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_Page_Down, 0,
+ "scroll_vertical", 2,
+ GTK_TYPE_ENUM, GTK_SCROLL_PAGE_FORWARD,
+ GTK_TYPE_FLOAT, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_Home, GDK_CONTROL_MASK,
+ "scroll_vertical", 2,
+ GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
+ GTK_TYPE_FLOAT, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_End, GDK_CONTROL_MASK,
+ "scroll_vertical", 2,
+ GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
+ GTK_TYPE_FLOAT, 0);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_KP_Up, 0,
+ "extend_selection", 3,
+ GTK_TYPE_ENUM, GTK_SCROLL_STEP_BACKWARD,
+ GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
+ gtk_binding_entry_add_signal (binding_set, GDK_KP_Down, 0,
+ "extend_selection", 3,
+ GTK_TYPE_ENUM, GTK_SCROLL_STEP_FORWARD,
+ GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
+ gtk_binding_entry_add_signal (binding_set, GDK_KP_Page_Up, 0,
+ "extend_selection", 3,
+ GTK_TYPE_ENUM, GTK_SCROLL_PAGE_BACKWARD,
+ GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
+ gtk_binding_entry_add_signal (binding_set, GDK_KP_Page_Down, 0,
+ "extend_selection", 3,
+ GTK_TYPE_ENUM, GTK_SCROLL_PAGE_FORWARD,
+ GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
+ gtk_binding_entry_add_signal (binding_set, GDK_KP_Home, 0,
+ "extend_selection", 3,
+ GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
+ GTK_TYPE_FLOAT, 0.0, GTK_TYPE_BOOL, TRUE);
+ gtk_binding_entry_add_signal (binding_set, GDK_KP_End, 0,
+ "extend_selection", 3,
+ GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
+ GTK_TYPE_FLOAT, 1.0, GTK_TYPE_BOOL, TRUE);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_Left, 0,
+ "scroll_horizontal", 2,
+ GTK_TYPE_ENUM, GTK_SCROLL_STEP_BACKWARD,
+ GTK_TYPE_FLOAT, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_KP_Left, 0,
+ "scroll_horizontal", 2,
+ GTK_TYPE_ENUM, GTK_SCROLL_STEP_BACKWARD,
+ GTK_TYPE_FLOAT, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_Right, 0,
+ "scroll_horizontal", 2,
+ GTK_TYPE_ENUM, GTK_SCROLL_STEP_FORWARD,
+ GTK_TYPE_FLOAT, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_KP_Right, 0,
+ "scroll_horizontal", 2,
+ GTK_TYPE_ENUM, GTK_SCROLL_STEP_FORWARD,
+ GTK_TYPE_FLOAT, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_Home, 0,
+ "scroll_horizontal", 2,
+ GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
+ GTK_TYPE_FLOAT, 0.0);
+ gtk_binding_entry_add_signal (binding_set, GDK_End, 0,
+ "sroll_horizontal", 2,
+ GTK_TYPE_ENUM, GTK_SCROLL_JUMP,
+ GTK_TYPE_FLOAT, 1.0);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_KP_Divide, 0,
+ "undo_selection", 0);
+ gtk_binding_entry_add_signal (binding_set, GDK_Escape, 0,
+ "abort_column_resize", 0);
+ gtk_binding_entry_add_signal (binding_set, GDK_space, 0,
+ "toggle_focus_row", 0);
+ gtk_binding_entry_add_signal (binding_set, GDK_KP_Multiply, 0,
+ "toggle_add_mode", 0);
+ gtk_binding_entry_add_signal (binding_set, GDK_KP_Add, 0,
+ "select_all", 0);
+ gtk_binding_entry_add_signal (binding_set, GDK_KP_Subtract, 0,
+ "unselect_all", 0);
+ gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0,
+ "end_selection", 0);
+ }
+ */
}
static void
@@ -396,8 +791,48 @@ gtk_clist_marshal_signal_2 (GtkObject * object,
rfunc = (GtkCListSignal2) func;
+ (*rfunc) (object, func_data);
+}
+
+static void
+gtk_clist_marshal_signal_3 (GtkObject * object,
+ GtkSignalFunc func,
+ gpointer func_data,
+ GtkArg * args)
+{
+ GtkCListSignal3 rfunc;
+
+ rfunc = (GtkCListSignal3) func;
+
+ (*rfunc) (object, GTK_VALUE_INT (args[0]), func_data);
+}
+
+static void
+gtk_clist_marshal_signal_4 (GtkObject * object,
+ GtkSignalFunc func,
+ gpointer func_data,
+ GtkArg * args)
+{
+ GtkCListSignal4 rfunc;
+
+ rfunc = (GtkCListSignal4) func;
+
(*rfunc) (object, GTK_VALUE_INT (args[0]),
- func_data);
+ GTK_VALUE_FLOAT (args[1]), func_data);
+}
+
+static void
+gtk_clist_marshal_signal_5 (GtkObject * object,
+ GtkSignalFunc func,
+ gpointer func_data,
+ GtkArg * args)
+{
+ GtkCListSignal5 rfunc;
+
+ rfunc = (GtkCListSignal5) func;
+
+ (*rfunc) (object, GTK_VALUE_INT (args[0]), GTK_VALUE_FLOAT (args[1]),
+ GTK_VALUE_BOOL (args[2]), func_data);
}
static void
@@ -444,6 +879,20 @@ gtk_clist_init (GtkCList * clist)
clist->selection_mode = GTK_SELECTION_SINGLE;
clist->selection = NULL;
+ clist->selection_end = NULL;
+ clist->undo_selection = NULL;
+ clist->undo_unselection = NULL;
+
+ GTK_WIDGET_SET_FLAGS (clist, GTK_CAN_FOCUS);
+ GTK_CLIST_SET_FLAG (clist, CLIST_CHILD_HAS_FOCUS);
+ clist->focus_row = -1;
+ clist->undo_anchor = -1;
+
+ clist->anchor = -1;
+ clist->anchor_state = GTK_STATE_SELECTED;
+ clist->drag_pos = -1;
+ clist->htimer = 0;
+ clist->vtimer = 0;
}
/* Constructors */
@@ -537,6 +986,7 @@ gtk_clist_set_border (GtkCList * clist,
GtkShadowType border)
{
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
clist->shadow_type = border;
@@ -549,14 +999,39 @@ gtk_clist_set_selection_mode (GtkCList * clist,
GtkSelectionMode mode)
{
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
+
+ if (mode == clist->selection_mode)
+ return;
clist->selection_mode = mode;
+ clist->anchor = -1;
+ clist->anchor_state = GTK_STATE_SELECTED;
+ clist->drag_pos = -1;
+ clist->undo_anchor = clist->focus_row;
+
+ g_list_free (clist->undo_selection);
+ g_list_free (clist->undo_unselection);
+ clist->undo_selection = NULL;
+ clist->undo_unselection = NULL;
+
+ switch (mode)
+ {
+ case GTK_SELECTION_MULTIPLE:
+ case GTK_SELECTION_EXTENDED:
+ return;
+ case GTK_SELECTION_BROWSE:
+ case GTK_SELECTION_SINGLE:
+ gtk_clist_unselect_all (clist);
+ break;
+ }
}
void
gtk_clist_freeze (GtkCList * clist)
{
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
GTK_CLIST_SET_FLAG (clist, CLIST_FROZEN);
}
@@ -565,6 +1040,7 @@ void
gtk_clist_thaw (GtkCList * clist)
{
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
GTK_CLIST_UNSET_FLAG (clist, CLIST_FROZEN);
@@ -576,6 +1052,7 @@ void
gtk_clist_column_titles_show (GtkCList * clist)
{
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
if (!GTK_CLIST_SHOW_TITLES (clist))
{
@@ -590,6 +1067,7 @@ void
gtk_clist_column_titles_hide (GtkCList * clist)
{
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
if (GTK_CLIST_SHOW_TITLES (clist))
{
@@ -605,6 +1083,7 @@ gtk_clist_column_title_active (GtkCList * clist,
gint column)
{
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
if (column < 0 || column >= clist->columns)
return;
@@ -623,6 +1102,7 @@ gtk_clist_column_title_passive (GtkCList * clist,
gint column)
{
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
if (column < 0 || column >= clist->columns)
return;
@@ -642,6 +1122,7 @@ gtk_clist_column_titles_active (GtkCList * clist)
gint i;
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
for (i = 0; i < clist->columns; i++)
if (clist->column[i].button)
@@ -654,6 +1135,7 @@ gtk_clist_column_titles_passive (GtkCList * clist)
gint i;
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
for (i = 0; i < clist->columns; i++)
if (clist->column[i].button)
@@ -671,6 +1153,7 @@ gtk_clist_set_column_title (GtkCList * clist,
GtkWidget *label;
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
if (column < 0 || column >= clist->columns)
return;
@@ -731,6 +1214,7 @@ gtk_clist_set_column_widget (GtkCList * clist,
GtkWidget *old_widget;
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
if (column < 0 || column >= clist->columns)
return;
@@ -771,6 +1255,7 @@ gtk_clist_set_column_justification (GtkCList * clist,
GtkWidget *alignment;
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
if (column < 0 || column >= clist->columns)
return;
@@ -816,6 +1301,7 @@ gtk_clist_set_column_width (GtkCList * clist,
gint width)
{
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
if (column < 0 || column >= clist->columns)
return;
@@ -844,6 +1330,7 @@ gtk_clist_set_row_height (GtkCList * clist,
gint text_height;
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
if (height > 0)
clist->row_height = height;
@@ -873,51 +1360,40 @@ gtk_clist_moveto (GtkCList * clist,
gfloat row_align,
gfloat col_align)
{
- gint x, y;
-
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
if (row < -1 || row >= clist->rows)
return;
if (column < -1 || column >= clist->columns)
return;
- /* adjust vertical scrollbar */
- if (row >= 0)
- {
- x = ROW_TOP (clist, row) - (row_align * (clist->clist_window_height -
- (clist->row_height + 2 * CELL_SPACING)));
-
- if (x < 0)
- GTK_RANGE (clist->vscrollbar)->adjustment->value = 0.0;
- else if (x > LIST_HEIGHT (clist) - clist->clist_window_height)
- GTK_RANGE (clist->vscrollbar)->adjustment->value = LIST_HEIGHT (clist) -
- clist->clist_window_height;
- else
- GTK_RANGE (clist->vscrollbar)->adjustment->value = x;
-
- gtk_signal_emit_by_name (GTK_OBJECT (GTK_RANGE (clist->vscrollbar)->adjustment),
- "value_changed");
- }
-
+ row_align = CLAMP (row_align, 0, 1);
+ col_align = CLAMP (col_align, 0, 1);
+
/* adjust horizontal scrollbar */
if (column >= 0)
{
- y = COLUMN_LEFT (clist, column) - (col_align * (clist->clist_window_width -
- clist->column[column].area.width +
- 2 * (CELL_SPACING + COLUMN_INSET)));
-
- if (y < 0)
- GTK_RANGE (clist->hscrollbar)->adjustment->value = 0.0;
- else if (y > LIST_WIDTH (clist) - clist->clist_window_width)
- GTK_RANGE (clist->hscrollbar)->adjustment->value = LIST_WIDTH (clist) -
- clist->clist_window_width;
+ GtkAdjustment *adj;
+ gint x;
+
+ adj = GTK_RANGE (clist->hscrollbar)->adjustment;
+
+ x = COLUMN_LEFT (clist, column) - CELL_SPACING - COLUMN_INSET -
+ (col_align * (clist->clist_window_width - 2 * COLUMN_INSET -
+ CELL_SPACING - clist->column[column].area.width));
+ if (x < 0)
+ gtk_adjustment_set_value (adj, 0.0);
+ else if (x > LIST_WIDTH (clist) - clist->clist_window_width)
+ gtk_adjustment_set_value
+ (adj, LIST_WIDTH (clist) - clist->clist_window_width);
else
- GTK_RANGE (clist->hscrollbar)->adjustment->value = y;
-
- gtk_signal_emit_by_name (GTK_OBJECT (GTK_RANGE (clist->hscrollbar)->adjustment),
- "value_changed");
+ gtk_adjustment_set_value (adj, x);
}
+
+ /* adjust vertical scrollbar */
+ if (row >= 0)
+ move_vertical (clist, row, row_align);
}
GtkCellType
@@ -928,6 +1404,7 @@ gtk_clist_get_cell_type (GtkCList * clist,
GtkCListRow *clist_row;
g_return_val_if_fail (clist != NULL, -1);
+ g_return_val_if_fail (GTK_IS_CLIST (clist), -1);
if (row < 0 || row >= clist->rows)
return -1;
@@ -948,6 +1425,7 @@ gtk_clist_set_text (GtkCList * clist,
GtkCListRow *clist_row;
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
if (row < 0 || row >= clist->rows)
return;
@@ -966,8 +1444,7 @@ gtk_clist_set_text (GtkCList * clist,
if (!GTK_CLIST_FROZEN (clist))
{
if (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE)
- (GTK_CLIST_CLASS (GTK_OBJECT (clist)->klass)->draw_row)
- (clist, NULL, row, clist_row);
+ GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row);
}
}
@@ -980,6 +1457,7 @@ gtk_clist_get_text (GtkCList * clist,
GtkCListRow *clist_row;
g_return_val_if_fail (clist != NULL, 0);
+ g_return_val_if_fail (GTK_IS_CLIST (clist), 0);
if (row < 0 || row >= clist->rows)
return 0;
@@ -1007,6 +1485,7 @@ gtk_clist_set_pixmap (GtkCList * clist,
GtkCListRow *clist_row;
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
if (row < 0 || row >= clist->rows)
return;
@@ -1025,8 +1504,7 @@ gtk_clist_set_pixmap (GtkCList * clist,
if (!GTK_CLIST_FROZEN (clist))
{
if (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE)
- (GTK_CLIST_CLASS (GTK_OBJECT (clist)->klass)->draw_row)
- (clist, NULL, row, clist_row);
+ GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row);
}
}
@@ -1040,6 +1518,7 @@ gtk_clist_get_pixmap (GtkCList * clist,
GtkCListRow *clist_row;
g_return_val_if_fail (clist != NULL, 0);
+ g_return_val_if_fail (GTK_IS_CLIST (clist), 0);
if (row < 0 || row >= clist->rows)
return 0;
@@ -1073,6 +1552,7 @@ gtk_clist_set_pixtext (GtkCList * clist,
GtkCListRow *clist_row;
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
if (row < 0 || row >= clist->rows)
return;
@@ -1089,8 +1569,7 @@ gtk_clist_set_pixtext (GtkCList * clist,
if (!GTK_CLIST_FROZEN (clist))
{
if (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE)
- (GTK_CLIST_CLASS (GTK_OBJECT (clist)->klass)->draw_row)
- (clist, NULL, row, clist_row);
+ GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row);
}
}
@@ -1106,6 +1585,7 @@ gtk_clist_get_pixtext (GtkCList * clist,
GtkCListRow *clist_row;
g_return_val_if_fail (clist != NULL, 0);
+ g_return_val_if_fail (GTK_IS_CLIST (clist), 0);
if (row < 0 || row >= clist->rows)
return 0;
@@ -1138,6 +1618,7 @@ gtk_clist_set_foreground (GtkCList * clist,
GtkCListRow *clist_row;
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
if (row < 0 || row >= clist->rows)
return;
@@ -1154,8 +1635,7 @@ gtk_clist_set_foreground (GtkCList * clist,
if (!GTK_CLIST_FROZEN (clist)
&& (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE))
- (GTK_CLIST_CLASS (GTK_OBJECT (clist)->klass)->draw_row)
- (clist, NULL, row, clist_row);
+ GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row);
}
void
@@ -1166,6 +1646,7 @@ gtk_clist_set_background (GtkCList * clist,
GtkCListRow *clist_row;
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
if (row < 0 || row >= clist->rows)
return;
@@ -1182,8 +1663,7 @@ gtk_clist_set_background (GtkCList * clist,
if (!GTK_CLIST_FROZEN (clist)
&& (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE))
- (GTK_CLIST_CLASS (GTK_OBJECT (clist)->klass)->draw_row)
- (clist, NULL, row, clist_row);
+ GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row);
}
void
@@ -1196,6 +1676,7 @@ gtk_clist_set_shift (GtkCList * clist,
GtkCListRow *clist_row;
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
if (row < 0 || row >= clist->rows)
return;
@@ -1209,8 +1690,7 @@ gtk_clist_set_shift (GtkCList * clist,
if (!GTK_CLIST_FROZEN (clist)
&& (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE))
- (GTK_CLIST_CLASS (GTK_OBJECT (clist)->klass)->draw_row)
- (clist, NULL, row, clist_row);
+ GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row);
}
gint
@@ -1221,6 +1701,7 @@ gtk_clist_append (GtkCList * clist,
GtkCListRow *clist_row;
g_return_val_if_fail (clist != NULL, -1);
+ g_return_val_if_fail (GTK_IS_CLIST (clist), -1);
clist_row = row_new (clist);
clist->rows++;
@@ -1243,7 +1724,7 @@ gtk_clist_append (GtkCList * clist,
switch (clist->selection_mode)
{
case GTK_SELECTION_BROWSE:
- gtk_clist_select_row (clist, 0, -1);
+ select_row (clist, 0, -1, NULL);
break;
default:
@@ -1275,6 +1756,7 @@ gtk_clist_insert (GtkCList * clist,
GtkCListRow *clist_row;
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
g_return_if_fail (text != NULL);
/* return if out of bounds */
@@ -1303,6 +1785,9 @@ gtk_clist_insert (GtkCList * clist,
clist->rows++;
+ if (row < ROW_FROM_YPIXEL (clist, 0))
+ clist->voffset -= (clist->row_height + CELL_SPACING);
+
/* syncronize the selection list */
sync_selection (clist, row, SYNC_INSERT);
}
@@ -1326,6 +1811,7 @@ gtk_clist_remove (GtkCList * clist,
GtkCListRow *clist_row;
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
/* return if out of bounds */
if (row < 0 || row > (clist->rows - 1))
@@ -1344,14 +1830,16 @@ gtk_clist_remove (GtkCList * clist,
* removal */
if (clist_row->state == GTK_STATE_SELECTED)
{
- was_selected = 1;
-
switch (clist->selection_mode)
{
case GTK_SELECTION_SINGLE:
- case GTK_SELECTION_BROWSE:
case GTK_SELECTION_MULTIPLE:
- gtk_clist_unselect_row (clist, row, -1);
+ case GTK_SELECTION_EXTENDED:
+ unselect_row (clist, row, -1, NULL);
+ break;
+
+ case GTK_SELECTION_BROWSE:
+ select_row (clist, row - 1, -1, NULL);
break;
default:
@@ -1363,27 +1851,16 @@ gtk_clist_remove (GtkCList * clist,
* end of the list */
if (row == clist->rows - 1)
clist->row_list_end = list->prev;
+ if (row >= clist->focus_row && clist->focus_row >=0)
+ clist->focus_row--;
clist->row_list = g_list_remove (clist->row_list, clist_row);
clist->rows--;
- sync_selection (clist, row, SYNC_REMOVE);
-
- /* preform any selections required by the selection mode */
- if (was_selected)
- {
- switch (clist->selection_mode)
- {
- case GTK_SELECTION_BROWSE:
- if (row == clist->rows)
- gtk_clist_select_row (clist, row - 1, -1);
- else
- gtk_clist_select_row (clist, row, -1);
- break;
+
+ if (row < ROW_FROM_YPIXEL (clist, 0))
+ clist->voffset += clist->row_height + CELL_SPACING;
- default:
- break;
- }
- }
+ sync_selection (clist, row, SYNC_REMOVE);
/* toast the row */
row_delete (clist, clist_row);
@@ -1404,25 +1881,37 @@ sync_selection (GtkCList * clist,
gint mode)
{
GList *list;
-
- list = clist->selection;
- while (list)
+ gint d;
+
+ if (mode == SYNC_INSERT)
+ d = 1;
+ else
+ d = -1;
+
+ if (clist->focus_row >= row)
{
- if (GPOINTER_TO_INT (list->data) >= row)
- switch (mode)
- {
- case SYNC_INSERT:
- list->data = ((gchar*) list->data) + 1;
- break;
+ clist->focus_row += d;
+ if (clist->focus_row == -1 && clist->rows >= 1)
+ clist->focus_row = 0;
+ }
- case SYNC_REMOVE:
- list->data = ((gchar*) list->data) - 1;
- break;
+ if (clist->selection_mode == GTK_SELECTION_BROWSE && clist->anchor != -1)
+ GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
- default:
- break;
- }
+ g_list_free (clist->undo_selection);
+ g_list_free (clist->undo_unselection);
+ clist->undo_selection = NULL;
+ clist->undo_unselection = NULL;
+ clist->anchor = -1;
+ clist->drag_pos = -1;
+ clist->undo_anchor = clist->focus_row;
+
+ list = clist->selection;
+ while (list)
+ {
+ if (GPOINTER_TO_INT (list->data) >= row)
+ list->data = ((gchar*) list->data) + d;
list = list->next;
}
}
@@ -1430,28 +1919,41 @@ sync_selection (GtkCList * clist,
void
gtk_clist_clear (GtkCList * clist)
{
+ GTK_CLIST_CLASS_FW (clist)->clear (clist);
+}
+
+static void
+real_clear (GtkCList * clist)
+{
GList *list;
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
/* remove all the rows */
for (list = clist->row_list; list; list = list->next)
- {
- GtkCListRow *clist_row;
+ row_delete (clist, GTK_CLIST_ROW (list));
- clist_row = list->data;
- row_delete (clist, clist_row);
- }
g_list_free (clist->row_list);
/* free up the selection list */
g_list_free (clist->selection);
+ g_list_free (clist->undo_selection);
+ g_list_free (clist->undo_unselection);
clist->row_list = NULL;
clist->row_list_end = NULL;
clist->selection = NULL;
+ clist->selection_end = NULL;
+ clist->undo_selection = NULL;
+ clist->undo_unselection = NULL;
clist->voffset = 0;
clist->rows = 0;
+ clist->focus_row = -1;
+ clist->anchor = -1;
+ clist->undo_anchor = -1;
+ clist->anchor_state = GTK_STATE_SELECTED;
+ clist->drag_pos = -1;
/* zero-out the scrollbars */
if (clist->vscrollbar)
@@ -1460,10 +1962,7 @@ gtk_clist_clear (GtkCList * clist)
gtk_signal_emit_by_name (GTK_OBJECT (GTK_RANGE (clist->vscrollbar)->adjustment), "changed");
if (!GTK_CLIST_FROZEN (clist))
- {
- adjust_scrollbars (clist);
- draw_rows (clist, NULL);
- }
+ gtk_clist_thaw (clist);
}
}
@@ -1477,6 +1976,7 @@ gtk_clist_swap_rows (GtkCList * clist,
gpointer swap;
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
if (row1 < 0 || row1 > (clist->rows - 1))
return;
@@ -1509,12 +2009,12 @@ gtk_clist_swap_rows (GtkCList * clist,
if (!GTK_CLIST_FROZEN (clist))
{
if (gtk_clist_row_is_visible (clist, row1) != GTK_VISIBILITY_NONE)
- (GTK_CLIST_CLASS (GTK_OBJECT (clist)->klass)->draw_row)
- (clist, NULL, row1, (GtkCListRow *) link2->data);
+ GTK_CLIST_CLASS_FW (clist)->draw_row
+ (clist, NULL, row1, GTK_CLIST_ROW (link2));
if (gtk_clist_row_is_visible (clist, row2) != GTK_VISIBILITY_NONE)
- (GTK_CLIST_CLASS (GTK_OBJECT (clist)->klass)->draw_row)
- (clist, NULL, row2, (GtkCListRow *) link1->data);
+ GTK_CLIST_CLASS_FW (clist)->draw_row
+ (clist, NULL, row2, GTK_CLIST_ROW (link1));
}
}
@@ -1535,6 +2035,7 @@ gtk_clist_set_row_data_full (GtkCList * clist,
GtkCListRow *clist_row;
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
if (row < 0 || row > (clist->rows - 1))
return;
@@ -1547,7 +2048,7 @@ gtk_clist_set_row_data_full (GtkCList * clist,
* so the application can respond to the new data --
* this could be questionable behavior */
if (clist_row->state == GTK_STATE_SELECTED)
- gtk_clist_select_row (clist, row, -1);
+ select_row (clist, row, -1, NULL);
}
gpointer
@@ -1557,6 +2058,7 @@ gtk_clist_get_row_data (GtkCList * clist,
GtkCListRow *clist_row;
g_return_val_if_fail (clist != NULL, NULL);
+ g_return_val_if_fail (GTK_IS_CLIST (clist), NULL);
if (row < 0 || row > (clist->rows - 1))
return NULL;
@@ -1578,21 +2080,9 @@ gtk_clist_find_row_from_data (GtkCList * clist,
if (clist->rows < 1)
return -1; /* is this an optimization or just worthless? */
- n = 0;
- list = clist->row_list;
- while (list)
- {
- GtkCListRow *clist_row;
-
- clist_row = list->data;
- if (clist_row->data == data)
- break;
- n++;
- list = list->next;
- }
-
- if (list)
- return n;
+ for (n = 0, list = clist->row_list; list; n++, list = list->next)
+ if (GTK_CLIST_ROW (list)->data == data)
+ return n;
return -1;
}
@@ -1603,6 +2093,7 @@ gtk_clist_select_row (GtkCList * clist,
gint column)
{
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
if (row < 0 || row >= clist->rows)
return;
@@ -1619,6 +2110,7 @@ gtk_clist_unselect_row (GtkCList * clist,
gint column)
{
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
if (row < 0 || row >= clist->rows)
return;
@@ -1636,6 +2128,7 @@ gtk_clist_row_is_visible (GtkCList * clist,
gint top;
g_return_val_if_fail (clist != NULL, 0);
+ g_return_val_if_fail (GTK_IS_CLIST (clist), 0);
if (row < 0 || row >= clist->rows)
return GTK_VISIBILITY_NONE;
@@ -1658,7 +2151,7 @@ gtk_clist_row_is_visible (GtkCList * clist,
return GTK_VISIBILITY_FULL;
}
-GtkAdjustment*
+GtkAdjustment *
gtk_clist_get_vadjustment (GtkCList * clist)
{
g_return_val_if_fail (clist != NULL, NULL);
@@ -1667,7 +2160,7 @@ gtk_clist_get_vadjustment (GtkCList * clist)
return gtk_range_get_adjustment (GTK_RANGE (clist->vscrollbar));
}
-GtkAdjustment*
+GtkAdjustment *
gtk_clist_get_hadjustment (GtkCList * clist)
{
g_return_val_if_fail (clist != NULL, NULL);
@@ -1701,6 +2194,69 @@ gtk_clist_set_policy (GtkCList * clist,
}
}
+void
+gtk_clist_undo_selection (GtkCList *clist)
+{
+ g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
+
+ if (clist->selection_mode == GTK_SELECTION_EXTENDED &&
+ (clist->undo_selection || clist->undo_unselection))
+ gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNDO_SELECTION]);
+}
+
+static void
+real_undo_selection (GtkCList *clist)
+{
+ GList *work;
+
+ g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
+
+ if (gdk_pointer_is_grabbed () ||
+ clist->selection_mode != GTK_SELECTION_EXTENDED)
+ return;
+
+ if (clist->anchor >= 0)
+ resync_selection (clist, NULL);
+
+ if (!(clist->undo_selection || clist->undo_unselection))
+ {
+ gtk_clist_unselect_all (clist);
+ return;
+ }
+
+ for (work = clist->undo_selection; work; work = work->next)
+ gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW],
+ GPOINTER_TO_INT (work->data), -1, NULL);
+
+ for (work = clist->undo_unselection; work; work = work->next)
+ gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNSELECT_ROW],
+ GPOINTER_TO_INT (work->data), -1, NULL);
+
+ if (GTK_WIDGET_HAS_FOCUS (clist) && clist->focus_row != clist->undo_anchor)
+ {
+ gtk_clist_draw_focus (GTK_WIDGET (clist));
+ clist->focus_row = clist->undo_anchor;
+ gtk_clist_draw_focus (GTK_WIDGET (clist));
+ }
+ else
+ clist->focus_row = clist->undo_anchor;
+
+ clist->undo_anchor = -1;
+
+ g_list_free (clist->undo_selection);
+ g_list_free (clist->undo_unselection);
+ clist->undo_selection = NULL;
+ clist->undo_unselection = NULL;
+
+ if (ROW_TOP_YPIXEL (clist, clist->focus_row) + clist->row_height >
+ clist->clist_window_height)
+ gtk_clist_moveto (clist, clist->focus_row, -1, 1, 0);
+ else if (ROW_TOP_YPIXEL (clist, clist->focus_row) < 0)
+ gtk_clist_moveto (clist, clist->focus_row, -1, 0, 0);
+}
+
/*
* GTKOBJECT
* gtk_clist_destroy
@@ -1742,6 +2298,17 @@ gtk_clist_destroy (GtkObject * object)
clist->hscrollbar = NULL;
}
+ if (clist->htimer)
+ {
+ gtk_timeout_remove (clist->htimer);
+ clist->htimer = 0;
+ }
+ if (clist->vtimer)
+ {
+ gtk_timeout_remove (clist->vtimer);
+ clist->vtimer = 0;
+ }
+
/* destroy the column buttons */
for (i = 0; i < clist->columns; i++)
if (clist->column[i].button)
@@ -1820,10 +2387,10 @@ gtk_clist_realize (GtkWidget * widget)
attributes.event_mask |= (GDK_EXPOSURE_MASK |
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
- GDK_KEY_PRESS_MASK);
+ GDK_KEY_PRESS_MASK |
+ GDK_KEY_RELEASE_MASK);
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
-
/* main window */
widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
gdk_window_set_user_data (widget->window, clist);
@@ -1870,7 +2437,8 @@ gtk_clist_realize (GtkWidget * widget)
attributes.event_mask = (GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_POINTER_MOTION_MASK |
- GDK_POINTER_MOTION_HINT_MASK);
+ GDK_POINTER_MOTION_HINT_MASK |
+ GDK_KEY_PRESS_MASK);
attributes.cursor = clist->cursor_drag = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW);
attributes_mask = GDK_WA_CURSOR;
@@ -2104,7 +2672,10 @@ gtk_clist_button_press (GtkWidget * widget,
{
gint i;
GtkCList *clist;
- gint x, y, row, column;
+ gint x;
+ gint y;
+ gint row;
+ gint column;
g_return_val_if_fail (widget != NULL, FALSE);
g_return_val_if_fail (GTK_IS_CLIST (widget), FALSE);
@@ -2112,6 +2683,10 @@ gtk_clist_button_press (GtkWidget * widget,
clist = GTK_CLIST (widget);
+ /* we don't handle button 2 and 3 */
+ if (event->button != 1)
+ return FALSE;
+
/* selections on the list */
if (event->window == clist->clist_window)
{
@@ -2119,8 +2694,102 @@ gtk_clist_button_press (GtkWidget * widget,
y = event->y;
if (get_selection_info (clist, x, y, &row, &column))
- toggle_row (clist, row, column, event);
+ {
+ gint old_row = clist->focus_row;
+ gboolean no_focus_row = FALSE;
+
+ if (clist->focus_row == -1)
+ {
+ old_row = row;
+ no_focus_row = TRUE;
+ }
+
+ GTK_CLIST_SET_FLAG (clist, CLIST_DRAG_SELECTION);
+ gdk_pointer_grab (clist->clist_window, FALSE,
+ GDK_POINTER_MOTION_HINT_MASK |
+ GDK_BUTTON1_MOTION_MASK |
+ GDK_BUTTON_RELEASE_MASK,
+ NULL, NULL, event->time);
+
+
+ if (GTK_CLIST_ADD_MODE (clist))
+ {
+ GTK_CLIST_UNSET_FLAG (clist, CLIST_ADD_MODE);
+ if (GTK_WIDGET_HAS_FOCUS (widget))
+ {
+ gtk_clist_draw_focus (widget);
+ gdk_gc_set_line_attributes (clist->xor_gc, 1,
+ GDK_LINE_SOLID, 0, 0);
+ clist->focus_row = row;
+ gtk_clist_draw_focus (widget);
+ }
+ else
+ {
+ gdk_gc_set_line_attributes (clist->xor_gc, 1,
+ GDK_LINE_SOLID, 0, 0);
+ clist->focus_row = row;
+ }
+ }
+ else if (row != clist->focus_row)
+ {
+ if (GTK_WIDGET_HAS_FOCUS (widget))
+ {
+ gtk_clist_draw_focus (widget);
+ clist->focus_row = row;
+ gtk_clist_draw_focus (widget);
+ }
+ else
+ clist->focus_row = row;
+ }
+
+ if (!GTK_WIDGET_HAS_FOCUS (widget))
+ gtk_widget_grab_focus (widget);
+ switch (clist->selection_mode)
+ {
+ case GTK_SELECTION_SINGLE:
+ case GTK_SELECTION_MULTIPLE:
+ clist->anchor = row;
+ break;
+
+ case GTK_SELECTION_BROWSE:
+ if (row != old_row || no_focus_row)
+ select_row (clist, row, column, (GdkEvent *) event);
+ break;
+
+ case GTK_SELECTION_EXTENDED:
+ if (event->state & GDK_CONTROL_MASK)
+ {
+ if (event->state & GDK_SHIFT_MASK)
+ {
+ set_anchor (clist, TRUE, old_row, old_row);
+ update_extended_selection (clist, clist->focus_row);
+ }
+ else
+ {
+ if (clist->anchor == -1)
+ set_anchor (clist, TRUE, row, old_row);
+ else
+ update_extended_selection (clist, clist->focus_row);
+ }
+ return TRUE;
+ }
+ if (event->state & GDK_SHIFT_MASK)
+ {
+ set_anchor (clist, FALSE, old_row, old_row);
+ update_extended_selection (clist, clist->focus_row);
+ return TRUE;
+ }
+ if (clist->anchor == -1)
+ set_anchor (clist, FALSE, row, old_row);
+ else
+ update_extended_selection (clist, clist->focus_row);
+ return TRUE;
+
+ default:
+ break;
+ }
+ }
return FALSE;
}
@@ -2137,6 +2806,9 @@ gtk_clist_button_press (GtkWidget * widget,
GDK_BUTTON_RELEASE_MASK,
NULL, NULL, event->time);
+ if (GTK_CLIST_ADD_MODE (clist))
+ gdk_gc_set_line_attributes (clist->xor_gc, 1, GDK_LINE_SOLID, 0, 0);
+
draw_xor_line (clist);
return FALSE;
}
@@ -2157,6 +2829,10 @@ gtk_clist_button_release (GtkWidget * widget,
clist = GTK_CLIST (widget);
+ /* we don't handle button 2 and 3 */
+ if (event->button != 1)
+ return FALSE;
+
/* release on resize windows */
if (GTK_CLIST_IN_DRAG (clist))
for (i = 0; i < clist->columns; i++)
@@ -2166,22 +2842,156 @@ gtk_clist_button_release (GtkWidget * widget,
gtk_widget_get_pointer (widget, &x, NULL);
width = new_column_width (clist, i, &x, &visible);
gdk_pointer_ungrab (event->time);
-
+
if (visible)
draw_xor_line (clist);
+ if (GTK_CLIST_ADD_MODE (clist))
+ {
+ gdk_gc_set_line_attributes (clist->xor_gc, 1,
+ GDK_LINE_ON_OFF_DASH, 0, 0);
+ gdk_gc_set_dashes (clist->xor_gc, 0, "\4\4", 2);
+ }
+
resize_column (clist, i, width);
return FALSE;
}
+ if (GTK_CLIST_DRAG_SELECTION (clist))
+ {
+ gint row;
+ gint column;
+
+ GTK_CLIST_UNSET_FLAG (clist, CLIST_DRAG_SELECTION);
+ gdk_pointer_ungrab (event->time);
+ if (clist->htimer)
+ {
+ gtk_timeout_remove (clist->htimer);
+ clist->htimer = 0;
+ }
+ if (clist->vtimer)
+ {
+ gtk_timeout_remove (clist->vtimer);
+ clist->vtimer = 0;
+ }
+ switch (clist->selection_mode)
+ {
+ case GTK_SELECTION_EXTENDED:
+ if (!(event->state & GDK_SHIFT_MASK) ||
+ event->x < 0 || event->x >= clist->clist_window_width ||
+ event->y < 0 || event->y >= clist->clist_window_height)
+ GTK_CLIST_CLASS_FW (clist)->resync_selection
+ (clist, (GdkEvent *) event);
+ break;
+
+ case GTK_SELECTION_SINGLE:
+ case GTK_SELECTION_MULTIPLE:
+ if (get_selection_info (clist, event->x, event->y, &row, &column))
+ {
+ if (clist->anchor == clist->focus_row)
+ toggle_row (clist, row, column, (GdkEvent *) event);
+ }
+ clist->anchor = -1;
+ break;
+
+ default:
+ break;
+ }
+ }
+
return FALSE;
}
static gint
+horizontal_timeout (GtkCList *clist)
+{
+ gint x, y;
+ GdkEventMotion event;
+ GdkModifierType mask;
+
+ g_return_val_if_fail (GTK_IS_CLIST (clist), FALSE);
+
+ clist->htimer = 0;
+ gdk_window_get_pointer (clist->clist_window, &x, &y, &mask);
+
+ event.is_hint = 0;
+ event.x = x;
+ event.y = y;
+ event.state = mask;
+
+ gtk_clist_motion (GTK_WIDGET (clist), &event);
+
+ return FALSE;
+}
+
+static gint
+vertical_timeout (GtkCList *clist)
+{
+ gint x, y;
+ GdkEventMotion event;
+ GdkModifierType mask;
+
+ g_return_val_if_fail (GTK_IS_CLIST (clist), FALSE);
+
+ clist->vtimer = 0;
+ gdk_window_get_pointer (clist->clist_window, &x, &y, &mask);
+
+ event.is_hint = 0;
+ event.x = x;
+ event.y = y;
+ event.state = mask;
+
+ gtk_clist_motion (GTK_WIDGET (clist), &event);
+
+ return FALSE;
+}
+
+static void
+move_vertical (GtkCList *clist,
+ gint row,
+ gfloat align)
+{
+ gint y;
+ GtkAdjustment *adj;
+
+ adj = GTK_RANGE (clist->vscrollbar)->adjustment;
+
+ y = ROW_TOP_YPIXEL (clist, row) - clist->voffset;
+
+ y = y - align * (clist->clist_window_height - clist->row_height)
+ + (2 * align - 1) * CELL_SPACING;
+
+ if (y + adj->page_size > adj->upper)
+ adj->value = adj->upper - adj->page_size;
+ else
+ adj->value = y;
+
+ gtk_signal_emit_by_name (GTK_OBJECT (adj), "value_changed");
+}
+
+static void
+move_horizontal (GtkCList *clist,
+ gint diff)
+{
+ gfloat upper;
+ GtkAdjustment *adj;
+
+ adj = GTK_RANGE (clist->hscrollbar)->adjustment;
+
+ adj->value += diff;
+
+ upper = adj->upper - adj->page_size;
+ adj->value = MIN (adj->value, upper);
+ adj->value = MAX (adj->value, 0.0);
+
+ gtk_signal_emit_by_name (GTK_OBJECT (adj), "value_changed");
+}
+
+static gint
gtk_clist_motion (GtkWidget * widget,
GdkEventMotion * event)
{
- gint i, x, visible;
+ gint i, x, y, visible;
GtkCList *clist;
g_return_val_if_fail (widget != NULL, FALSE);
@@ -2217,6 +3027,155 @@ gtk_clist_motion (GtkWidget * widget,
}
}
+ if (GTK_CLIST_DRAG_SELECTION (clist))
+ {
+ gint row;
+
+ if (event->is_hint || event->window != clist->clist_window)
+ gdk_window_get_pointer (clist->clist_window, &x, &y, NULL);
+
+ /* horizontal autoscrolling */
+ if (LIST_WIDTH (clist) > clist->clist_window_width &&
+ (x < 0 || x >= clist->clist_window_width))
+ {
+ if (clist->htimer == 0)
+ {
+ clist->htimer = gtk_timeout_add
+ (SCROLL_TIME, (GtkFunction) horizontal_timeout, clist);
+
+ if (!((x < 0 && GTK_RANGE (clist->hscrollbar)->adjustment->value
+ == 0) || (x >= clist->clist_window_width &&
+ GTK_RANGE (clist->hscrollbar)->adjustment->value ==
+ LIST_WIDTH (clist) - clist->clist_window_width)))
+ {
+ if (x < 0)
+ move_horizontal (clist, -1 + (x/2));
+ else
+ move_horizontal (clist,
+ 1 + (x - clist->clist_window_width) / 2);
+ }
+ }
+ else
+ return TRUE;
+ }
+
+ row = ROW_FROM_YPIXEL (clist, y);
+
+ /* don't scroll on last pixel row if it's a cell spacing */
+ if (y == clist->clist_window_height-1 &&
+ y == ROW_TOP_YPIXEL (clist, row-1) + clist->row_height)
+ return TRUE;
+
+ /* vertical autoscrolling */
+ if (LIST_HEIGHT (clist) > clist->clist_window_height &&
+ (y < 0 || y >= clist->clist_window_height))
+ {
+ if (clist->vtimer == 0)
+ {
+ clist->vtimer = gtk_timeout_add (SCROLL_TIME,
+ (GtkFunction) vertical_timeout,
+ clist);
+
+ if ((y < 0 && clist->focus_row == 0) ||
+ (y >= clist->clist_window_height &&
+ clist->focus_row == clist->rows-1))
+ return TRUE;
+
+ if (row < 0 && clist->focus_row > 0)
+ {
+ gtk_clist_draw_focus (widget);
+ clist->focus_row = 0;
+ gtk_clist_draw_focus (widget);
+ }
+ else if (row > clist->rows - 1 && clist->focus_row
+ < clist->rows - 1)
+ {
+ gtk_clist_draw_focus (widget);
+ clist->focus_row = clist->rows - 1;
+ gtk_clist_draw_focus (widget);
+ }
+ else if (row >= 0 && row <= clist->rows - 1)
+ {
+ gtk_clist_draw_focus (widget);
+ clist->focus_row = row;
+ gtk_clist_draw_focus (widget);
+ }
+ else
+ return TRUE;
+
+ switch (clist->selection_mode)
+ {
+ case GTK_SELECTION_BROWSE:
+ select_row (clist, clist->focus_row, -1, (GdkEvent *) event);
+ break;
+
+ case GTK_SELECTION_EXTENDED:
+ update_extended_selection (clist, clist->focus_row);
+ break;
+
+ default:
+ break;
+ }
+
+ if (y < 0)
+ move_vertical (clist, row, 0);
+ else
+ move_vertical (clist, row, 1);
+ }
+ else
+ return TRUE;
+ }
+
+ if (row == clist->focus_row)
+ return TRUE;
+
+ /* dragging inside clist_window */
+ if (row < 0 && clist->focus_row > 0)
+ {
+ gtk_clist_draw_focus (widget);
+ clist->focus_row = 0;
+ gtk_clist_draw_focus (widget);
+ }
+ else if (row > clist->rows-1 && clist->focus_row < clist->rows-1)
+ {
+ gtk_clist_draw_focus (widget);
+ clist->focus_row = clist->rows-1;
+ gtk_clist_draw_focus (widget);
+ }
+ else if (row >= 0 && row <= clist->rows-1)
+ {
+ gtk_clist_draw_focus (widget);
+ clist->focus_row = row;
+ gtk_clist_draw_focus (widget);
+ }
+ else
+ return TRUE;
+
+ switch (clist->selection_mode)
+ {
+ case GTK_SELECTION_EXTENDED:
+ update_extended_selection (clist, clist->focus_row);
+ return TRUE;
+
+ case GTK_SELECTION_BROWSE:
+ select_row (clist, clist->focus_row, -1, (GdkEvent *) event);
+ break;
+
+ default:
+ break;
+ }
+
+ if (ROW_TOP_YPIXEL(clist, clist->focus_row) + clist->row_height <= 0)
+ gtk_clist_moveto (clist, clist->focus_row, -1, 0, 0);
+ else if (ROW_TOP_YPIXEL (clist, clist->focus_row) < 0)
+ gtk_clist_moveto (clist, clist->focus_row, -1, 0, 0);
+ else if (ROW_TOP_YPIXEL (clist, clist->focus_row) >=
+ clist->clist_window_height)
+ gtk_clist_moveto (clist, clist->focus_row, -1, 1, 0);
+ else if (ROW_TOP_YPIXEL (clist, clist->focus_row) + clist->row_height >
+ clist->clist_window_height)
+ gtk_clist_moveto (clist, clist->focus_row, -1, 1, 0);
+ }
return TRUE;
}
@@ -2854,6 +3813,26 @@ draw_row (GtkCList * clist,
break;
}
}
+ if (clist->focus_row == row && GTK_WIDGET_HAS_FOCUS (widget))
+ {
+ if (area)
+ {
+ if (gdk_rectangle_intersect (area, &row_rectangle,
+ &intersect_rectangle))
+ {
+ gdk_gc_set_clip_rectangle (clist->xor_gc, &intersect_rectangle);
+ gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE,
+ row_rectangle.x, row_rectangle.y,
+ row_rectangle.width - 1,
+ row_rectangle.height - 1);
+ gdk_gc_set_clip_rectangle (clist->xor_gc, NULL);
+ }
+ }
+ else
+ gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE,
+ row_rectangle.x, row_rectangle.y,
+ row_rectangle.width - 1, row_rectangle.height - 1);
+ }
}
static void
@@ -2898,8 +3877,7 @@ draw_rows (GtkCList * clist,
if (i > last_row)
return;
- (GTK_CLIST_CLASS (GTK_OBJECT (clist)->klass)->draw_row)
- (clist, area, i, clist_row);
+ GTK_CLIST_CLASS_FW (clist)->draw_row (clist, area, i, clist_row);
i++;
}
@@ -3006,75 +3984,25 @@ static void
toggle_row (GtkCList * clist,
gint row,
gint column,
- GdkEventButton * event)
+ GdkEvent * event)
{
- gint i;
- GList *list;
- GtkCListRow *clist_row, *selected_row;
-
- i = 0;
- list = clist->row_list;
- selected_row = NULL;
+ GtkCListRow *clist_row;
switch (clist->selection_mode)
{
+ case GTK_SELECTION_EXTENDED:
+ case GTK_SELECTION_MULTIPLE:
case GTK_SELECTION_SINGLE:
- while (list)
- {
- clist_row = list->data;
- list = list->next;
-
- if (row == i)
- selected_row = clist_row;
- else if (clist_row->state == GTK_STATE_SELECTED)
- gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNSELECT_ROW],
- i, column, event);
- i++;
- }
-
- if (selected_row && selected_row->state == GTK_STATE_SELECTED)
- gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNSELECT_ROW],
- row, column, event);
- else
- gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW],
- row, column, event);
- break;
-
-
- case GTK_SELECTION_BROWSE:
- while (list)
+ clist_row = g_list_nth (clist->row_list, row)->data;
+ if (clist_row->state == GTK_STATE_SELECTED)
{
- clist_row = list->data;
- list = list->next;
-
- if (i != row && clist_row->state == GTK_STATE_SELECTED)
- gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNSELECT_ROW],
- i, column, event);
- i++;
+ unselect_row (clist, row, column, event);
+ return;
}
- gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW],
- row, column, event);
- break;
-
-
- case GTK_SELECTION_MULTIPLE:
- clist_row = (g_list_nth (clist->row_list, row))->data;
-
- if (clist_row->state == GTK_STATE_SELECTED)
- gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNSELECT_ROW],
- row, column, event);
- else
- gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW],
- row, column, event);
- break;
-
-
- case GTK_SELECTION_EXTENDED:
- break;
-
- default:
+ case GTK_SELECTION_BROWSE:
+ select_row (clist, row, column, event);
break;
}
}
@@ -3083,107 +4011,97 @@ static void
select_row (GtkCList * clist,
gint row,
gint column,
- GdkEventButton * event)
+ GdkEvent * event)
{
- gint i;
- GList *list;
- GtkCListRow *clist_row;
-
- switch (clist->selection_mode)
- {
- case GTK_SELECTION_SINGLE:
- case GTK_SELECTION_BROWSE:
- i = 0;
- list = clist->row_list;
- while (list)
- {
- clist_row = list->data;
- list = list->next;
-
- if (row != i && clist_row->state == GTK_STATE_SELECTED)
- gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNSELECT_ROW],
- i, column, event);
-
- i++;
- }
-
- gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW],
- row, column, event);
- break;
-
- case GTK_SELECTION_MULTIPLE:
- gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW],
- row, column, event);
-
- break;
-
- case GTK_SELECTION_EXTENDED:
- break;
-
- default:
- break;
- }
+ gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW],
+ row, column, event);
}
static void
unselect_row (GtkCList * clist,
gint row,
gint column,
- GdkEventButton * event)
+ GdkEvent * event)
{
- switch (clist->selection_mode)
- {
- case GTK_SELECTION_SINGLE:
- case GTK_SELECTION_BROWSE:
- case GTK_SELECTION_MULTIPLE:
- gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNSELECT_ROW],
- row, column, event);
- break;
-
- case GTK_SELECTION_EXTENDED:
- break;
-
- default:
- break;
- }
+ gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNSELECT_ROW],
+ row, column, event);
}
static void
real_select_row (GtkCList * clist,
gint row,
gint column,
- GdkEventButton * event)
+ GdkEvent * event)
{
GtkCListRow *clist_row;
+ GList *list;
+ gint sel_row;
+ gboolean row_selected;
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
if (row < 0 || row > (clist->rows - 1))
return;
+ switch (clist->selection_mode)
+ {
+ case GTK_SELECTION_SINGLE:
+ case GTK_SELECTION_BROWSE:
+
+ row_selected = FALSE;
+ list = clist->selection;
+
+ while (list)
+ {
+ sel_row = GPOINTER_TO_INT (list->data);
+ list = list->next;
+
+ if (row == sel_row)
+ row_selected = TRUE;
+ else
+ gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNSELECT_ROW],
+ sel_row, column, event);
+ }
+
+ if (row_selected)
+ return;
+
+ default:
+ break;
+ }
+
clist_row = (g_list_nth (clist->row_list, row))->data;
- if (clist_row->state == GTK_STATE_NORMAL)
- {
- clist_row->state = GTK_STATE_SELECTED;
- clist->selection = g_list_append (clist->selection, GINT_TO_POINTER (row));
+ if (clist_row->state != GTK_STATE_NORMAL)
+ return;
- if (!GTK_CLIST_FROZEN (clist)
- && (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE))
- (GTK_CLIST_CLASS (GTK_OBJECT (clist)->klass)->draw_row)
- (clist, NULL, row, clist_row);
+ clist_row->state = GTK_STATE_SELECTED;
+ if (!clist->selection)
+ {
+ clist->selection = g_list_append (clist->selection,
+ GINT_TO_POINTER (row));
+ clist->selection_end = clist->selection;
}
+ else
+ clist->selection_end =
+ g_list_append (clist->selection_end, GINT_TO_POINTER (row))->next;
+
+ if (!GTK_CLIST_FROZEN (clist)
+ && (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE))
+ GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row);
}
static void
real_unselect_row (GtkCList * clist,
gint row,
gint column,
- GdkEventButton * event)
+ GdkEvent * event)
{
GtkCListRow *clist_row;
g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
if (row < 0 || row > (clist->rows - 1))
return;
@@ -3193,12 +4111,17 @@ real_unselect_row (GtkCList * clist,
if (clist_row->state == GTK_STATE_SELECTED)
{
clist_row->state = GTK_STATE_NORMAL;
- clist->selection = g_list_remove (clist->selection, GINT_TO_POINTER (row));
+ if (clist->selection_end &&
+ clist->selection_end->data == GINT_TO_POINTER (row))
+ clist->selection_end = clist->selection_end->prev;
+
+ clist->selection = g_list_remove (clist->selection,
+ GINT_TO_POINTER (row));
+
if (!GTK_CLIST_FROZEN (clist)
&& (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE))
- (GTK_CLIST_CLASS (GTK_OBJECT (clist)->klass)->draw_row)
- (clist, NULL, row, clist_row);
+ GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row, clist_row);
}
}
@@ -3212,6 +4135,7 @@ get_selection_info (GtkCList * clist,
gint trow, tcol;
g_return_val_if_fail (clist != NULL, 0);
+ g_return_val_if_fail (GTK_IS_CLIST (clist), 0);
/* bounds checking, return false if the user clicked
* on a blank area */
@@ -3331,8 +4255,7 @@ column_button_create (GtkCList * clist,
if (GTK_WIDGET_REALIZED (clist) && clist->title_window)
gtk_widget_set_parent_window (clist->column[column].button, clist->title_window);
- gtk_signal_connect (GTK_OBJECT (button),
- "clicked",
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) column_button_clicked,
(gpointer) clist);
@@ -3376,6 +4299,7 @@ create_scrollbars (GtkCList * clist)
GtkAdjustment *adjustment;
clist->vscrollbar = gtk_vscrollbar_new (NULL);
+
adjustment = gtk_range_get_adjustment (GTK_RANGE (clist->vscrollbar));
gtk_signal_connect (GTK_OBJECT (adjustment), "changed",
@@ -3390,6 +4314,7 @@ create_scrollbars (GtkCList * clist)
gtk_widget_show (clist->vscrollbar);
clist->hscrollbar = gtk_hscrollbar_new (NULL);
+
adjustment = gtk_range_get_adjustment (GTK_RANGE (clist->hscrollbar));
gtk_signal_connect (GTK_OBJECT (adjustment), "changed",
@@ -3614,7 +4539,10 @@ hadjustment_value_changed (GtkAdjustment * adjustment,
{
GtkCList *clist;
GdkRectangle area;
- gint i, diff, value;
+ gint i;
+ gint y = 0;
+ gint diff = 0;
+ gint value;
g_return_if_fail (adjustment != NULL);
g_return_if_fail (data != NULL);
@@ -3622,97 +4550,151 @@ hadjustment_value_changed (GtkAdjustment * adjustment,
clist = GTK_CLIST (data);
- if (!GTK_WIDGET_DRAWABLE (clist))
+ if (!GTK_WIDGET_DRAWABLE (clist) ||
+ adjustment != gtk_range_get_adjustment (GTK_RANGE (clist->hscrollbar)))
return;
value = adjustment->value;
-
- if (adjustment == gtk_range_get_adjustment (GTK_RANGE (clist->hscrollbar)))
+
+ /* move the column buttons and resize windows */
+ for (i = 0; i < clist->columns; i++)
{
- /* move the column buttons and resize windows */
- for (i = 0; i < clist->columns; i++)
+ if (clist->column[i].button)
{
- if (clist->column[i].button)
+ clist->column[i].button->allocation.x -= value + clist->hoffset;
+
+ if (clist->column[i].button->window)
{
- clist->column[i].button->allocation.x -= value + clist->hoffset;
-
- if (clist->column[i].button->window)
- {
- gdk_window_move (clist->column[i].button->window,
- clist->column[i].button->allocation.x,
- clist->column[i].button->allocation.y);
-
- if (clist->column[i].window)
- gdk_window_move (clist->column[i].window,
- clist->column[i].button->allocation.x +
- clist->column[i].button->allocation.width -
- (DRAG_WIDTH / 2), 0);
- }
+ gdk_window_move (clist->column[i].button->window,
+ clist->column[i].button->allocation.x,
+ clist->column[i].button->allocation.y);
+
+ if (clist->column[i].window)
+ gdk_window_move (clist->column[i].window,
+ clist->column[i].button->allocation.x +
+ clist->column[i].button->allocation.width -
+ (DRAG_WIDTH / 2), 0);
}
}
+ }
+
+ if (value > -clist->hoffset)
+ {
+ /* scroll right */
+ diff = value + clist->hoffset;
+
+ clist->hoffset = -value;
+
+ /* we have to re-draw the whole screen here... */
+ if (diff >= clist->clist_window_width)
+ {
+ draw_rows (clist, NULL);
+ return;
+ }
- if (value > -clist->hoffset)
+ if (GTK_WIDGET_HAS_FOCUS (clist) && !GTK_CLIST_CHILD_HAS_FOCUS (clist) &&
+ GTK_CLIST_ADD_MODE (clist))
{
- /* scroll right */
- diff = value + clist->hoffset;
+ y = ROW_TOP_YPIXEL (clist, clist->focus_row);
+
+ gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, 0, y,
+ clist->clist_window_width - 1,
+ clist->row_height - 1);
+ }
+ gdk_window_copy_area (clist->clist_window,
+ clist->fg_gc,
+ 0, 0,
+ clist->clist_window,
+ diff,
+ 0,
+ clist->clist_window_width - diff,
+ clist->clist_window_height);
+
+ area.x = clist->clist_window_width - diff;
+ }
+ else
+ {
+ /* scroll left */
+ if (!(diff = -clist->hoffset - value))
+ return;
- /* we have to re-draw the whole screen here... */
- if (diff >= clist->clist_window_width)
- {
- clist->hoffset = -value;
- draw_rows (clist, NULL);
- return;
- }
+ clist->hoffset = -value;
+
+ /* we have to re-draw the whole screen here... */
+ if (diff >= clist->clist_window_width)
+ {
+ draw_rows (clist, NULL);
+ return;
+ }
+
+ if (GTK_WIDGET_HAS_FOCUS (clist) && !GTK_CLIST_CHILD_HAS_FOCUS (clist) &&
+ GTK_CLIST_ADD_MODE (clist))
+ {
+ y = ROW_TOP_YPIXEL (clist, clist->focus_row);
+
+ gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE, 0, y,
+ clist->clist_window_width - 1,
+ clist->row_height - 1);
+ }
- if ((diff != 0) && (diff != clist->clist_window_width))
- gdk_window_copy_area (clist->clist_window,
- clist->fg_gc,
- 0, 0,
- clist->clist_window,
- diff,
- 0,
- clist->clist_window_width - diff,
- clist->clist_window_height);
+ gdk_window_copy_area (clist->clist_window,
+ clist->fg_gc,
+ diff, 0,
+ clist->clist_window,
+ 0,
+ 0,
+ clist->clist_window_width - diff,
+ clist->clist_window_height);
+
+ area.x = 0;
+ }
- area.x = clist->clist_window_width - diff;
- area.y = 0;
- area.width = diff;
- area.height = clist->clist_window_height;
+ area.y = 0;
+ area.width = diff;
+ area.height = clist->clist_window_height;
+
+ check_exposures (clist);
+
+ if (GTK_WIDGET_HAS_FOCUS (clist) && !GTK_CLIST_CHILD_HAS_FOCUS (clist))
+ {
+ if (GTK_CLIST_ADD_MODE (clist))
+ {
+ gint focus_row;
+
+ focus_row = clist->focus_row;
+ clist->focus_row = -1;
+ draw_rows (clist, &area);
+ clist->focus_row = focus_row;
+
+ gdk_draw_rectangle (clist->clist_window, clist->xor_gc,
+ FALSE, 0, y, clist->clist_window_width - 1,
+ clist->row_height - 1);
+ return;
}
else
{
- /* scroll left */
- diff = -clist->hoffset - value;
-
- /* we have to re-draw the whole screen here... */
- if (diff >= clist->clist_window_width)
+ gint x0;
+ gint x1;
+
+ if (area.x == 0)
{
- clist->hoffset = -value;
- draw_rows (clist, NULL);
- return;
+ x0 = clist->clist_window_width - 1;
+ x1 = diff;
}
-
- if ((diff != 0) && (diff != clist->clist_window_width))
- gdk_window_copy_area (clist->clist_window,
- clist->fg_gc,
- diff, 0,
- clist->clist_window,
- 0,
- 0,
- clist->clist_window_width - diff,
- clist->clist_window_height);
-
- area.x = 0;
- area.y = 0;
- area.width = diff;
- area.height = clist->clist_window_height;
+ else
+ {
+ x0 = 0;
+ x1 = area.x - 1;
+ }
+
+ y = ROW_TOP_YPIXEL (clist, clist->focus_row);
+ gdk_draw_line (clist->clist_window, clist->xor_gc,
+ x0, y + 1, x0, y + clist->row_height - 2);
+ gdk_draw_line (clist->clist_window, clist->xor_gc,
+ x1, y + 1, x1, y + clist->row_height - 2);
+
}
-
- clist->hoffset = -value;
- if ((diff != 0) && (diff != clist->clist_window_width))
- check_exposures (clist);
}
-
draw_rows (clist, &area);
}
@@ -3935,3 +4917,1172 @@ add_style_data (GtkCList * clist)
/* Column widths */
}
+
+
+/* focus functions */
+
+static void
+gtk_clist_draw_focus (GtkWidget *widget)
+{
+ GtkCList *clist;
+
+ g_return_if_fail (widget != NULL);
+ g_return_if_fail (GTK_IS_CLIST (widget));
+
+ if (!GTK_WIDGET_DRAWABLE (widget))
+ return;
+
+ clist = GTK_CLIST (widget);
+ if (clist->focus_row >= 0)
+ gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE,
+ 0, ROW_TOP_YPIXEL(clist, clist->focus_row),
+ clist->clist_window_width - 1,
+ clist->row_height - 1);
+}
+
+static void
+gtk_clist_set_focus_child (GtkContainer *container,
+ GtkWidget *child)
+{
+ g_return_if_fail (container != NULL);
+ g_return_if_fail (GTK_IS_CLIST (container));
+
+ if (child)
+ {
+ g_return_if_fail (GTK_IS_WIDGET (child));
+ GTK_CLIST_SET_FLAG (GTK_CLIST (container), CLIST_CHILD_HAS_FOCUS);
+ }
+
+ parent_class->set_focus_child (container, child);
+}
+
+static gint
+gtk_clist_focus_in (GtkWidget *widget,
+ GdkEventFocus *event)
+{
+ GtkCList *clist;
+
+ g_return_val_if_fail (widget != NULL, FALSE);
+ g_return_val_if_fail (GTK_IS_CLIST (widget), FALSE);
+ g_return_val_if_fail (event != NULL, FALSE);
+
+ GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
+ GTK_CLIST_UNSET_FLAG (widget, CLIST_CHILD_HAS_FOCUS);
+
+ clist = GTK_CLIST (widget);
+
+ if (clist->selection_mode == GTK_SELECTION_BROWSE &&
+ clist->selection == NULL && clist->focus_row > -1)
+ select_row (clist, clist->focus_row, -1, (GdkEvent *) event);
+ else
+ gtk_widget_draw_focus (widget);
+
+ return FALSE;
+}
+
+static gint
+gtk_clist_focus_out (GtkWidget *widget,
+ GdkEventFocus *event)
+{
+ g_return_val_if_fail (widget != NULL, FALSE);
+ g_return_val_if_fail (GTK_IS_CLIST (widget), FALSE);
+ g_return_val_if_fail (event != NULL, FALSE);
+
+ GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
+ gtk_widget_draw_focus (widget);
+
+ if (GTK_CLIST (widget)->anchor != -1)
+ GTK_CLIST_CLASS_FW (widget)->resync_selection
+ (GTK_CLIST (widget), (GdkEvent *) event);
+
+ return FALSE;
+}
+
+static void
+toggle_add_mode (GtkCList *clist)
+{
+ g_return_if_fail (clist != 0);
+ g_return_if_fail (GTK_IS_CLIST (clist));
+
+ if (gdk_pointer_is_grabbed () ||
+ clist->selection_mode != GTK_SELECTION_EXTENDED)
+ return;
+
+ gtk_clist_draw_focus (GTK_WIDGET (clist));
+ if (!GTK_CLIST_ADD_MODE (clist))
+ {
+ GTK_CLIST_SET_FLAG (clist, CLIST_ADD_MODE);
+ gdk_gc_set_line_attributes (clist->xor_gc, 1,
+ GDK_LINE_ON_OFF_DASH, 0, 0);
+ gdk_gc_set_dashes (clist->xor_gc, 0, "\4\4", 2);
+ }
+ else
+ {
+ GTK_CLIST_UNSET_FLAG (clist, CLIST_ADD_MODE);
+ gdk_gc_set_line_attributes (clist->xor_gc, 1, GDK_LINE_SOLID, 0, 0);
+ clist->anchor_state = GTK_STATE_SELECTED;
+ }
+ gtk_clist_draw_focus (GTK_WIDGET (clist));
+}
+
+static void
+toggle_focus_row (GtkCList *clist)
+{
+ g_return_if_fail (clist != 0);
+ g_return_if_fail (GTK_IS_CLIST (clist));
+
+ if (gdk_pointer_is_grabbed ())
+ return;
+
+ switch (clist->selection_mode)
+ {
+ case GTK_SELECTION_SINGLE:
+ case GTK_SELECTION_MULTIPLE:
+
+ toggle_row (clist, clist->focus_row, 0, NULL);
+ break;
+
+ case GTK_SELECTION_EXTENDED:
+ g_list_free (clist->undo_selection);
+ g_list_free (clist->undo_unselection);
+ clist->undo_selection = NULL;
+ clist->undo_unselection = NULL;
+
+ if (GTK_CLIST_ADD_MODE (clist))
+ {
+ clist->anchor = clist->focus_row;
+ clist->drag_pos = clist->focus_row;
+ clist->undo_anchor = clist->focus_row;
+ fake_toggle_row (clist, clist->focus_row);
+ GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+ }
+ else
+ {
+ clist->anchor = clist->focus_row;
+ clist->drag_pos = clist->focus_row;
+ clist->undo_anchor = clist->focus_row;
+ GTK_CLIST_CLASS_FW (clist)->fake_unselect_all (clist,
+ clist->focus_row);
+ GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void
+move_focus_row (GtkCList *clist,
+ GtkScrollType scroll_type,
+ gfloat position)
+{
+ GtkWidget *widget;
+
+ g_return_if_fail (clist != 0);
+ g_return_if_fail (GTK_IS_CLIST (clist));
+
+ widget = GTK_WIDGET (clist);
+
+ switch (scroll_type)
+ {
+ case GTK_SCROLL_STEP_BACKWARD:
+ if (clist->focus_row <= 0)
+ return;
+ gtk_clist_draw_focus (widget);
+ clist->focus_row--;
+ gtk_clist_draw_focus (widget);
+ break;
+ case GTK_SCROLL_STEP_FORWARD:
+ if (clist->focus_row >= clist->rows - 1)
+ return;
+ gtk_clist_draw_focus (widget);
+ clist->focus_row++;
+ gtk_clist_draw_focus (widget);
+ break;
+ case GTK_SCROLL_PAGE_BACKWARD:
+ if (clist->focus_row <= 0)
+ return;
+ gtk_clist_draw_focus (widget);
+ clist->focus_row = MAX (0, clist->focus_row -
+ (2 * clist->clist_window_height -
+ clist->row_height - CELL_SPACING) /
+ (2 * (clist->row_height + CELL_SPACING)));
+ gtk_clist_draw_focus (widget);
+ break;
+ case GTK_SCROLL_PAGE_FORWARD:
+ if (clist->focus_row >= clist->rows - 1)
+ return;
+ gtk_clist_draw_focus (widget);
+ clist->focus_row = MIN (clist->rows - 1, clist->focus_row +
+ (2 * clist->clist_window_height -
+ clist->row_height - CELL_SPACING) /
+ (2 * (clist->row_height + CELL_SPACING)));
+ gtk_clist_draw_focus (widget);
+ break;
+ case GTK_SCROLL_JUMP:
+ if (position >= 0 && position <= 1)
+ {
+ gtk_clist_draw_focus (widget);
+ clist->focus_row = position * (clist->rows - 1);
+ gtk_clist_draw_focus (widget);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+scroll_horizontal (GtkCList *clist,
+ GtkScrollType scroll_type,
+ gfloat position)
+{
+ gint column = 0;
+
+ g_return_if_fail (clist != 0);
+ g_return_if_fail (GTK_IS_CLIST (clist));
+
+ if (gdk_pointer_is_grabbed ())
+ return;
+
+ switch (scroll_type)
+ {
+ case GTK_SCROLL_STEP_BACKWARD:
+ column = COLUMN_FROM_XPIXEL (clist, 0);
+ if (COLUMN_LEFT_XPIXEL (clist, column) - CELL_SPACING - COLUMN_INSET >= 0
+ && column > 0)
+ column--;
+ break;
+ case GTK_SCROLL_STEP_FORWARD:
+ column = COLUMN_FROM_XPIXEL (clist, clist->clist_window_width);
+ if (column < 0)
+ return;
+ if (COLUMN_LEFT_XPIXEL (clist, column) + clist->column[column].area.width
+ + CELL_SPACING + COLUMN_INSET - 1 <= clist->clist_window_width &&
+ column < clist->columns - 1)
+ column++;
+ break;
+ case GTK_SCROLL_PAGE_BACKWARD:
+ case GTK_SCROLL_PAGE_FORWARD:
+ return;
+ case GTK_SCROLL_JUMP:
+ if (position >= 0 && position <= 1)
+ column = position * (clist->columns - 1);
+ else
+ return;
+ break;
+ default:
+ break;
+ }
+
+ if (COLUMN_LEFT_XPIXEL (clist, column) < CELL_SPACING + COLUMN_INSET)
+ gtk_clist_moveto (clist, -1, column, 0, 0);
+ else if (COLUMN_LEFT_XPIXEL (clist, column) + CELL_SPACING + COLUMN_INSET - 1
+ + clist->column[column].area.width > clist->clist_window_width)
+ {
+ if (column == clist->columns - 1)
+ gtk_clist_moveto (clist, -1, column, 0, 0);
+ else
+ gtk_clist_moveto (clist, -1, column, 0, 1);
+ }
+}
+
+static void
+scroll_vertical (GtkCList *clist,
+ GtkScrollType scroll_type,
+ gfloat position)
+{
+ g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
+
+ if (gdk_pointer_is_grabbed ())
+ return;
+
+ switch (clist->selection_mode)
+ {
+ case GTK_SELECTION_EXTENDED:
+ if (clist->anchor >= 0)
+ return;
+ if (!GTK_CLIST_ADD_MODE (clist))
+ gtk_clist_unselect_all (clist);
+
+ case GTK_SELECTION_BROWSE:
+
+ if (clist->selection_mode == GTK_SELECTION_BROWSE)
+ unselect_row (clist,clist->focus_row, -1, NULL);
+
+ move_focus_row (clist, scroll_type, position);
+
+ if (clist->selection_mode == GTK_SELECTION_EXTENDED &&
+ GTK_CLIST_ADD_MODE (clist))
+ return;
+
+ switch (gtk_clist_row_is_visible (clist, clist->focus_row))
+ {
+ case GTK_VISIBILITY_NONE:
+ select_row (clist, clist->focus_row, -1, NULL);
+ switch (scroll_type)
+ {
+ case GTK_SCROLL_STEP_BACKWARD:
+ case GTK_SCROLL_PAGE_BACKWARD:
+ gtk_clist_moveto (clist, clist->focus_row, -1, 0, 0);
+ break;
+ case GTK_SCROLL_STEP_FORWARD:
+ case GTK_SCROLL_PAGE_FORWARD:
+ gtk_clist_moveto (clist, clist->focus_row, -1, 1, 0);
+ break;
+ case GTK_SCROLL_JUMP:
+ gtk_clist_moveto (clist, clist->focus_row, -1, 0.5, 0);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case GTK_VISIBILITY_PARTIAL:
+ switch (scroll_type)
+ {
+ case GTK_SCROLL_STEP_BACKWARD:
+ case GTK_SCROLL_PAGE_BACKWARD:
+ gtk_clist_moveto (clist, clist->focus_row, -1, 0, 0);
+ break;
+ case GTK_SCROLL_STEP_FORWARD:
+ case GTK_SCROLL_PAGE_FORWARD:
+ gtk_clist_moveto (clist, clist->focus_row, -1, 1, 0);
+ break;
+ case GTK_SCROLL_JUMP:
+ gtk_clist_moveto (clist, clist->focus_row, -1, 0.5, 0);
+ break;
+ default:
+ break;
+ }
+
+ default:
+ select_row (clist, clist->focus_row, -1, NULL);
+ break;
+ }
+ break;
+
+ default:
+ move_focus_row (clist, scroll_type, position);
+
+ if (ROW_TOP_YPIXEL (clist, clist->focus_row) + clist->row_height >
+ clist->clist_window_height)
+ gtk_clist_moveto (clist, clist->focus_row, -1, 1, 0);
+ else if (ROW_TOP_YPIXEL (clist, clist->focus_row) < 0)
+ gtk_clist_moveto (clist, clist->focus_row, -1, 0, 0);
+ break;
+ }
+}
+
+static void
+set_anchor (GtkCList *clist,
+ gboolean add_mode,
+ gint anchor,
+ gint undo_anchor)
+{
+ g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
+
+ if (clist->selection_mode != GTK_SELECTION_EXTENDED || clist->anchor >= 0)
+ return;
+
+ g_list_free (clist->undo_selection);
+ g_list_free (clist->undo_unselection);
+ clist->undo_selection = NULL;
+ clist->undo_unselection = NULL;
+
+ if (add_mode)
+ fake_toggle_row (clist, anchor);
+ else
+ {
+ GTK_CLIST_CLASS_FW (clist)->fake_unselect_all (clist, anchor);
+ clist->anchor_state = GTK_STATE_SELECTED;
+ }
+
+ clist->anchor = anchor;
+ clist->drag_pos = anchor;
+ clist->undo_anchor = undo_anchor;
+}
+
+static void
+resync_selection (GtkCList *clist,
+ GdkEvent *event)
+{
+ gint i;
+ gint e;
+ gint row;
+ gboolean thaw = FALSE;
+ GList *list;
+ GtkCListRow *clist_row;
+
+ if (clist->anchor < 0)
+ return;
+
+ if (!GTK_CLIST_FROZEN (clist))
+ {
+ GTK_CLIST_SET_FLAG (clist, CLIST_FROZEN);
+ thaw = TRUE;
+ }
+
+ i = MIN (clist->anchor, clist->drag_pos);
+ e = MAX (clist->anchor, clist->drag_pos);
+
+ if (clist->undo_selection)
+ {
+
+ list = clist->selection;
+ clist->selection = clist->undo_selection;
+ clist->selection_end = g_list_last (clist->selection);
+ clist->undo_selection = list;
+ list = clist->selection;
+ while (list)
+ {
+ row = GPOINTER_TO_INT (list->data);
+ list = list->next;
+ if (row < i || row > e)
+ {
+ clist_row = g_list_nth (clist->row_list, row)->data;
+ clist_row->state = GTK_STATE_SELECTED;
+ unselect_row (clist, row, -1, event);
+ clist->undo_selection = g_list_prepend
+ (clist->undo_selection, GINT_TO_POINTER (row));
+ }
+ }
+ }
+
+ for (list = g_list_nth (clist->row_list, i); i <= e; i++, list = list->next)
+ if (g_list_find (clist->selection, GINT_TO_POINTER(i)))
+ {
+ if (GTK_CLIST_ROW (list)->state == GTK_STATE_NORMAL)
+ {
+ GTK_CLIST_ROW (list)->state = GTK_STATE_SELECTED;
+ unselect_row (clist, i, -1, event);
+ clist->undo_selection = g_list_prepend (clist->undo_selection,
+ GINT_TO_POINTER (i));
+ }
+ }
+ else if (GTK_CLIST_ROW (list)->state == GTK_STATE_SELECTED)
+ {
+ GTK_CLIST_ROW (list)->state = GTK_STATE_NORMAL;
+ clist->undo_unselection = g_list_prepend (clist->undo_unselection,
+ GINT_TO_POINTER (i));
+ }
+
+ for (list = clist->undo_unselection; list; list = list->next)
+ gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW],
+ GPOINTER_TO_INT (list->data), -1, event);
+
+ clist->anchor = -1;
+ clist->drag_pos = -1;
+
+ if (thaw)
+ GTK_CLIST_UNSET_FLAG (clist, CLIST_FROZEN);
+}
+
+static void
+update_extended_selection (GtkCList *clist,
+ gint row)
+{
+ gint i;
+ GList *list;
+ GdkRectangle area;
+ gint s1 = -1;
+ gint s2 = -1;
+ gint e1 = -1;
+ gint e2 = -1;
+ gint y1 = clist->clist_window_height;
+ gint y2 = clist->clist_window_height;
+ gint h1 = 0;
+ gint h2 = 0;
+ gint top;
+
+ if (row < 0)
+ row = 0;
+ if (row >= clist->rows)
+ row = clist->rows - 1;
+
+ /* extending downwards */
+ if (row > clist->drag_pos && clist->anchor <= clist->drag_pos)
+ {
+ s2 = clist->drag_pos + 1;
+ e2 = row;
+ }
+ /* extending upwards */
+ else if (row < clist->drag_pos && clist->anchor >= clist->drag_pos)
+ {
+ s2 = row;
+ e2 = clist->drag_pos - 1;
+ }
+ else if (row < clist->drag_pos && clist->anchor < clist->drag_pos)
+ {
+ e1 = clist->drag_pos;
+ /* row and drag_pos on different sides of anchor :
+ take back the selection between anchor and drag_pos,
+ select between anchor and row */
+ if (row < clist->anchor)
+ {
+ s1 = clist->anchor + 1;
+ s2 = row;
+ e2 = clist->anchor - 1;
+ }
+ /* take back the selection between anchor and drag_pos */
+ else
+ s1 = row + 1;
+ }
+ else if (row > clist->drag_pos && clist->anchor > clist->drag_pos)
+ {
+ s1 = clist->drag_pos;
+ /* row and drag_pos on different sides of anchor :
+ take back the selection between anchor and drag_pos,
+ select between anchor and row */
+ if (row > clist->anchor)
+ {
+ e1 = clist->anchor - 1;
+ s2 = clist->anchor + 1;
+ e2 = row;
+ }
+ /* take back the selection between anchor and drag_pos */
+ else
+ e1 = row - 1;
+ }
+
+ clist->drag_pos = row;
+
+ area.x = 0;
+ area.width = clist->clist_window_width;
+
+ /* restore the elements between s1 and e1 */
+ if (s1 >= 0)
+ {
+ for (i = s1, list = g_list_nth (clist->row_list, i); i <= e1;
+ i++, list = list->next)
+ {
+ if (GTK_CLIST_CLASS_FW (clist)->selection_find (clist, i, list))
+ GTK_CLIST_ROW (list)->state = GTK_STATE_SELECTED;
+ else
+ GTK_CLIST_ROW (list)->state = GTK_STATE_NORMAL;
+ }
+
+ top = ROW_TOP_YPIXEL (clist, clist->focus_row);
+
+ if (top + clist->row_height <= 0)
+ {
+ area.y = 0;
+ area.height = ROW_TOP_YPIXEL (clist, e1) + clist->row_height;
+ draw_rows (clist, &area);
+ gtk_clist_moveto (clist, clist->focus_row, -1, 0, 0);
+ }
+ else if (top >= clist->clist_window_height)
+ {
+ area.y = ROW_TOP_YPIXEL (clist, s1);
+ area.height = clist->clist_window_height - area.y;
+ draw_rows (clist, &area);
+ gtk_clist_moveto (clist, clist->focus_row, -1, 1, 0);
+ }
+ else if (top < 0)
+ gtk_clist_moveto (clist, clist->focus_row, -1, 0, 0);
+ else if (top + clist->row_height > clist->clist_window_height)
+ gtk_clist_moveto (clist, clist->focus_row, -1, 1, 0);
+
+ y1 = ROW_TOP_YPIXEL (clist, s1);
+ h1 = (e1 - s1 + 1) * (clist->row_height + CELL_SPACING);
+ }
+
+ /* extend the selection between s2 and e2 */
+ if (s2 >= 0)
+ {
+ for (i = s2, list = g_list_nth (clist->row_list, i); i <= e2;
+ i++, list = list->next)
+ if (GTK_CLIST_ROW (list)->state != clist->anchor_state)
+ GTK_CLIST_ROW (list)->state = clist->anchor_state;
+
+ top = ROW_TOP_YPIXEL (clist, clist->focus_row);
+
+ if (top + clist->row_height <= 0)
+ {
+ area.y = 0;
+ area.height = ROW_TOP_YPIXEL (clist, e2) + clist->row_height;
+ draw_rows (clist, &area);
+ gtk_clist_moveto (clist, clist->focus_row, -1, 0, 0);
+ }
+ else if (top >= clist->clist_window_height)
+ {
+ area.y = ROW_TOP_YPIXEL (clist, s2);
+ area.height = clist->clist_window_height - area.y;
+ draw_rows (clist, &area);
+ gtk_clist_moveto (clist, clist->focus_row, -1, 1, 0);
+ }
+ else if (top < 0)
+ gtk_clist_moveto (clist, clist->focus_row, -1, 0, 0);
+ else if (top + clist->row_height > clist->clist_window_height)
+ gtk_clist_moveto (clist, clist->focus_row, -1, 1, 0);
+
+ y2 = ROW_TOP_YPIXEL (clist, s2);
+ h2 = (e2-s2+1) * (clist->row_height + CELL_SPACING);
+ }
+
+ area.y = MAX (0, MIN (y1, y2));
+ if (area.y > clist->clist_window_height)
+ area.y = 0;
+ area.height = MIN (clist->clist_window_height, h1 + h2);
+ if (s1 >= 0 && s2 >= 0)
+ area.height += (clist->row_height + CELL_SPACING);
+ draw_rows (clist, &area);
+}
+
+static void
+start_selection (GtkCList *clist)
+{
+ g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
+
+ if (gdk_pointer_is_grabbed ())
+ return;
+
+ set_anchor (clist, GTK_CLIST_ADD_MODE (clist), clist->focus_row,
+ clist->focus_row);
+}
+
+static void
+end_selection (GtkCList *clist)
+{
+ g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
+
+ if (gdk_pointer_is_grabbed () || clist->anchor == -1)
+ return;
+
+ GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+}
+
+static void
+extend_selection (GtkCList *clist,
+ GtkScrollType scroll_type,
+ gfloat position,
+ gboolean auto_start_selection)
+{
+ g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
+
+ if (gdk_pointer_is_grabbed () ||
+ clist->selection_mode != GTK_SELECTION_EXTENDED)
+ return;
+
+ if (auto_start_selection)
+ set_anchor (clist, GTK_CLIST_ADD_MODE (clist), clist->focus_row,
+ clist->focus_row);
+ else if (clist->anchor == -1)
+ return;
+
+ move_focus_row (clist, scroll_type, position);
+
+ if (ROW_TOP_YPIXEL (clist, clist->focus_row) + clist->row_height >
+ clist->clist_window_height)
+ gtk_clist_moveto (clist, clist->focus_row, -1, 1, 0);
+ else if (ROW_TOP_YPIXEL (clist, clist->focus_row) < 0)
+ gtk_clist_moveto (clist, clist->focus_row, -1, 0, 0);
+
+ update_extended_selection (clist, clist->focus_row);
+}
+
+static void
+abort_column_resize (GtkCList *clist)
+{
+ g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
+
+ if (!GTK_CLIST_IN_DRAG (clist))
+ return;
+
+ GTK_CLIST_UNSET_FLAG (clist, CLIST_IN_DRAG);
+ gdk_pointer_ungrab (gdk_time_get());
+
+ if (clist->x_drag >= 0 && clist->x_drag <= clist->clist_window_width - 1)
+ draw_xor_line (clist);
+
+ if (GTK_CLIST_ADD_MODE (clist))
+ {
+ gdk_gc_set_line_attributes (clist->xor_gc, 1, GDK_LINE_ON_OFF_DASH, 0,0);
+ gdk_gc_set_dashes (clist->xor_gc, 0, "\4\4", 2);
+ }
+}
+
+static gint
+gtk_clist_key_press (GtkWidget * widget,
+ GdkEventKey * event)
+{
+ GtkCList *clist;
+ gboolean handled = FALSE;
+
+ g_return_val_if_fail (widget != NULL, FALSE);
+ g_return_val_if_fail (GTK_IS_CLIST (widget), FALSE);
+ g_return_val_if_fail (event != NULL, FALSE);
+
+ clist = GTK_CLIST (widget);
+
+
+ if (event->keyval == GDK_Escape && GTK_CLIST_IN_DRAG (clist))
+ {
+ GTK_CLIST_UNSET_FLAG (clist, CLIST_IN_DRAG);
+ gdk_pointer_ungrab (event->time);
+
+ if (clist->x_drag >= 0 && clist->x_drag <= clist->clist_window_width - 1)
+ draw_xor_line (clist);
+
+ if (GTK_CLIST_ADD_MODE (clist))
+ {
+ gdk_gc_set_line_attributes (clist->xor_gc, 1, GDK_LINE_ON_OFF_DASH,
+ 0, 0);
+ gdk_gc_set_dashes (clist->xor_gc, 0, "\4\4", 2);
+ }
+ return TRUE;
+ }
+
+ if (GTK_WIDGET_CLASS (parent_class)->key_press_event)
+ handled = GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
+
+ if (handled)
+ return handled;
+
+ switch (event->keyval)
+ {
+ case GDK_Tab:
+ case GDK_ISO_Left_Tab:
+ if (event->state & GDK_SHIFT_MASK)
+ return gtk_container_focus (GTK_CONTAINER (widget),
+ GTK_DIR_TAB_BACKWARD);
+ else
+ return gtk_container_focus (GTK_CONTAINER (widget),
+ GTK_DIR_TAB_FORWARD);
+
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+title_focus (GtkCList * clist,
+ gint dir)
+{
+ GtkWidget *focus_child;
+ gboolean return_val = FALSE;
+ gint d = 1;
+ gint i = 0;
+ gint j;
+
+ if (!GTK_CLIST_SHOW_TITLES (clist))
+ return FALSE;
+
+ focus_child = GTK_CONTAINER (clist)->focus_child;
+
+ switch (dir)
+ {
+ case GTK_DIR_TAB_BACKWARD:
+ case GTK_DIR_UP:
+ if (!focus_child || focus_child == clist->hscrollbar ||
+ focus_child == clist->hscrollbar ||
+ !GTK_CLIST_CHILD_HAS_FOCUS (clist))
+ {
+ if (dir == GTK_DIR_UP)
+ i = COLUMN_FROM_XPIXEL (clist, 0);
+ else
+ i = clist->columns - 1;
+ focus_child = clist->column[i].button;
+ dir = GTK_DIR_TAB_FORWARD;
+ }
+ else
+ d = -1;
+ break;
+ case GTK_DIR_LEFT:
+ d = -1;
+ if (!focus_child || focus_child == clist->hscrollbar ||
+ focus_child == clist->hscrollbar)
+ {
+ i = clist->columns - 1;
+ focus_child = clist->column[i].button;
+ }
+ break;
+ case GTK_DIR_RIGHT:
+ if (!focus_child || focus_child == clist->hscrollbar ||
+ focus_child == clist->hscrollbar)
+ {
+ i = 0;
+ focus_child = clist->column[i].button;
+ }
+ break;
+ }
+
+ if (focus_child)
+ while (i < clist->columns)
+ {
+ if (clist->column[i].button == focus_child)
+ {
+ if (clist->column[i].button &&
+ GTK_WIDGET_VISIBLE (clist->column[i].button) &&
+ GTK_IS_CONTAINER (clist->column[i].button) &&
+ !GTK_WIDGET_HAS_FOCUS (clist->column[i].button))
+ if (gtk_container_focus
+ (GTK_CONTAINER (clist->column[i].button), dir))
+ {
+ return_val = TRUE;
+ i -= d;
+ }
+ if (!return_val && dir == GTK_DIR_UP)
+ return FALSE;
+ i += d;
+ break;
+ }
+ i++;
+ }
+
+ j = i;
+
+ if (!return_val)
+ while (j >= 0 && j < clist->columns)
+ {
+ if (clist->column[j].button &&
+ GTK_WIDGET_VISIBLE (clist->column[j].button))
+ {
+ if (GTK_IS_CONTAINER (clist->column[j].button) &&
+ gtk_container_focus
+ (GTK_CONTAINER (clist->column[j].button), dir))
+ {
+ return_val = TRUE;
+ break;
+ }
+ else if (GTK_WIDGET_CAN_FOCUS (clist->column[j].button))
+ {
+ gtk_widget_grab_focus (clist->column[j].button);
+ return_val = TRUE;
+ break;
+ }
+ }
+ j += d;
+ }
+
+ if (return_val)
+ {
+ if (COLUMN_LEFT_XPIXEL (clist, j) < CELL_SPACING + COLUMN_INSET)
+ gtk_clist_moveto (clist, -1, j, 0, 0);
+ else if (COLUMN_LEFT_XPIXEL(clist, j) + clist->column[j].area.width >
+ clist->clist_window_width)
+ {
+ if (j == clist->columns-1)
+ gtk_clist_moveto (clist, -1, j, 0, 0);
+ else
+ gtk_clist_moveto (clist, -1, j, 0, 1);
+ }
+ }
+ return return_val;
+}
+
+static gint
+gtk_clist_focus (GtkContainer * container,
+ GtkDirectionType direction)
+{
+ GtkCList *clist;
+ GtkWidget *focus_child;
+ gint old_row;
+
+ g_return_val_if_fail (container != NULL, FALSE);
+ g_return_val_if_fail (GTK_IS_CLIST (container), FALSE);
+
+ if (!GTK_WIDGET_SENSITIVE (container))
+ return FALSE;
+
+ clist = GTK_CLIST (container);
+ focus_child = container->focus_child;
+ old_row = clist->focus_row;
+
+ switch (direction)
+ {
+ case GTK_DIR_LEFT:
+ case GTK_DIR_RIGHT:
+ if (GTK_CLIST_CHILD_HAS_FOCUS (clist) &&
+ (!focus_child || (focus_child && focus_child != clist->vscrollbar &&
+ focus_child != clist->hscrollbar)))
+ {
+ if (title_focus (clist, direction))
+ return TRUE;
+ gtk_container_set_focus_child (container, NULL);
+ return FALSE;
+ }
+ gtk_widget_grab_focus (GTK_WIDGET (container));
+ return TRUE;
+ case GTK_DIR_DOWN:
+ case GTK_DIR_TAB_FORWARD:
+ if (GTK_CLIST_CHILD_HAS_FOCUS (clist) &&
+ (!focus_child || (focus_child != clist->vscrollbar &&
+ focus_child != clist->hscrollbar)))
+ {
+ gboolean tf = FALSE;
+
+ if (((focus_child && direction == GTK_DIR_DOWN) ||
+ !(tf = title_focus (clist, GTK_DIR_TAB_FORWARD)))
+ && clist->rows)
+ {
+ if (clist->focus_row < 0)
+ {
+ clist->focus_row = 0;
+
+ if ((clist->selection_mode == GTK_SELECTION_BROWSE ||
+ clist->selection_mode == GTK_SELECTION_EXTENDED) &&
+ !clist->selection)
+ select_row (clist, clist->focus_row, -1, NULL);
+ }
+ gtk_widget_grab_focus (GTK_WIDGET (container));
+ return TRUE;
+ }
+
+ if (tf)
+ return TRUE;
+ }
+
+ GTK_CLIST_SET_FLAG (clist, CLIST_CHILD_HAS_FOCUS);
+
+ if ((!GTK_CLIST_CHILD_HAS_FOCUS (clist) || !focus_child ||
+ (focus_child != clist->vscrollbar &&
+ focus_child != clist->hscrollbar)) &&
+ GTK_WIDGET_VISIBLE (clist->vscrollbar) &&
+ GTK_WIDGET_CAN_FOCUS (clist->vscrollbar))
+ {
+ gtk_widget_grab_focus (clist->vscrollbar);
+ return TRUE;
+ }
+
+ if ((!GTK_CLIST_CHILD_HAS_FOCUS (clist) || !focus_child ||
+ focus_child != clist->hscrollbar) &&
+ GTK_WIDGET_VISIBLE (clist->hscrollbar) &&
+ GTK_WIDGET_CAN_FOCUS (clist->hscrollbar))
+ {
+ gtk_widget_grab_focus (clist->hscrollbar);
+ return TRUE;
+ }
+ break;
+ case GTK_DIR_UP:
+ case GTK_DIR_TAB_BACKWARD:
+ if (!focus_child && GTK_CLIST_CHILD_HAS_FOCUS (clist) &&
+ GTK_WIDGET_VISIBLE (clist->hscrollbar) &&
+ GTK_WIDGET_CAN_FOCUS (clist->hscrollbar))
+ {
+ gtk_widget_grab_focus (clist->hscrollbar);
+ return TRUE;
+ }
+
+ if ((!focus_child || focus_child == clist->hscrollbar) &&
+ GTK_CLIST_CHILD_HAS_FOCUS (clist) &&
+ GTK_WIDGET_VISIBLE (clist->vscrollbar) &&
+ GTK_WIDGET_CAN_FOCUS (clist->vscrollbar))
+ {
+ gtk_widget_grab_focus (clist->vscrollbar);
+ return TRUE;
+ }
+
+ if ((!focus_child || focus_child == clist->hscrollbar ||
+ focus_child == clist->vscrollbar) &&
+ GTK_CLIST_CHILD_HAS_FOCUS (clist) && clist->rows)
+ {
+ if (clist->focus_row < 0)
+ {
+ clist->focus_row = 0;
+ if ((clist->selection_mode == GTK_SELECTION_BROWSE ||
+ clist->selection_mode == GTK_SELECTION_EXTENDED) &&
+ !clist->selection)
+ select_row (clist, clist->focus_row, -1, NULL);
+ }
+ gtk_widget_grab_focus (GTK_WIDGET (container));
+ return TRUE;
+ }
+
+ GTK_CLIST_SET_FLAG (clist, CLIST_CHILD_HAS_FOCUS);
+
+ if (title_focus (clist, direction))
+ return TRUE;
+
+ break;
+
+ default:
+ break;
+ }
+
+ gtk_container_set_focus_child (container, NULL);
+ return FALSE;
+}
+
+void
+gtk_clist_unselect_all (GtkCList * clist)
+{
+ GTK_CLIST_CLASS_FW (clist)->unselect_all (clist);
+}
+
+static void
+real_unselect_all (GtkCList * clist)
+{
+ GList *list;
+ gint i;
+
+ g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
+
+ if (gdk_pointer_is_grabbed ())
+ return;
+
+ switch (clist->selection_mode)
+ {
+ case GTK_SELECTION_BROWSE:
+ if (clist->focus_row >= 0)
+ {
+ select_row (clist, clist->focus_row, -1, NULL);
+ return;
+ }
+ break;
+
+ case GTK_SELECTION_EXTENDED:
+ g_list_free (clist->undo_selection);
+ g_list_free (clist->undo_unselection);
+ clist->undo_selection = NULL;
+ clist->undo_unselection = NULL;
+
+ clist->anchor = -1;
+ clist->drag_pos = -1;
+ clist->undo_anchor = clist->focus_row;
+ break;
+
+ default:
+ break;
+ }
+
+ list = clist->selection;
+
+ while (list)
+ {
+ i = GPOINTER_TO_INT (list->data);
+ list = list->next;
+ unselect_row (clist, i, -1, NULL);
+ }
+}
+
+void
+gtk_clist_select_all (GtkCList * clist)
+{
+ GTK_CLIST_CLASS_FW (clist)->select_all (clist);
+}
+
+static void
+real_select_all (GtkCList * clist)
+{
+ GList *list;
+ gint i;
+
+ g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
+
+ if (gdk_pointer_is_grabbed ())
+ return;
+
+ switch (clist->selection_mode)
+ {
+ case GTK_SELECTION_SINGLE:
+ case GTK_SELECTION_BROWSE:
+ return;
+
+ case GTK_SELECTION_EXTENDED:
+ g_list_free (clist->undo_selection);
+ g_list_free (clist->undo_unselection);
+ clist->undo_selection = NULL;
+ clist->undo_unselection = NULL;
+
+ if (clist->rows &&
+ ((GtkCListRow *) (clist->row_list->data))->state !=
+ GTK_STATE_SELECTED)
+ fake_toggle_row (clist, 0);
+
+ clist->anchor_state = GTK_STATE_SELECTED;
+ clist->anchor = 0;
+ clist->drag_pos = 0;
+ clist->undo_anchor = clist->focus_row;
+ update_extended_selection (clist, clist->rows);
+ GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+ return;
+
+ case GTK_SELECTION_MULTIPLE:
+ for (i = 0, list = clist->row_list; list; i++, list = list->next)
+ {
+ if (((GtkCListRow *)(list->data))->state == GTK_STATE_NORMAL)
+ gtk_signal_emit (GTK_OBJECT (clist), clist_signals[SELECT_ROW],
+ i, -1, NULL);
+ }
+ return;
+ }
+}
+
+static void
+fake_unselect_all (GtkCList * clist,
+ gint row)
+{
+ GList *list;
+ GList *work;
+ gint i;
+
+ if (row >= 0 && (work = g_list_nth (clist->row_list, row)))
+ {
+ if (GTK_CLIST_ROW (work)->state == GTK_STATE_NORMAL)
+ {
+ GTK_CLIST_ROW (work)->state = GTK_STATE_SELECTED;
+
+ if (!GTK_CLIST_FROZEN (clist) &&
+ gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE)
+ GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row,
+ GTK_CLIST_ROW (work));
+ }
+ }
+
+ clist->undo_selection = clist->selection;
+ clist->selection = NULL;
+ clist->selection_end = NULL;
+
+ for (list = clist->undo_selection; list; list = list->next)
+ {
+ if ((i = GPOINTER_TO_INT (list->data)) == row ||
+ !(work = g_list_nth (clist->row_list, i)))
+ continue;
+
+ GTK_CLIST_ROW (work)->state = GTK_STATE_NORMAL;
+ if (!GTK_CLIST_FROZEN (clist) &&
+ gtk_clist_row_is_visible (clist, i) != GTK_VISIBILITY_NONE)
+ GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, i,
+ GTK_CLIST_ROW (work));
+ }
+}
+
+static void
+fake_toggle_row (GtkCList *clist,
+ gint row)
+{
+ GList *work;
+
+ if (!(work = g_list_nth (clist->row_list, row)))
+ return;
+
+ if (GTK_CLIST_ROW (work)->state == GTK_STATE_NORMAL)
+ clist->anchor_state = GTK_CLIST_ROW (work)->state = GTK_STATE_SELECTED;
+ else
+ clist->anchor_state = GTK_CLIST_ROW (work)->state = GTK_STATE_NORMAL;
+
+ if (!GTK_CLIST_FROZEN (clist) &&
+ gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE)
+ GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row,
+ GTK_CLIST_ROW (work));
+}
+
+static GList *
+selection_find (GtkCList *clist,
+ gint row_number,
+ GList *row_list_element)
+{
+ return g_list_find (clist->selection, GINT_TO_POINTER (row_number));
+}
diff --git a/gtk/gtkclist.h b/gtk/gtkclist.h
index fb1ed5d58..ec347dda7 100644
--- a/gtk/gtkclist.h
+++ b/gtk/gtkclist.h
@@ -27,6 +27,7 @@
#include <gtk/gtkbutton.h>
#include <gtk/gtkhscrollbar.h>
#include <gtk/gtkvscrollbar.h>
+#include <gtk/gtkenums.h>
#ifdef __cplusplus
extern "C"
@@ -38,9 +39,12 @@ enum
{
GTK_CLIST_FROZEN = 1 << 0,
GTK_CLIST_IN_DRAG = 1 << 1,
- GTK_CLIST_ROW_HEIGHT_SET = 1 << 2,
- GTK_CLIST_SHOW_TITLES = 1 << 3,
- GTK_CLIST_CONSTRUCTED = 1 << 4
+ GTK_CLIST_DRAG_SELECTION = 1 << 2,
+ GTK_CLIST_ROW_HEIGHT_SET = 1 << 3,
+ GTK_CLIST_SHOW_TITLES = 1 << 4,
+ GTK_CLIST_CONSTRUCTED = 1 << 5,
+ GTK_CLIST_CHILD_HAS_FOCUS = 1 << 6,
+ GTK_CLIST_ADD_MODE = 1 << 7
};
/* cell types */
@@ -53,11 +57,11 @@ typedef enum
GTK_CELL_WIDGET
} GtkCellType;
-#define GTK_TYPE_CLIST (gtk_clist_get_type ())
-#define GTK_CLIST(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_CLIST, GtkCList))
-#define GTK_CLIST_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_CLIST, GtkCListClass))
-#define GTK_IS_CLIST(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_CLIST))
-#define GTK_IS_CLIST_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_CLIST))
+#define GTK_TYPE_CLIST (gtk_clist_get_type ())
+#define GTK_CLIST(obj) (GTK_CHECK_CAST ((obj), gtk_clist_get_type (), GtkCList))
+#define GTK_CLIST_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), gtk_clist_get_type (), GtkCListClass))
+#define GTK_IS_CLIST(obj) (GTK_CHECK_TYPE ((obj), gtk_clist_get_type ()))
+#define GTK_IS_CLIST_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_CLIST))
#define GTK_CLIST_FLAGS(clist) (GTK_CLIST (clist)->flags)
#define GTK_CLIST_SET_FLAG(clist,flag) (GTK_CLIST_FLAGS (clist) |= (GTK_ ## flag))
@@ -68,6 +72,11 @@ typedef enum
#define GTK_CLIST_ROW_HEIGHT_SET(clist) (GTK_CLIST_FLAGS (clist) & GTK_CLIST_ROW_HEIGHT_SET)
#define GTK_CLIST_SHOW_TITLES(clist) (GTK_CLIST_FLAGS (clist) & GTK_CLIST_SHOW_TITLES)
#define GTK_CLIST_CONSTRUCTED(clist) (GTK_CLIST_FLAGS (clist) & GTK_CLIST_CONSTRUCTED)
+#define GTK_CLIST_CHILD_HAS_FOCUS(clist) (GTK_CLIST_FLAGS (clist) & GTK_CLIST_CHILD_HAS_FOCUS)
+#define GTK_CLIST_DRAG_SELECTION(clist) (GTK_CLIST_FLAGS (clist) & GTK_CLIST_DRAG_SELECTION)
+#define GTK_CLIST_ADD_MODE(clist) (GTK_CLIST_FLAGS (clist) & GTK_CLIST_ADD_MODE)
+
+#define GTK_CLIST_ROW(_glist_) ((GtkCListRow *)((_glist_)->data))
/* pointer casting for cells */
#define GTK_CELL_TEXT(cell) (((GtkCellText *) &(cell)))
@@ -90,7 +99,7 @@ struct _GtkCList
{
GtkContainer container;
- guint8 flags;
+ guint16 flags;
/* mem chunks */
GMemChunk *row_mem_chunk;
@@ -133,6 +142,11 @@ struct _GtkCList
/* list of selected rows */
GList *selection;
+ GList *selection_end;
+
+ GList *undo_selection;
+ GList *undo_unselection;
+ gint undo_anchor;
/* scrollbars */
GtkWidget *vscrollbar;
@@ -152,6 +166,16 @@ struct _GtkCList
/* the current x-pixel location of the xor-drag line */
gint x_drag;
+
+ /* focus handling */
+ gint focus_row;
+
+ /* dragging the selection */
+ gint anchor;
+ GtkStateType anchor_state;
+ gint drag_pos;
+ gint htimer;
+ gint vtimer;
};
struct _GtkCListClass
@@ -161,17 +185,48 @@ struct _GtkCListClass
void (*select_row) (GtkCList * clist,
gint row,
gint column,
- GdkEventButton * event);
+ GdkEvent * event);
void (*unselect_row) (GtkCList * clist,
gint row,
gint column,
- GdkEventButton * event);
+ GdkEvent * event);
void (*click_column) (GtkCList * clist,
gint column);
+
+ void (*toggle_focus_row) (GtkCList * clist);
+ void (*select_all) (GtkCList * clist);
+ void (*unselect_all) (GtkCList * clist);
+ void (*undo_selection) (GtkCList * clist);
+ void (*start_selection) (GtkCList * clist);
+ void (*end_selection) (GtkCList * clist);
+ void (*extend_selection) (GtkCList * clist,
+ GtkScrollType scroll_type,
+ gfloat position,
+ gboolean auto_start_selection);
+ void (*scroll_horizontal) (GtkCList * clist,
+ GtkScrollType scroll_type,
+ gfloat position);
+ void (*scroll_vertical) (GtkCList * clist,
+ GtkScrollType scroll_type,
+ gfloat position);
+ void (*toggle_add_mode) (GtkCList * clist);
+ void (*abort_column_resize) (GtkCList * clist);
+
+ void (*resync_selection) (GtkCList * clist,
+ GdkEvent * event);
+ GList * (*selection_find) (GtkCList *clist,
+ gint row_number,
+ GList *row_list_element);
void (*draw_row) (GtkCList * clist,
GdkRectangle * area,
gint row,
GtkCListRow * clist_row);
+ void (*clear) (GtkCList * clist);
+ void (*fake_unselect_all) (GtkCList * clist,
+ gint row);
+
+
+
gint scrollbar_spacing;
};
@@ -364,9 +419,6 @@ void gtk_clist_moveto (GtkCList * clist,
GtkVisibility gtk_clist_row_is_visible (GtkCList * clist,
gint row);
-GtkAdjustment* gtk_clist_get_vadjustment (GtkCList * clist);
-GtkAdjustment* gtk_clist_get_hadjustment (GtkCList * clist);
-
/* returns the cell type */
GtkCellType gtk_clist_get_cell_type (GtkCList * clist,
gint row,
@@ -480,6 +532,9 @@ void gtk_clist_unselect_row (GtkCList * clist,
gint row,
gint column);
+/* undo the last select/unselect operation */
+void gtk_clist_undo_selection (GtkCList *clist);
+
/* clear the entire list -- this is much faster than removing each item
* with gtk_clist_remove */
void gtk_clist_clear (GtkCList * clist);
@@ -491,10 +546,14 @@ gint gtk_clist_get_selection_info (GtkCList * clist,
gint * row,
gint * column);
-/* swap the position of two rows */
-void gtk_clist_swap_rows (GtkCList * clist, gint row1, gint row2);
+/* in multiple or extended mode, select all rows */
+void gtk_clist_select_all (GtkCList *clist);
+/* in all modes except browse mode, deselect all rows */
+void gtk_clist_unselect_all (GtkCList *clist);
+/* swap the position of two rows */
+void gtk_clist_swap_rows (GtkCList * clist, gint row1, gint row2);
#ifdef __cplusplus
}
diff --git a/gtk/gtkctree.c b/gtk/gtkctree.c
index 5e001c178..503b163fe 100644
--- a/gtk/gtkctree.c
+++ b/gtk/gtkctree.c
@@ -23,7 +23,9 @@
#include <stdlib.h>
#include "gtkctree.h"
+#include "gtkbindings.h"
#include <gdk/gdkx.h>
+#include <gdk/gdkkeysyms.h>
#define PM_SIZE 8
#define TAB_SIZE (PM_SIZE + 6)
@@ -41,6 +43,9 @@
+ (clist)->hoffset)
#define COLUMN_LEFT(clist, column) ((clist)->column[(column)].area.x)
+#define GTK_CLIST_CLASS_FW(_widget_) GTK_CLIST_CLASS (GTK_OBJECT (_widget_)->klass)
+
+
static void gtk_ctree_class_init (GtkCTreeClass *klass);
static void gtk_ctree_init (GtkCTree *ctree);
static void gtk_ctree_destroy (GtkObject *object);
@@ -102,6 +107,7 @@ static void tree_delete (GtkCTree *ctree,
static void tree_delete_row (GtkCTree *ctree,
GList *node,
gpointer data);
+static void real_clear (GtkCList *clist);
static void tree_update_level (GtkCTree *ctree,
GList *node,
gpointer data);
@@ -111,12 +117,27 @@ static void tree_select (GtkCTree *ctree,
static void tree_unselect (GtkCTree *ctree,
GList *node,
gpointer data);
+static void real_select_all (GtkCList *clist);
+static void real_unselect_all (GtkCList *clist);
static void tree_expand (GtkCTree *ctree,
GList *node,
gpointer data);
static void tree_collapse (GtkCTree *ctree,
GList *node,
gpointer data);
+static void tree_toggle_expansion (GtkCTree *ctree,
+ GList *node,
+ gpointer data);
+static void change_focus_row_expansion (GtkCTree *ctree,
+ GtkCTreeExpansion expansion);
+static void real_select_row (GtkCList *clist,
+ gint row,
+ gint column,
+ GdkEvent *event);
+static void real_unselect_row (GtkCList *clist,
+ gint row,
+ gint column,
+ GdkEvent *event);
static void real_tree_select (GtkCTree *ctree,
GList *node,
gint column);
@@ -137,9 +158,11 @@ static void real_tree_move (GtkCTree *ctree,
static void gtk_ctree_link (GtkCTree *ctree,
GList *node,
GList *parent,
- GList *sibling);
+ GList *sibling,
+ gboolean update_focus_row);
static void gtk_ctree_unlink (GtkCTree *ctree,
- GList *node);
+ GList *node,
+ gboolean update_focus_row);
static GList * gtk_ctree_last_visible (GtkCTree *ctree,
GList *node);
static void gtk_ctree_marshal_signal_1 (GtkObject *object,
@@ -154,6 +177,10 @@ static void gtk_ctree_marshal_signal_3 (GtkObject *object,
GtkSignalFunc func,
gpointer func_data,
GtkArg *args);
+static void gtk_ctree_marshal_signal_4 (GtkObject *object,
+ GtkSignalFunc func,
+ gpointer func_data,
+ GtkArg *args);
static gboolean ctree_is_hot_spot (GtkCTree *ctree,
GList *node,
gint row,
@@ -166,6 +193,23 @@ static gint default_compare (GtkCTree *ctree,
const GList *node1,
const GList *node2);
+
+
+static void fake_unselect_all (GtkCList *clist,
+ gint row);
+static GList* selection_find (GtkCList *clist,
+ gint row_number,
+ GList *row_list_element);
+static void resync_selection (GtkCList *clist,
+ GdkEvent *event);
+static void real_undo_selection (GtkCList *clist);
+static void select_row_recursive (GtkCTree *ctree,
+ GList *node,
+ gpointer data);
+
+
+
+
enum
{
TREE_SELECT_ROW,
@@ -173,6 +217,7 @@ enum
TREE_EXPAND,
TREE_COLLAPSE,
TREE_MOVE,
+ CHANGE_FOCUS_ROW_EXPANSION,
LAST_SIGNAL
};
@@ -191,6 +236,10 @@ typedef void (*GtkCTreeSignal3) (GtkObject *object,
GList *arg1,
gpointer data);
+typedef void (*GtkCTreeSignal4) (GtkObject *object,
+ GtkCTreeExpansion arg1,
+ gpointer data);
+
static GtkCListClass *parent_class = NULL;
static GtkContainerClass *container_class = NULL;
@@ -264,6 +313,19 @@ gtk_ctree_marshal_signal_3 (GtkObject *object,
}
static void
+gtk_ctree_marshal_signal_4 (GtkObject *object,
+ GtkSignalFunc func,
+ gpointer func_data,
+ GtkArg *args)
+{
+ GtkCTreeSignal4 rfunc;
+
+ rfunc = (GtkCTreeSignal4) func;
+
+ (*rfunc) (object, GTK_VALUE_ENUM (args[0]), func_data);
+}
+
+static void
gtk_ctree_class_init (GtkCTreeClass *klass)
{
GtkObjectClass *object_class;
@@ -314,6 +376,14 @@ gtk_ctree_class_init (GtkCTreeClass *klass)
gtk_ctree_marshal_signal_2,
GTK_TYPE_NONE, 3, GTK_TYPE_POINTER, GTK_TYPE_POINTER,
GTK_TYPE_POINTER);
+ ctree_signals[CHANGE_FOCUS_ROW_EXPANSION] =
+ gtk_signal_new ("change_focus_row_expansion",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (GtkCTreeClass,
+ change_focus_row_expansion),
+ gtk_ctree_marshal_signal_4,
+ GTK_TYPE_NONE, 1, GTK_TYPE_ENUM);
gtk_object_class_add_signals (object_class, ctree_signals, LAST_SIGNAL);
@@ -325,16 +395,70 @@ gtk_ctree_class_init (GtkCTreeClass *klass)
widget_class->button_release_event = gtk_ctree_button_release;
widget_class->motion_notify_event = gtk_ctree_button_motion;
- clist_class->select_row = NULL;
- clist_class->unselect_row = NULL;
+ clist_class->select_row = real_select_row;
+ clist_class->unselect_row = real_unselect_row;
+ clist_class->undo_selection = real_undo_selection;
+ clist_class->resync_selection = resync_selection;
+ clist_class->selection_find = selection_find;
clist_class->click_column = NULL;
clist_class->draw_row = draw_row;
+ clist_class->clear = real_clear;
+ clist_class->select_all = real_select_all;
+ clist_class->unselect_all = real_unselect_all;
+ clist_class->fake_unselect_all = fake_unselect_all;
klass->tree_select_row = real_tree_select;
klass->tree_unselect_row = real_tree_unselect;
klass->tree_expand = real_tree_expand;
klass->tree_collapse = real_tree_collapse;
klass->tree_move = real_tree_move;
+ klass->change_focus_row_expansion = change_focus_row_expansion;
+
+ {
+ GtkBindingSet *binding_set;
+
+ binding_set = gtk_binding_set_by_class (klass);
+ gtk_binding_entry_add_signal (binding_set,
+ '+', GDK_SHIFT_MASK,
+ "change_focus_row_expansion", 1,
+ GTK_TYPE_ENUM, GTK_CTREE_EXPANSION_EXPAND);
+ gtk_binding_entry_add_signal (binding_set,
+ GDK_KP_Add, 0,
+ "change_focus_row_expansion", 1,
+ GTK_TYPE_ENUM, GTK_CTREE_EXPANSION_EXPAND);
+ gtk_binding_entry_add_signal (binding_set,
+ GDK_KP_Add, GDK_CONTROL_MASK,
+ "change_focus_row_expansion", 1,
+ GTK_TYPE_ENUM,
+ GTK_CTREE_EXPANSION_EXPAND_RECURSIVE);
+ gtk_binding_entry_add_signal (binding_set,
+ '-', 0,
+ "change_focus_row_expansion", 1,
+ GTK_TYPE_ENUM, GTK_CTREE_EXPANSION_COLLAPSE);
+ gtk_binding_entry_add_signal (binding_set,
+ GDK_KP_Subtract, 0,
+ "change_focus_row_expansion", 1,
+ GTK_TYPE_ENUM, GTK_CTREE_EXPANSION_COLLAPSE);
+ gtk_binding_entry_add_signal (binding_set,
+ GDK_KP_Subtract, GDK_CONTROL_MASK,
+ "change_focus_row_expansion", 1,
+ GTK_TYPE_ENUM,
+ GTK_CTREE_EXPANSION_COLLAPSE_RECURSIVE);
+ gtk_binding_entry_add_signal (binding_set,
+ '=', 0,
+ "change_focus_row_expansion", 1,
+ GTK_TYPE_ENUM, GTK_CTREE_EXPANSION_TOGGLE);
+ gtk_binding_entry_add_signal (binding_set,
+ GDK_KP_Multiply, 0,
+ "change_focus_row_expansion", 1,
+ GTK_TYPE_ENUM, GTK_CTREE_EXPANSION_TOGGLE);
+ gtk_binding_entry_add_signal (binding_set,
+ GDK_KP_Multiply, GDK_CONTROL_MASK,
+ "change_focus_row_expansion", 1,
+ GTK_TYPE_ENUM,
+ GTK_CTREE_EXPANSION_TOGGLE_RECURSIVE);
+ }
+
}
static void
@@ -344,7 +468,6 @@ gtk_ctree_init (GtkCTree *ctree)
ctree->drag_icon = NULL;
ctree->tree_indent = 20;
ctree->tree_column = 0;
- ctree->selection_last = NULL;
ctree->drag_row = -1;
ctree->drag_source = NULL;
ctree->drag_target = NULL;
@@ -371,7 +494,7 @@ gtk_ctree_destroy (GtkObject *object)
GTK_CLIST_SET_FLAG (clist, CLIST_FROZEN);
- gtk_ctree_clear (GTK_CTREE (object));
+ gtk_clist_clear (GTK_CLIST (object));
if (clist->vscrollbar)
{
@@ -458,6 +581,7 @@ gtk_ctree_button_press (GtkWidget *widget,
if (event->window == clist->clist_window)
{
+ gboolean collapse_expand = FALSE;
GList *work;
gint x;
gint y;
@@ -466,40 +590,105 @@ gtk_ctree_button_press (GtkWidget *widget,
x = event->x;
y = event->y;
- if (gtk_clist_get_selection_info (clist, x, y, &row, &column))
- {
- if (event->button == 1)
- ctree->drag_row = - 1 - ROW_FROM_YPIXEL (clist, y);
- work = g_list_nth (clist->row_list, row);
+ if (!gtk_clist_get_selection_info (clist, x, y, &row, &column))
+ return FALSE;
+
+ if (event->button == 2)
+ ctree->drag_row = - 1 - ROW_FROM_YPIXEL (clist, y);
+
+ work = g_list_nth (clist->row_list, row);
- if (GTK_CTREE_ROW (work)->children &&
- (event->type == GDK_2BUTTON_PRESS ||
- (ctree_is_hot_spot (ctree, work, row, x, y)
- && event->button == 1)))
- {
- if (GTK_CTREE_ROW (work)->expanded)
- gtk_ctree_collapse (ctree, work);
- else
- gtk_ctree_expand (ctree, work);
- }
- else if (ctree->reorderable && event->button == 1 && !ctree->in_drag)
+ if (ctree->reorderable && event->button == 2 && !ctree->in_drag &&
+ clist->anchor == -1)
+ {
+ gdk_pointer_grab (event->window, FALSE,
+ GDK_POINTER_MOTION_HINT_MASK |
+ GDK_BUTTON2_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
+ NULL, NULL, event->time);
+ ctree->in_drag = TRUE;
+ ctree->drag_source = work;
+ ctree->drag_target = NULL;
+ return FALSE;
+ }
+ else if (event->button == 1 &&
+ (GTK_CTREE_ROW (work)->children &&
+ (event->type == GDK_2BUTTON_PRESS ||
+ ctree_is_hot_spot (ctree, work, row, x, y))))
+ {
+ if (GTK_CTREE_ROW (work)->expanded)
+ gtk_ctree_collapse (ctree, work);
+ else
+ gtk_ctree_expand (ctree, work);
+
+ collapse_expand = TRUE;
+ }
+ if (event->button == 1)
+ {
+ gint old_row = clist->focus_row;
+ gboolean no_focus_row = FALSE;
+
+ switch (clist->selection_mode)
{
- gdk_pointer_grab (event->window, FALSE,
+ case GTK_SELECTION_MULTIPLE:
+ case GTK_SELECTION_SINGLE:
+ if (!collapse_expand)
+ break;
+
+ if (clist->focus_row == -1)
+ {
+ old_row = row;
+ no_focus_row = TRUE;
+ }
+
+ GTK_CLIST_SET_FLAG (clist, CLIST_DRAG_SELECTION);
+ gdk_pointer_grab (clist->clist_window, FALSE,
GDK_POINTER_MOTION_HINT_MASK |
GDK_BUTTON1_MOTION_MASK |
GDK_BUTTON_RELEASE_MASK,
NULL, NULL, event->time);
- ctree->in_drag = TRUE;
- ctree->drag_source = work;
- ctree->drag_target = NULL;
+
+ if (GTK_CLIST_ADD_MODE (clist))
+ {
+ GTK_CLIST_UNSET_FLAG (clist, CLIST_ADD_MODE);
+ if (GTK_WIDGET_HAS_FOCUS (widget))
+ {
+ gtk_widget_draw_focus (widget);
+ gdk_gc_set_line_attributes (clist->xor_gc, 1,
+ GDK_LINE_SOLID, 0, 0);
+ clist->focus_row = row;
+ gtk_widget_draw_focus (widget);
+ }
+ else
+ {
+ gdk_gc_set_line_attributes (clist->xor_gc, 1,
+ GDK_LINE_SOLID, 0, 0);
+ clist->focus_row = row;
+ }
+ }
+ else if (row != clist->focus_row)
+ {
+ if (GTK_WIDGET_HAS_FOCUS (widget))
+ {
+ gtk_widget_draw_focus (widget);
+ clist->focus_row = row;
+ gtk_widget_draw_focus (widget);
+ }
+ else
+ clist->focus_row = row;
+ }
+
+ if (!GTK_WIDGET_HAS_FOCUS (widget))
+ gtk_widget_grab_focus (widget);
+
return FALSE;
+
+ default:
+ break;
}
}
- return FALSE;
}
- return
- (* GTK_WIDGET_CLASS (parent_class)->button_press_event) (widget, event);
+ return GTK_WIDGET_CLASS (parent_class)->button_press_event (widget, event);
}
static gint
@@ -520,11 +709,12 @@ gtk_ctree_button_motion (GtkWidget *widget,
ctree = GTK_CTREE (widget);
clist = GTK_CLIST (widget);
- if (!ctree->reorderable)
- return
- (* GTK_WIDGET_CLASS (parent_class)->motion_notify_event) (widget, event);
+ if (GTK_CLIST_IN_DRAG (clist))
+ return GTK_WIDGET_CLASS (parent_class)->motion_notify_event
+ (widget, event);
- if (event->window == clist->clist_window && ctree->in_drag)
+ if (event->window == clist->clist_window &&
+ ctree->in_drag && ctree->reorderable)
{
GdkModifierType modmask;
gint root_x;
@@ -540,8 +730,7 @@ gtk_ctree_button_motion (GtkWidget *widget,
y >= ROW_TOP_YPIXEL (clist, -ctree->drag_row-1) &&
y <= ROW_TOP_YPIXEL (clist, -ctree->drag_row-1) + clist->row_height)
return
- (* GTK_WIDGET_CLASS (parent_class)->motion_notify_event)
- (widget, event);
+ GTK_WIDGET_CLASS (parent_class)->motion_notify_event (widget, event);
if (ctree->use_icons)
{
@@ -585,7 +774,7 @@ gtk_ctree_button_motion (GtkWidget *widget,
if (y < 0 || y > clist->clist_window_height ||
ROW_TOP_YPIXEL (clist, row + 1) > clist->clist_window_height
|| row >= clist->rows)
- return (* GTK_WIDGET_CLASS (parent_class)->motion_notify_event)
+ return GTK_WIDGET_CLASS (parent_class)->motion_notify_event
(widget, event);
if (y - ROW_TOP_YPIXEL (clist, row) < clist->row_height / 4)
@@ -632,8 +821,7 @@ gtk_ctree_button_motion (GtkWidget *widget,
}
}
}
- return
- (* GTK_WIDGET_CLASS (parent_class)->motion_notify_event) (widget, event);
+ return GTK_WIDGET_CLASS (parent_class)->motion_notify_event (widget, event);
}
static gint
@@ -650,7 +838,7 @@ gtk_ctree_button_release (GtkWidget *widget,
ctree = GTK_CTREE (widget);
clist = GTK_CLIST (widget);
- if (event->button == 1)
+ if (event->button == 2 && clist->anchor == -1)
{
gdk_pointer_ungrab (event->time);
ctree->in_drag = FALSE;
@@ -672,40 +860,13 @@ gtk_ctree_button_release (GtkWidget *widget,
draw_xor_line (ctree);
ctree->drag_row = -1;
}
- else
- {
- if (event->window == clist->clist_window)
- {
- gint row;
- gint column;
- GList *work;
-
- if (gtk_clist_get_selection_info (clist, event->x, event->y,
- &row, &column))
- if (row == - (ctree->drag_row + 1) &&
- (work = g_list_nth (clist->row_list, row)))
- {
- if (GTK_CTREE_ROW (work)->children &&
- ctree_is_hot_spot (ctree, work, row, event->x,
- event->y))
- return (* GTK_WIDGET_CLASS (parent_class)
- ->button_release_event) (widget, event);
- tree_toggle_selection (ctree, work, column);
- }
- return FALSE;
- }
- return
- (* GTK_WIDGET_CLASS (parent_class)->button_release_event)
- (widget, event);
- }
/* nop if out of bounds / source == target */
if (event->x < 0 || event->y < -3 ||
event->x > clist->clist_window_width ||
event->y > clist->clist_window_height + 3 ||
ctree->drag_target == ctree->drag_source)
- return
- (* GTK_WIDGET_CLASS (parent_class)->button_release_event)
+ return GTK_WIDGET_CLASS (parent_class)->button_release_event
(widget, event);
if (!GTK_CTREE_ROW (ctree->drag_source)->children ||
@@ -746,8 +907,24 @@ gtk_ctree_button_release (GtkWidget *widget,
ctree->drag_source = NULL;
ctree->drag_target = NULL;
}
- return
- (* GTK_WIDGET_CLASS (parent_class)->button_release_event) (widget, event);
+ else if (event->button == 1 && GTK_CLIST_DRAG_SELECTION (clist) &&
+ (clist->selection_mode == GTK_SELECTION_SINGLE ||
+ clist->selection_mode == GTK_SELECTION_MULTIPLE))
+ {
+ gint row;
+ gint column;
+ GList *work;
+
+ if (gtk_clist_get_selection_info
+ (clist, event->x, event->y, &row, &column))
+ {
+ if (clist->anchor == clist->focus_row &&
+ (work = g_list_nth (clist->row_list, row)))
+ tree_toggle_selection (ctree, work, column);
+ }
+ clist->anchor = -1;
+ }
+ return GTK_WIDGET_CLASS (parent_class)->button_release_event (widget, event);
}
static void
@@ -2246,6 +2423,26 @@ draw_row (GtkCList *clist,
}
}
}
+ if (clist->focus_row == row && GTK_WIDGET_HAS_FOCUS (widget))
+ {
+ if (area)
+ {
+ if (gdk_rectangle_intersect (area, &row_rectangle,
+ &intersect_rectangle))
+ {
+ gdk_gc_set_clip_rectangle (clist->xor_gc, &intersect_rectangle);
+ gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE,
+ row_rectangle.x, row_rectangle.y,
+ row_rectangle.width - 1,
+ row_rectangle.height - 1);
+ gdk_gc_set_clip_rectangle (clist->xor_gc, NULL);
+ }
+ }
+ else
+ gdk_draw_rectangle (clist->clist_window, clist->xor_gc, FALSE,
+ row_rectangle.x, row_rectangle.y,
+ row_rectangle.width - 1, row_rectangle.height - 1);
+ }
}
static void
@@ -2268,8 +2465,8 @@ tree_draw_row (GtkCTree *ctree,
num++;
}
if (gtk_clist_row_is_visible (clist, num) != GTK_VISIBILITY_NONE)
- (GTK_CLIST_CLASS (GTK_OBJECT (clist)->klass)->draw_row)
- (clist, NULL, num, &(GTK_CTREE_ROW (row)->row));
+ GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, num,
+ GTK_CLIST_ROW (row));
}
}
@@ -2297,11 +2494,12 @@ static void
gtk_ctree_link (GtkCTree *ctree,
GList *node,
GList *parent,
- GList *sibling)
+ GList *sibling,
+ gboolean update_focus_row)
{
GtkCList *clist;
GList *list_end;
- gint visible = TRUE;
+ gboolean visible = FALSE;
gint rows = 0;
g_return_if_fail (!sibling || GTK_CTREE_ROW (sibling)->parent == parent);
@@ -2311,20 +2509,30 @@ gtk_ctree_link (GtkCTree *ctree,
clist = GTK_CLIST (ctree);
+ if (update_focus_row && clist->selection_mode == GTK_SELECTION_BROWSE)
+ {
+ if (clist->anchor != -1)
+ GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+
+ g_list_free (clist->undo_selection);
+ g_list_free (clist->undo_unselection);
+ clist->undo_selection = NULL;
+ clist->undo_unselection = NULL;
+ }
+
for (rows = 1, list_end = node; list_end->next; list_end = list_end->next)
rows++;
GTK_CTREE_ROW (node)->parent = parent;
GTK_CTREE_ROW (node)->sibling = sibling;
- if (parent)
+ if (!parent || (parent && (gtk_ctree_is_visible (ctree, parent) &&
+ GTK_CTREE_ROW (parent)->expanded)))
{
- if ((visible = gtk_ctree_is_visible (ctree, parent)) &&
- GTK_CTREE_ROW (parent)->expanded)
- clist->rows += rows;
+ visible = TRUE;
+ clist->rows += rows;
}
- else
- clist->rows += rows;
+
if (sibling)
{
@@ -2407,13 +2615,24 @@ gtk_ctree_link (GtkCTree *ctree,
if (clist->row_list_end == NULL || clist->row_list_end->next == node)
clist->row_list_end = list_end;
- if (!GTK_CLIST_FROZEN (clist) && visible)
- gtk_clist_thaw (clist);
+ if (visible && update_focus_row)
+ {
+ gint pos;
+
+ pos = g_list_position (clist->row_list, node);
+
+ if (pos <= clist->focus_row)
+ {
+ clist->focus_row += rows;
+ clist->undo_anchor = clist->focus_row;
+ }
+ }
}
static void
gtk_ctree_unlink (GtkCTree *ctree,
- GList *node)
+ GList *node,
+ gboolean update_focus_row)
{
GtkCList *clist;
gint rows;
@@ -2428,6 +2647,17 @@ gtk_ctree_unlink (GtkCTree *ctree,
clist = GTK_CLIST (ctree);
+ if (update_focus_row && clist->selection_mode == GTK_SELECTION_BROWSE)
+ {
+ if (clist->anchor != -1)
+ GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+
+ g_list_free (clist->undo_selection);
+ g_list_free (clist->undo_unselection);
+ clist->undo_selection = NULL;
+ clist->undo_unselection = NULL;
+ }
+
visible = gtk_ctree_is_visible (ctree, node);
/* clist->row_list_end unlinked ? */
@@ -2446,6 +2676,24 @@ gtk_ctree_unlink (GtkCTree *ctree,
rows++;
}
+ if (visible)
+ {
+ clist->rows -= (rows + 1);
+
+ if (update_focus_row)
+ {
+ gint pos;
+
+ pos = g_list_position (clist->row_list, node);
+ if (pos + rows + 1 < clist->focus_row)
+ clist->focus_row -= (rows + 1);
+ else if (pos <= clist->focus_row)
+ clist->focus_row = pos - 1;
+ clist->undo_anchor = clist->focus_row;
+ }
+ }
+
+
if (work)
{
work->prev->next = NULL;
@@ -2499,14 +2747,6 @@ gtk_ctree_unlink (GtkCTree *ctree,
GTK_CTREE_ROW (sibling)->sibling = GTK_CTREE_ROW (node)->sibling;
}
}
-
- if (visible)
- {
- clist->rows -= (rows + 1);
-
- if (!GTK_CLIST_FROZEN (clist))
- gtk_clist_thaw (clist);
- }
}
static void
@@ -2534,6 +2774,17 @@ real_tree_move (GtkCTree *ctree,
clist = GTK_CLIST (ctree);
+ if (clist->selection_mode == GTK_SELECTION_BROWSE)
+ {
+ if (clist->anchor != -1)
+ GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+
+ g_list_free (clist->undo_selection);
+ g_list_free (clist->undo_unselection);
+ clist->undo_selection = NULL;
+ clist->undo_unselection = NULL;
+ }
+
if (ctree->auto_sort)
{
if (new_parent == GTK_CTREE_ROW (node)->parent)
@@ -2558,23 +2809,87 @@ real_tree_move (GtkCTree *ctree,
thaw = TRUE;
}
- gtk_ctree_unlink (ctree, node);
- gtk_ctree_link (ctree, node, new_parent, new_sibling);
+ work = NULL;
+ if (gtk_ctree_is_visible (ctree, node) ||
+ gtk_ctree_is_visible (ctree, new_sibling))
+ work = g_list_nth (clist->row_list, clist->focus_row);
+
+ gtk_ctree_unlink (ctree, node, FALSE);
+ gtk_ctree_link (ctree, node, new_parent, new_sibling, FALSE);
+
+ if (work)
+ {
+ while (work && !gtk_ctree_is_visible (ctree, work))
+ work = GTK_CTREE_ROW (work)->parent;
+ clist->focus_row = g_list_position (clist->row_list, work);
+ clist->undo_anchor = clist->focus_row;
+ }
if (thaw)
gtk_clist_thaw (clist);
}
+static void
+change_focus_row_expansion (GtkCTree *ctree,
+ GtkCTreeExpansion action)
+{
+ GtkCList *clist;
+ GList *node;
+
+ g_return_if_fail (ctree != NULL);
+ g_return_if_fail (GTK_IS_CTREE (ctree));
+
+ clist = GTK_CLIST (ctree);
+
+ if (gdk_pointer_is_grabbed ())
+ return;
+
+ if (!(node = g_list_nth (clist->row_list, clist->focus_row)) ||
+ GTK_CTREE_ROW (node)->is_leaf || !(GTK_CTREE_ROW (node)->children))
+ return;
+
+ switch (action)
+ {
+ case GTK_CTREE_EXPANSION_EXPAND:
+ gtk_ctree_expand (ctree, node);
+ break;
+ case GTK_CTREE_EXPANSION_EXPAND_RECURSIVE:
+ gtk_ctree_expand_recursive (ctree, node);
+ break;
+ case GTK_CTREE_EXPANSION_COLLAPSE:
+ gtk_ctree_collapse (ctree, node);
+ break;
+ case GTK_CTREE_EXPANSION_COLLAPSE_RECURSIVE:
+ gtk_ctree_collapse_recursive (ctree, node);
+ break;
+ case GTK_CTREE_EXPANSION_TOGGLE:
+ gtk_ctree_toggle_expansion (ctree, node);
+ break;
+ case GTK_CTREE_EXPANSION_TOGGLE_RECURSIVE:
+ gtk_ctree_toggle_expansion_recursive (ctree, node);
+ break;
+ }
+}
+
static void
real_tree_expand (GtkCTree *ctree,
GList *node)
{
+ GtkCList *clist;
GList *work;
gint level;
+ g_return_if_fail (ctree != NULL);
+ g_return_if_fail (GTK_IS_CTREE (ctree));
+
if (!node || GTK_CTREE_ROW (node)->expanded)
return;
+ clist = GTK_CLIST (ctree);
+
+ if (clist->selection_mode == GTK_SELECTION_EXTENDED && clist->anchor >= 0)
+ GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+
GTK_CTREE_ROW (node)->expanded = TRUE;
level = GTK_CTREE_ROW (node)->level;
@@ -2591,7 +2906,11 @@ real_tree_expand (GtkCTree *ctree,
work = GTK_CTREE_ROW (node)->children;
if (work)
{
+ GtkCList *clist;
gint tmp = 0;
+ gint row;
+
+ clist = GTK_CLIST (ctree);
while (work->next)
{
@@ -2604,15 +2923,18 @@ real_tree_expand (GtkCTree *ctree,
if (node->next)
node->next->prev = work;
else
- GTK_CLIST (ctree)->row_list_end = work;
+ clist->row_list_end = work;
node->next = GTK_CTREE_ROW (node)->children;
if (gtk_ctree_is_visible (ctree, node))
{
- GTK_CLIST (ctree)->rows += tmp + 1;
+ row = g_list_position (clist->row_list, node);
+ if (row < clist->focus_row)
+ clist->focus_row += tmp + 1;
+ clist->rows += tmp + 1;
if (!GTK_CLIST_FROZEN (ctree))
- gtk_clist_thaw (GTK_CLIST (ctree));
+ gtk_clist_thaw (clist);
}
}
}
@@ -2621,12 +2943,21 @@ static void
real_tree_collapse (GtkCTree *ctree,
GList *node)
{
+ GtkCList *clist;
GList *work;
gint level;
+ g_return_if_fail (ctree != NULL);
+ g_return_if_fail (GTK_IS_CTREE (ctree));
+
if (!node || !GTK_CTREE_ROW (node)->expanded)
return;
+ clist = GTK_CLIST (ctree);
+
+ if (clist->selection_mode == GTK_SELECTION_EXTENDED && clist->anchor >= 0)
+ GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+
GTK_CTREE_ROW (node)->expanded = FALSE;
level = GTK_CTREE_ROW (node)->level;
@@ -2643,7 +2974,11 @@ real_tree_collapse (GtkCTree *ctree,
work = GTK_CTREE_ROW (node)->children;
if (work)
{
+ GtkCList *clist;
gint tmp = 0;
+ gint row;
+
+ clist = GTK_CLIST (ctree);
while (work && GTK_CTREE_ROW (work)->level > level)
{
@@ -2660,14 +2995,17 @@ real_tree_collapse (GtkCTree *ctree,
else
{
node->next = NULL;
- GTK_CLIST (ctree)->row_list_end = node;
+ clist->row_list_end = node;
}
if (gtk_ctree_is_visible (ctree, node))
{
- GTK_CLIST (ctree)->rows -= tmp;
+ row = g_list_position (clist->row_list, node);
+ if (row < clist->focus_row)
+ clist->focus_row -= tmp;
+ clist->rows -= tmp;
if (!GTK_CLIST_FROZEN (ctree))
- gtk_clist_thaw (GTK_CLIST (ctree));
+ gtk_clist_thaw (clist);
}
}
}
@@ -2812,8 +3150,8 @@ tree_delete (GtkCTree *ctree,
work = g_list_find (clist->selection, node);
if (work)
{
- if (ctree->selection_last && ctree->selection_last == work)
- ctree->selection_last = ctree->selection_last->prev;
+ if (clist->selection_end && clist->selection_end == work)
+ clist->selection_end = clist->selection_end->prev;
clist->selection = g_list_remove (clist->selection, node);
}
}
@@ -2886,6 +3224,22 @@ tree_collapse (GtkCTree *ctree,
data);
}
+static void
+tree_toggle_expansion (GtkCTree *ctree,
+ GList *node,
+ gpointer data)
+{
+ if (!node)
+ return;
+
+ if (GTK_CTREE_ROW (node)->expanded)
+ gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_COLLAPSE], node,
+ data);
+ else
+ gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_EXPAND], node,
+ data);
+}
+
static GtkCTreeRow *
row_new (GtkCTree *ctree)
{
@@ -3003,12 +3357,46 @@ cell_empty (GtkCList *clist,
}
static void
+real_select_row (GtkCList *clist,
+ gint row,
+ gint column,
+ GdkEvent *event)
+{
+ GList *node;
+
+ g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CTREE (clist));
+
+ if ((node = g_list_nth (clist->row_list, row)))
+ gtk_signal_emit (GTK_OBJECT (clist), ctree_signals[TREE_SELECT_ROW],
+ node, event);
+}
+
+static void
+real_unselect_row (GtkCList *clist,
+ gint row,
+ gint column,
+ GdkEvent *event)
+{
+ GList *node;
+
+ g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CTREE (clist));
+
+ if ((node = g_list_nth (clist->row_list, row)))
+ gtk_signal_emit (GTK_OBJECT (clist), ctree_signals[TREE_UNSELECT_ROW],
+ node, event);
+}
+
+static void
real_tree_select (GtkCTree *ctree,
GList *node,
gint column)
{
GtkCList *clist;
- GList *selection;
+ GList *list;
+ GList *sel_row;
+ gboolean node_selected;
g_return_if_fail (ctree != NULL);
@@ -3017,15 +3405,12 @@ real_tree_select (GtkCTree *ctree,
clist = GTK_CLIST (ctree);
- if (GTK_CTREE_ROW (node)->row.state == GTK_STATE_SELECTED)
- return;
-
- if (clist->selection_mode == GTK_SELECTION_SINGLE ||
- clist->selection_mode == GTK_SELECTION_BROWSE)
+ switch (clist->selection_mode)
{
- GList *list;
- GList *sel_row;
+ case GTK_SELECTION_SINGLE:
+ case GTK_SELECTION_BROWSE:
+ node_selected = FALSE;
list = clist->selection;
while (list)
@@ -3033,27 +3418,29 @@ real_tree_select (GtkCTree *ctree,
sel_row = list->data;
list = list->next;
- if (node != sel_row &&
- GTK_CTREE_ROW (sel_row)->row.state == GTK_STATE_SELECTED)
- gtk_signal_emit (GTK_OBJECT (ctree),
- ctree_signals[TREE_UNSELECT_ROW], sel_row,
- column);
+ if (node == sel_row)
+ node_selected = TRUE;
+ else
+ gtk_signal_emit (GTK_OBJECT (ctree),
+ ctree_signals[TREE_UNSELECT_ROW], sel_row, column);
}
+
+ if (node_selected)
+ return;
+
+ default:
+ break;
}
GTK_CTREE_ROW (node)->row.state = GTK_STATE_SELECTED;
- selection = g_list_alloc ();
- selection->data = node;
- if (ctree->selection_last)
+ if (!clist->selection)
{
- ctree->selection_last->next = selection;
- selection->prev = ctree->selection_last;
+ clist->selection = g_list_append (clist->selection, node);
+ clist->selection_end = clist->selection;
}
- else
- clist->selection = selection;
-
- ctree->selection_last = selection;
+ else
+ clist->selection_end = g_list_append (clist->selection_end, node)->next;
tree_draw_row (ctree, node);
}
@@ -3070,15 +3457,16 @@ real_tree_unselect (GtkCTree *ctree,
if (!node)
return;
+ clist = GTK_CLIST (ctree);
+
if (GTK_CTREE_ROW (node)->row.state != GTK_STATE_SELECTED)
return;
- clist = GTK_CLIST (ctree);
-
- if (ctree->selection_last && ctree->selection_last->data == node)
- ctree->selection_last = ctree->selection_last->prev;
+ if (clist->selection_end && clist->selection_end->data == node)
+ clist->selection_end = clist->selection_end->prev;
clist->selection = g_list_remove (clist->selection, node);
+
GTK_CTREE_ROW (node)->row.state = GTK_STATE_NORMAL;
tree_draw_row (ctree, node);
@@ -3089,7 +3477,14 @@ tree_toggle_selection (GtkCTree *ctree,
GList *node,
gint column)
{
- switch (GTK_CLIST (ctree)->selection_mode)
+ GtkCList *clist;
+
+ g_return_if_fail (ctree != NULL);
+ g_return_if_fail (GTK_IS_CTREE (ctree));
+
+ clist = GTK_CLIST (ctree);
+
+ switch (clist->selection_mode)
{
case GTK_SELECTION_SINGLE:
case GTK_SELECTION_MULTIPLE:
@@ -3109,10 +3504,117 @@ tree_toggle_selection (GtkCTree *ctree,
case GTK_SELECTION_EXTENDED:
break;
+ }
+}
+
+static void
+select_row_recursive (GtkCTree *ctree,
+ GList *node,
+ gpointer data)
+{
+ if (!node || GTK_CTREE_ROW (node)->row.state == GTK_STATE_SELECTED)
+ return;
+
+ GTK_CLIST (ctree)->undo_unselection =
+ g_list_prepend (GTK_CLIST (ctree)->undo_unselection, node);
+ gtk_ctree_select (ctree, node);
+}
+
+static void
+real_select_all (GtkCList *clist)
+{
+ GtkCTree *ctree;
+ GList *node;
+ gboolean thaw = FALSE;
+
+ g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CTREE (clist));
+
+ ctree = GTK_CTREE (clist);
+
+ switch (clist->selection_mode)
+ {
+ case GTK_SELECTION_SINGLE:
+ case GTK_SELECTION_BROWSE:
+ return;
+
+ case GTK_SELECTION_EXTENDED:
+
+ if (!GTK_CLIST_FROZEN (clist))
+ {
+ gtk_clist_freeze (clist);
+ thaw = TRUE;
+ }
+
+ g_list_free (clist->undo_selection);
+ g_list_free (clist->undo_unselection);
+ clist->undo_selection = NULL;
+ clist->undo_unselection = NULL;
+
+ clist->anchor_state = GTK_STATE_SELECTED;
+ clist->anchor = -1;
+ clist->drag_pos = -1;
+ clist->undo_anchor = clist->focus_row;
+
+ for (node = clist->row_list; node; node = node->next)
+ gtk_ctree_pre_recursive (ctree, node, select_row_recursive, NULL);
+
+ if (thaw)
+ gtk_clist_thaw (clist);
+ break;
+
+ case GTK_SELECTION_MULTIPLE:
+ gtk_ctree_select_recursive (ctree, NULL);
+ break;;
+ }
+}
+
+static void
+real_unselect_all (GtkCList *clist)
+{
+ GtkCTree *ctree;
+ GList *list;
+ GList *node;
+
+ g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CTREE (clist));
+
+ ctree = GTK_CTREE (clist);
+
+ switch (clist->selection_mode)
+ {
+ case GTK_SELECTION_BROWSE:
+ if (clist->focus_row >= 0)
+ {
+ gtk_ctree_select
+ (ctree, g_list_nth (clist->row_list, clist->focus_row));
+ return;
+ }
+ break;
+
+ case GTK_SELECTION_EXTENDED:
+ g_list_free (clist->undo_selection);
+ g_list_free (clist->undo_unselection);
+ clist->undo_selection = NULL;
+ clist->undo_unselection = NULL;
+
+ clist->anchor = -1;
+ clist->drag_pos = -1;
+ clist->undo_anchor = clist->focus_row;
+ break;
default:
break;
}
+
+ list = clist->selection;
+
+ while (list)
+ {
+ node = list->data;
+ list = list->next;
+ gtk_ctree_unselect (ctree, node);
+ }
}
static gboolean
@@ -3290,7 +3792,10 @@ gtk_ctree_insert (GtkCTree *ctree,
sibling = GTK_CTREE_ROW (sibling)->sibling;
}
- gtk_ctree_link (ctree, node, parent, sibling);
+ gtk_ctree_link (ctree, node, parent, sibling, TRUE);
+
+ if (!GTK_CLIST_FROZEN (clist))
+ gtk_clist_thaw (clist);
return node;
}
@@ -3315,55 +3820,40 @@ gtk_ctree_remove (GtkCTree *ctree,
if (node)
{
- gtk_ctree_unlink (ctree, node);
- gtk_ctree_post_recursive (ctree, node, GTK_CTREE_FUNC (tree_delete),
+ gtk_ctree_unlink (ctree, node, TRUE);
+ gtk_ctree_post_recursive (ctree, node, GTK_CTREE_FUNC (tree_delete),
NULL);
}
else
- {
- GList *work;
- GList *ptr;
-
- work = clist->row_list;
- clist->row_list = NULL;
- clist->row_list_end = NULL;
- clist->rows = 0;
-
- while (work)
- {
- ptr = work;
- work = GTK_CTREE_ROW (work)->sibling;
- gtk_ctree_post_recursive (ctree, ptr, GTK_CTREE_FUNC (tree_delete),
- NULL);
- }
- }
+ gtk_clist_clear (clist);
if (thaw)
gtk_clist_thaw (clist);
}
-void
-gtk_ctree_clear (GtkCTree *ctree)
+static void
+real_clear (GtkCList *clist)
{
- GtkCList *clist;
+ GtkCTree *ctree;
GList *work;
GList *ptr;
- g_return_if_fail (ctree != NULL);
- g_return_if_fail (GTK_IS_CTREE (ctree));
+ g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CTREE (clist));
- clist = GTK_CLIST (ctree);
+ ctree = GTK_CTREE (clist);
- /* free up the selection list */
- g_list_free (clist->selection);
- clist->selection = NULL;
- ctree->selection_last = NULL;
+ ctree->drag_row = -1;
+ ctree->drag_rect = FALSE;
+ ctree->in_drag = FALSE;
+ ctree->drag_source = NULL;
+ ctree->drag_target = NULL;
+ ctree->drag_icon = NULL;
/* remove all the rows */
work = clist->row_list;
clist->row_list = NULL;
clist->row_list_end = NULL;
- clist->rows = 0;
while (work)
{
@@ -3373,25 +3863,7 @@ gtk_ctree_clear (GtkCTree *ctree)
NULL);
}
- clist->voffset = 0;
-
- ctree->drag_row = -1;
- ctree->drag_rect = FALSE;
- ctree->in_drag = FALSE;
- ctree->drag_source = NULL;
- ctree->drag_target = NULL;
- ctree->drag_icon = NULL;
-
- /* zero-out the scrollbars */
- if (clist->vscrollbar)
- {
- GTK_RANGE (clist->vscrollbar)->adjustment->value = 0.0;
- gtk_signal_emit_by_name
- (GTK_OBJECT (GTK_RANGE (clist->vscrollbar)->adjustment), "changed");
-
- if (!GTK_CLIST_FROZEN (clist))
- gtk_clist_thaw (clist);
- }
+ (parent_class->clear) (clist);
}
@@ -3422,7 +3894,8 @@ gtk_ctree_post_recursive (GtkCTree *ctree,
work = tmp;
}
- (* func) (ctree, node, data);
+ if (node)
+ func (ctree, node, data);
}
void
@@ -3434,10 +3907,12 @@ gtk_ctree_pre_recursive (GtkCTree *ctree,
GList *work;
GList *tmp;
- (* func) (ctree, node, data);
if (node)
- work = GTK_CTREE_ROW (node)->children;
+ {
+ work = GTK_CTREE_ROW (node)->children;
+ func (ctree, node, data);
+ }
else
work = GTK_CLIST (ctree)->row_list;
@@ -3595,6 +4070,9 @@ gtk_ctree_expand (GtkCTree *ctree,
g_return_if_fail (ctree != NULL);
g_return_if_fail (node != NULL);
+ if (GTK_CTREE_ROW (node)->is_leaf)
+ return;
+
gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_EXPAND], node);
}
@@ -3609,7 +4087,7 @@ gtk_ctree_expand_recursive (GtkCTree *ctree,
clist = GTK_CLIST (ctree);
- if (node && !GTK_CTREE_ROW (node)->children)
+ if (node && GTK_CTREE_ROW (node)->is_leaf)
return;
if (((node && gtk_ctree_is_visible (ctree, node)) || !node) &&
@@ -3632,6 +4110,9 @@ gtk_ctree_collapse (GtkCTree *ctree,
g_return_if_fail (ctree != NULL);
g_return_if_fail (node != NULL);
+ if (GTK_CTREE_ROW (node)->is_leaf)
+ return;
+
gtk_signal_emit (GTK_OBJECT (ctree), ctree_signals[TREE_COLLAPSE], node);
}
@@ -3644,11 +4125,11 @@ gtk_ctree_collapse_recursive (GtkCTree *ctree,
g_return_if_fail (ctree != NULL);
- clist = GTK_CLIST (ctree);
-
- if (node && !GTK_CTREE_ROW (node)->children)
+ if (node && GTK_CTREE_ROW (node)->is_leaf)
return;
+ clist = GTK_CLIST (ctree);
+
if (((node && gtk_ctree_is_visible (ctree, node)) || !node) &&
!GTK_CLIST_FROZEN (clist))
{
@@ -3663,6 +4144,47 @@ gtk_ctree_collapse_recursive (GtkCTree *ctree,
}
void
+gtk_ctree_toggle_expansion (GtkCTree *ctree,
+ GList *node)
+{
+ g_return_if_fail (ctree != NULL);
+ g_return_if_fail (node != NULL);
+
+ if (GTK_CTREE_ROW (node)->is_leaf)
+ return;
+
+ tree_toggle_expansion (ctree, node, NULL);
+}
+
+void
+gtk_ctree_toggle_expansion_recursive (GtkCTree *ctree,
+ GList *node)
+{
+ GtkCList *clist;
+ gboolean thaw = FALSE;
+
+ g_return_if_fail (ctree != NULL);
+
+ if (node && GTK_CTREE_ROW (node)->is_leaf)
+ return;
+
+ clist = GTK_CLIST (ctree);
+
+ if (((node && gtk_ctree_is_visible (ctree, node)) || !node) &&
+ !GTK_CLIST_FROZEN (clist))
+ {
+ gtk_clist_freeze (clist);
+ thaw = TRUE;
+ }
+
+ gtk_ctree_post_recursive (ctree, node,
+ GTK_CTREE_FUNC (tree_toggle_expansion), NULL);
+
+ if (thaw)
+ gtk_clist_thaw (clist);
+}
+
+void
gtk_ctree_select (GtkCTree *ctree,
GList *node)
{
@@ -3708,8 +4230,9 @@ gtk_ctree_real_select_recursive (GtkCTree *ctree,
clist = GTK_CLIST (ctree);
- if (clist->selection_mode == GTK_SELECTION_EXTENDED ||
- (state && clist->selection_mode != GTK_SELECTION_MULTIPLE) ||
+ if ((state &&
+ (clist->selection_mode != GTK_SELECTION_MULTIPLE ||
+ clist->selection_mode == GTK_SELECTION_EXTENDED)) ||
(!state && clist->selection_mode == GTK_SELECTION_BROWSE))
return;
@@ -4053,53 +4576,6 @@ gtk_ctree_set_background (GtkCTree *ctree,
}
void
-gtk_ctree_set_selection_mode (GtkCTree *ctree,
- GtkSelectionMode mode)
-{
- GtkCList *clist;
- GList *selection;
- GList *work;
- gboolean thaw = FALSE;
-
- g_return_if_fail (ctree != NULL);
- g_return_if_fail (GTK_IS_CTREE (ctree));
-
- clist = GTK_CLIST (ctree);
-
- if (mode == clist->selection_mode)
- return;
-
- clist->selection_mode = mode;
-
- if (mode == GTK_SELECTION_MULTIPLE)
- return;
-
- selection = clist->selection;
- if (selection && mode == GTK_SELECTION_BROWSE)
- selection = selection->next;
-
- if (!selection)
- return;
-
- if (!GTK_CLIST_FROZEN (clist))
- {
- gtk_clist_freeze (clist);
- thaw = TRUE;
- }
-
- while (selection)
- {
- work = selection->data;
- selection = selection->next;
- gtk_signal_emit (GTK_OBJECT (ctree),
- ctree_signals[TREE_UNSELECT_ROW], work);
- }
-
- if (thaw)
- gtk_clist_thaw (clist);
-}
-
-void
gtk_ctree_set_row_data (GtkCTree *ctree,
GList *node,
gpointer data)
@@ -4131,62 +4607,27 @@ gtk_ctree_get_row_data (GtkCTree *ctree,
}
void
-gtk_ctree_scroll_to (GtkCTree *ctree,
- GList *node,
- gint column,
- gfloat row_align,
- gfloat col_align)
+gtk_ctree_moveto (GtkCTree *ctree,
+ GList *node,
+ gint column,
+ gfloat row_align,
+ gfloat col_align)
{
- gint x;
- gint y;
- gint row = 0;
+ gint row = -1;
GtkCList *clist;
- GList *work;
- GtkAdjustment *adj;
g_return_if_fail (ctree != NULL);
g_return_if_fail (GTK_IS_CTREE (ctree));
clist = GTK_CLIST (ctree);
- if (node && !gtk_ctree_is_visible (ctree, node))
- return;
+ while (node && !gtk_ctree_is_visible (ctree, node))
+ node = GTK_CTREE_ROW (node)->parent;
- /* adjust vertical scrollbar */
if (node)
- {
- adj = GTK_RANGE (clist->vscrollbar)->adjustment;
- work = clist->row_list;
- while (work && work != node)
- {
- work = work->next;
- row++;
- }
-
- if (!work)
- return;
-
- y = ROW_TOP_YPIXEL (clist, row) - clist->voffset;
-
- y = y - row_align * (clist->clist_window_height - clist->row_height)
- + (2 * row_align - 1) * CELL_SPACING;
-
- if (y + adj->page_size > adj->upper)
- gtk_adjustment_set_value (adj, adj->upper - adj->page_size);
- else
- gtk_adjustment_set_value (adj, y);
- }
-
- /* adjust horizontal scrollbar */
- if (column >= 0)
- {
- adj = GTK_RANGE (clist->hscrollbar)->adjustment;
- x = COLUMN_LEFT (clist, column);
- x = x - col_align *
- (clist->clist_window_width - clist->column[column].area.width)
- + (2 * col_align - 1) * COLUMN_INSET;
- gtk_adjustment_set_value (adj, x);
- }
+ row = g_list_position (clist->row_list, node);
+
+ gtk_clist_moveto (clist, row, column, row_align, col_align);
}
@@ -4350,8 +4791,8 @@ tree_sort (GtkCTree *ctree,
list_start = GTK_CTREE_ROW (max)->sibling;
else
{
- gtk_ctree_unlink (ctree,max);
- gtk_ctree_link (ctree, max, node, list_start);
+ gtk_ctree_unlink (ctree, max, FALSE);
+ gtk_ctree_link (ctree, max, node, list_start, FALSE);
}
}
}
@@ -4361,6 +4802,7 @@ gtk_ctree_sort_recursive (GtkCTree *ctree,
GList *node)
{
GtkCList *clist;
+ GList *focus_node = NULL;
gboolean thaw = FALSE;
g_return_if_fail (ctree != NULL);
@@ -4374,8 +4816,28 @@ gtk_ctree_sort_recursive (GtkCTree *ctree,
thaw = TRUE;
}
+ if (clist->selection_mode == GTK_SELECTION_BROWSE)
+ {
+ if (clist->anchor != -1)
+ GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+
+ g_list_free (clist->undo_selection);
+ g_list_free (clist->undo_unselection);
+ clist->undo_selection = NULL;
+ clist->undo_unselection = NULL;
+ }
+
+ if (gtk_ctree_is_visible (ctree, node))
+ focus_node = g_list_nth (clist->row_list, clist->focus_row);
+
gtk_ctree_post_recursive (ctree, node, GTK_CTREE_FUNC (tree_sort), NULL);
+ if (focus_node)
+ {
+ clist->focus_row = g_list_position (clist->row_list, focus_node);
+ clist->undo_anchor = clist->focus_row;
+ }
+
if (thaw)
gtk_clist_thaw (clist);
}
@@ -4385,6 +4847,7 @@ gtk_ctree_sort (GtkCTree *ctree,
GList *node)
{
GtkCList *clist;
+ GList *focus_node = NULL;
gboolean thaw = FALSE;
g_return_if_fail (ctree != NULL);
@@ -4398,8 +4861,209 @@ gtk_ctree_sort (GtkCTree *ctree,
thaw = TRUE;
}
+ if (clist->selection_mode == GTK_SELECTION_BROWSE)
+ {
+ if (clist->anchor != -1)
+ GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+
+ g_list_free (clist->undo_selection);
+ g_list_free (clist->undo_unselection);
+ clist->undo_selection = NULL;
+ clist->undo_unselection = NULL;
+ }
+
+ if (gtk_ctree_is_visible (ctree, node))
+ focus_node = g_list_nth (clist->row_list, clist->focus_row);
+
tree_sort (ctree, node, NULL);
+ if (focus_node)
+ {
+ clist->focus_row = g_list_position (clist->row_list, focus_node);
+ clist->undo_anchor = clist->focus_row;
+ }
+
if (thaw)
gtk_clist_thaw (clist);
}
+
+/************************************************************************/
+
+static void
+fake_unselect_all (GtkCList *clist,
+ gint row)
+{
+ GList *list;
+ GList *focus_node = NULL;
+
+ if (row >= 0 && (focus_node = g_list_nth (clist->row_list, row)))
+ {
+ if (GTK_CTREE_ROW (focus_node)->row.state == GTK_STATE_NORMAL)
+ {
+ GTK_CTREE_ROW (focus_node)->row.state = GTK_STATE_SELECTED;
+
+ if (!GTK_CLIST_FROZEN (clist) &&
+ gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_NONE)
+ GTK_CLIST_CLASS_FW (clist)->draw_row (clist, NULL, row,
+ GTK_CLIST_ROW (focus_node));
+ }
+ }
+
+ clist->undo_selection = clist->selection;
+ clist->selection = NULL;
+ clist->selection_end = NULL;
+
+ for (list = clist->undo_selection; list; list = list->next)
+ {
+ if (list->data == focus_node)
+ continue;
+
+ GTK_CTREE_ROW ((GList *)(list->data))->row.state = GTK_STATE_NORMAL;
+ tree_draw_row (GTK_CTREE (clist), (GList *)(list->data));
+ }
+}
+
+static GList *
+selection_find (GtkCList *clist,
+ gint row_number,
+ GList *row_list_element)
+{
+ return g_list_find (clist->selection, row_list_element);
+}
+
+static void
+resync_selection (GtkCList *clist, GdkEvent *event)
+{
+ GtkCTree *ctree;
+ GList *list;
+ GList *node;
+ gint i;
+ gint e;
+ gint row;
+ gboolean thaw = FALSE;
+ gboolean unselect;
+
+ if (clist->anchor < 0)
+ return;
+
+ ctree = GTK_CTREE (clist);
+
+ if (!GTK_CLIST_FROZEN (clist))
+ {
+ GTK_CLIST_SET_FLAG (clist, CLIST_FROZEN);
+ thaw = TRUE;
+ }
+
+ i = MIN (clist->anchor, clist->drag_pos);
+ e = MAX (clist->anchor, clist->drag_pos);
+
+ if (clist->undo_selection)
+ {
+ list = clist->selection;
+ clist->selection = clist->undo_selection;
+ clist->selection_end = g_list_last (clist->selection);
+ clist->undo_selection = list;
+ list = clist->selection;
+
+ while (list)
+ {
+ node = list->data;
+ list = list->next;
+
+ unselect = TRUE;
+
+ if (gtk_ctree_is_visible (ctree, node))
+ {
+ row = g_list_position (clist->row_list, node);
+ if (row >= i && row <= e)
+ unselect = FALSE;
+ }
+ if (unselect)
+ {
+ GTK_CTREE_ROW (node)->row.state = GTK_STATE_SELECTED;
+ gtk_ctree_unselect (ctree, node);
+ clist->undo_selection = g_list_prepend (clist->undo_selection,
+ node);
+ }
+ }
+ }
+
+
+ for (node = g_list_nth (clist->row_list, i); i <= e; i++, node = node->next)
+ if (g_list_find (clist->selection, node))
+ {
+ if (GTK_CTREE_ROW (node)->row.state == GTK_STATE_NORMAL)
+ {
+ GTK_CTREE_ROW (node)->row.state = GTK_STATE_SELECTED;
+ gtk_ctree_unselect (ctree, node);
+ clist->undo_selection = g_list_prepend (clist->undo_selection,
+ node);
+ }
+ }
+ else if (GTK_CTREE_ROW (node)->row.state == GTK_STATE_SELECTED)
+ {
+ GTK_CTREE_ROW (node)->row.state = GTK_STATE_NORMAL;
+ clist->undo_unselection = g_list_prepend (clist->undo_unselection,
+ node);
+ }
+
+ for (list = clist->undo_unselection; list; list = list->next)
+ gtk_ctree_select (ctree, list->data);
+
+ clist->anchor = -1;
+ clist->drag_pos = -1;
+
+ if (thaw)
+ GTK_CLIST_UNSET_FLAG (clist, CLIST_FROZEN);
+}
+
+static void
+real_undo_selection (GtkCList *clist)
+{
+ GtkCTree *ctree;
+ GList *work;
+
+
+ g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
+
+ if (clist->selection_mode != GTK_SELECTION_EXTENDED)
+ return;
+
+ if (!(clist->undo_selection || clist->undo_unselection))
+ {
+ gtk_clist_unselect_all (clist);
+ return;
+ }
+
+ ctree = GTK_CTREE (clist);
+
+ for (work = clist->undo_selection; work; work = work->next)
+ gtk_ctree_select (ctree, (GList *) work->data);
+
+ for (work = clist->undo_unselection; work; work = work->next)
+ gtk_ctree_unselect (ctree, (GList *) work->data);
+
+ if (GTK_WIDGET_HAS_FOCUS (clist) && clist->focus_row != clist->undo_anchor)
+ {
+ gtk_widget_draw_focus (GTK_WIDGET (clist));
+ clist->focus_row = clist->undo_anchor;
+ gtk_widget_draw_focus (GTK_WIDGET (clist));
+ }
+ else
+ clist->focus_row = clist->undo_anchor;
+
+ clist->undo_anchor = -1;
+
+ g_list_free (clist->undo_selection);
+ g_list_free (clist->undo_unselection);
+ clist->undo_selection = NULL;
+ clist->undo_unselection = NULL;
+
+ if (ROW_TOP_YPIXEL (clist, clist->focus_row) + clist->row_height >
+ clist->clist_window_height)
+ gtk_clist_moveto (clist, clist->focus_row, -1, 1, 0);
+ else if (ROW_TOP_YPIXEL (clist, clist->focus_row) < 0)
+ gtk_clist_moveto (clist, clist->focus_row, -1, 0, 0);
+
+}
diff --git a/gtk/gtkctree.h b/gtk/gtkctree.h
index 7f2fdc33c..d13f6ca1c 100644
--- a/gtk/gtkctree.h
+++ b/gtk/gtkctree.h
@@ -37,7 +37,7 @@ extern "C"
(GTK_CHECK_CLASS_CAST ((klass), gtk_ctree_get_type (), GtkCTreeClass))
#define GTK_IS_CTREE(obj) \
(GTK_CHECK_TYPE ((obj), gtk_ctree_get_type ()))
-#define GTK_CTREE_ROW(glist) ((GtkCTreeRow *)((glist)->data))
+#define GTK_CTREE_ROW(_glist_) ((GtkCTreeRow *)((_glist_)->data))
#define GTK_CTREE_TREE(_ctree_, _glist_) \
((GtkCellTree *) &(((GtkCTreeRow *)((_glist_)->data))->cell[(_ctree_)->tree_col]))
@@ -58,6 +58,16 @@ typedef enum
GTK_CTREE_LINES_NONE
} GtkCTreeLineStyle;
+typedef enum
+{
+ GTK_CTREE_EXPANSION_EXPAND,
+ GTK_CTREE_EXPANSION_EXPAND_RECURSIVE,
+ GTK_CTREE_EXPANSION_COLLAPSE,
+ GTK_CTREE_EXPANSION_COLLAPSE_RECURSIVE,
+ GTK_CTREE_EXPANSION_TOGGLE,
+ GTK_CTREE_EXPANSION_TOGGLE_RECURSIVE
+} GtkCTreeExpansion;
+
typedef struct _GtkCTree GtkCTree;
typedef struct _GtkCTreeClass GtkCTreeClass;
typedef struct _GtkCTreeRow GtkCTreeRow;
@@ -82,7 +92,6 @@ struct _GtkCTree
gint tree_indent;
gint tree_column;
- GList *selection_last;
gint drag_row;
GList *drag_source;
GList *drag_target;
@@ -115,6 +124,8 @@ struct _GtkCTreeClass
GList *node,
GList *new_parent,
GList *new_sibling);
+ void (*change_focus_row_expansion) (GtkCTree *ctree,
+ GtkCTreeExpansion action);
};
struct _GtkCTreeRow
@@ -164,7 +175,6 @@ GList * gtk_ctree_insert (GtkCTree *ctree,
gboolean expanded);
void gtk_ctree_remove (GtkCTree *ctree,
GList *node);
-void gtk_ctree_clear (GtkCTree *ctree);
/***********************************************************
* Generic recursive functions, querying / finding tree *
@@ -214,6 +224,10 @@ void gtk_ctree_collapse (GtkCTree *ctree,
GList *node);
void gtk_ctree_collapse_recursive (GtkCTree *ctree,
GList *node);
+void gtk_ctree_toggle_expansion (GtkCTree *ctree,
+ GList *node);
+void gtk_ctree_toggle_expansion_recursive (GtkCTree *ctree,
+ GList *node);
void gtk_ctree_select (GtkCTree *ctree,
GList *node);
void gtk_ctree_select_recursive (GtkCTree *ctree,
@@ -296,8 +310,6 @@ void gtk_ctree_set_foreground (GtkCTree *ctree,
void gtk_ctree_set_background (GtkCTree *ctree,
GList *node,
GdkColor *color);
-void gtk_ctree_set_selection_mode (GtkCTree *ctree,
- GtkSelectionMode mode);
void gtk_ctree_set_row_data (GtkCTree *ctree,
GList *node,
gpointer data);
@@ -307,7 +319,7 @@ void gtk_ctree_set_row_data_full (GtkCTree *ctree,
GtkDestroyNotify destroy);
gpointer gtk_ctree_get_row_data (GtkCTree *ctree,
GList *node);
-void gtk_ctree_scroll_to (GtkCTree *ctree,
+void gtk_ctree_moveto (GtkCTree *ctree,
GList *node,
gint column,
gfloat row_align,
diff --git a/gtk/testgtk.c b/gtk/testgtk.c
index 2042ae874..5f99a8336 100644
--- a/gtk/testgtk.c
+++ b/gtk/testgtk.c
@@ -3034,12 +3034,14 @@ create_list (void)
gtk_widget_destroy (window);
}
+
/*
* GtkCList
*/
-#define TESTGTK_CLIST_COLUMNS 7
+
+#define TESTGTK_CLIST_COLUMNS 20
static gint clist_rows = 0;
-static gint clist_selected_row = 0;
+static GtkWidget *clist_omenu;
static void
add1000_clist (GtkWidget *widget, gpointer data)
@@ -3101,7 +3103,6 @@ add10000_clist (GtkWidget *widget, gpointer data)
gtk_clist_append (GTK_CLIST (data), texts);
}
gtk_clist_thaw (GTK_CLIST (data));
-
}
void
@@ -3114,7 +3115,7 @@ clear_clist (GtkWidget *widget, gpointer data)
void
remove_row_clist (GtkWidget *widget, gpointer data)
{
- gtk_clist_remove (GTK_CLIST (data), clist_selected_row);
+ gtk_clist_remove (GTK_CLIST (data), GTK_CLIST (data)->focus_row);
clist_rows--;
}
@@ -3134,7 +3135,8 @@ void
select_clist (GtkWidget *widget,
gint row,
gint column,
- GdkEventButton * bevent)
+ GdkEventButton * bevent,
+ GtkWidget *button)
{
gint i;
guint8 spacing;
@@ -3187,15 +3189,14 @@ select_clist (GtkWidget *widget,
}
g_print ("\n\n\n");
-
- clist_selected_row = row;
}
void
unselect_clist (GtkWidget *widget,
gint row,
gint column,
- GdkEventButton * bevent)
+ GdkEventButton * bevent,
+ GtkWidget *button)
{
gint i;
guint8 spacing;
@@ -3248,8 +3249,6 @@ unselect_clist (GtkWidget *widget,
}
g_print ("\n\n\n");
-
- clist_selected_row = row;
}
static void
@@ -3257,16 +3256,14 @@ insert_row_clist (GtkWidget *widget, gpointer data)
{
static char *text[] =
{
- "This",
- "is",
- "a",
- "inserted",
- "row",
- "la la la la la",
- "la la la la"
+ "This", "is", "a", "inserted", "row.",
+ "This", "is", "a", "inserted", "row.",
+ "This", "is", "a", "inserted", "row.",
+ "This", "is", "a", "inserted", "row."
};
- gtk_clist_insert (GTK_CLIST (data), clist_selected_row, text);
+ gtk_clist_insert (GTK_CLIST (data), GTK_CLIST (data)->focus_row, text);
+
clist_rows++;
}
@@ -3297,6 +3294,36 @@ clist_warning_test (GtkWidget *button,
}
static void
+undo_selection (GtkWidget *button, GtkCList *clist)
+{
+ gtk_clist_undo_selection (clist);
+}
+
+#define RADIOMENUTOGGLED(_rmi_, __i) { \
+ GSList * __g; \
+ __i = 0; \
+ __g = gtk_radio_menu_item_group(_rmi_); \
+ while( __g && !((GtkCheckMenuItem *)(__g->data))->active) { \
+ __g = __g->next; \
+ __i++; \
+ }\
+}
+
+static void
+clist_toggle_sel_mode (GtkWidget *widget, GtkCList *clist)
+{
+ gint i;
+
+ if (!GTK_WIDGET_MAPPED (widget))
+ return;
+
+ RADIOMENUTOGGLED ((GtkRadioMenuItem *)
+ (((GtkOptionMenu *)clist_omenu)->menu_item), i);
+
+ gtk_clist_set_selection_mode (clist, (GtkSelectionMode) (3-i));
+}
+
+static void
create_clist (void)
{
gint i;
@@ -3310,7 +3337,20 @@ create_clist (void)
"Title 3",
"Title 4",
"Title 5",
- "Title 6"
+ "Title 6",
+ "Title 7",
+ "Title 8",
+ "Title 9",
+ "Title 10",
+ "Title 11",
+ "Title 12",
+ "Title 13",
+ "Title 14",
+ "Title 15",
+ "Title 16",
+ "Title 17",
+ "Title 18",
+ "Title 19"
};
char text[TESTGTK_CLIST_COLUMNS][50];
@@ -3322,9 +3362,15 @@ create_clist (void)
GtkWidget *button;
GtkWidget *separator;
+ GtkWidget *undo_button;
+ GtkWidget *label;
+ GtkWidget *menu;
+ GtkWidget *menu_item;
+ GSList *group;
if (!window)
{
+ clist_rows = 0;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_signal_connect (GTK_OBJECT (window), "destroy",
@@ -3334,16 +3380,12 @@ create_clist (void)
gtk_window_set_title (GTK_WINDOW (window), "clist");
gtk_container_border_width (GTK_CONTAINER (window), 0);
-
box1 = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), box1);
- gtk_widget_show (box1);
-
box2 = gtk_hbox_new (FALSE, 10);
gtk_container_border_width (GTK_CONTAINER (box2), 10);
gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
- gtk_widget_show (box2);
/* create GtkCList here so we have a pointer to throw at the
* button callbacks -- more is done with it later */
@@ -3359,9 +3401,6 @@ create_clist (void)
(GtkSignalFunc) add1000_clist,
(gpointer) clist);
- gtk_widget_show (button);
-
-
button = gtk_button_new_with_label ("Add 10,000 Rows");
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
@@ -3370,8 +3409,6 @@ create_clist (void)
(GtkSignalFunc) add10000_clist,
(gpointer) clist);
- gtk_widget_show (button);
-
button = gtk_button_new_with_label ("Clear List");
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
@@ -3380,8 +3417,6 @@ create_clist (void)
(GtkSignalFunc) clear_clist,
(gpointer) clist);
- gtk_widget_show (button);
-
button = gtk_button_new_with_label ("Remove Row");
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
@@ -3390,13 +3425,10 @@ create_clist (void)
(GtkSignalFunc) remove_row_clist,
(gpointer) clist);
- gtk_widget_show (button);
-
/* second layer of buttons */
box2 = gtk_hbox_new (FALSE, 10);
gtk_container_border_width (GTK_CONTAINER (box2), 10);
gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
- gtk_widget_show (box2);
button = gtk_button_new_with_label ("Insert Row");
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
@@ -3406,8 +3438,6 @@ create_clist (void)
(GtkSignalFunc) insert_row_clist,
(gpointer) clist);
- gtk_widget_show (button);
-
button = gtk_button_new_with_label ("Show Title Buttons");
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
@@ -3416,8 +3446,6 @@ create_clist (void)
(GtkSignalFunc) show_titles_clist,
(gpointer) clist);
- gtk_widget_show (button);
-
button = gtk_button_new_with_label ("Hide Title Buttons");
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
@@ -3426,8 +3454,6 @@ create_clist (void)
(GtkSignalFunc) hide_titles_clist,
(gpointer) clist);
- gtk_widget_show (button);
-
button = gtk_button_new_with_label ("Warning Test");
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
@@ -3436,41 +3462,96 @@ create_clist (void)
(GtkSignalFunc) clist_warning_test,
(gpointer) clist);
- gtk_widget_show (button);
+ box2 = gtk_hbox_new (FALSE, 10);
+ gtk_container_border_width (GTK_CONTAINER (box2), 10);
+ gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
+
+ undo_button = gtk_button_new_with_label ("Undo last selection");
+ gtk_box_pack_start (GTK_BOX (box2), undo_button, TRUE, TRUE, 0);
+ gtk_signal_connect (GTK_OBJECT (undo_button),
+ "clicked",
+ (GtkSignalFunc) undo_selection,
+ (gpointer) clist);
+
+ label = gtk_label_new ("Selection Mode :");
+ gtk_box_pack_start (GTK_BOX (box2), label, FALSE, TRUE, 0);
+
+ clist_omenu = gtk_option_menu_new ();
+
+ menu = gtk_menu_new ();
+ group = NULL;
+
+ menu_item = gtk_radio_menu_item_new_with_label (group, "Single");
+ gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+ GTK_SIGNAL_FUNC (clist_toggle_sel_mode), clist);
+ group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+ gtk_menu_append (GTK_MENU (menu), menu_item);
+ gtk_widget_show (menu_item);
+
+ menu_item = gtk_radio_menu_item_new_with_label (group, "Browse");
+ gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+ GTK_SIGNAL_FUNC (clist_toggle_sel_mode), clist);
+ group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+ gtk_menu_append (GTK_MENU (menu), menu_item);
+ gtk_widget_show (menu_item);
+
+ menu_item = gtk_radio_menu_item_new_with_label (group, "Multiple");
+ gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+ GTK_SIGNAL_FUNC (clist_toggle_sel_mode), clist);
+ group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+ gtk_menu_append (GTK_MENU (menu), menu_item);
+ gtk_widget_show (menu_item);
+
+ menu_item = gtk_radio_menu_item_new_with_label (group, "Extended");
+ gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+ GTK_SIGNAL_FUNC (clist_toggle_sel_mode), clist);
+ group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+ gtk_menu_append (GTK_MENU (menu), menu_item);
+ gtk_check_menu_item_set_state (GTK_CHECK_MENU_ITEM (menu_item), TRUE);
+ gtk_widget_show (menu_item);
+
+ gtk_option_menu_set_menu (GTK_OPTION_MENU (clist_omenu), menu);
+ gtk_box_pack_start (GTK_BOX (box2), clist_omenu, FALSE, TRUE, 0);
+
+ gtk_option_menu_set_history (GTK_OPTION_MENU (clist_omenu), 3);
/* vbox for the list itself */
box2 = gtk_vbox_new (FALSE, 10);
gtk_container_border_width (GTK_CONTAINER (box2), 10);
gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
- gtk_widget_show (box2);
/*
* the rest of the clist configuration
*/
- gtk_clist_set_row_height (GTK_CLIST (clist), 20);
-
+
+ /*
gtk_signal_connect (GTK_OBJECT (clist),
"select_row",
(GtkSignalFunc) select_clist,
- NULL);
+ undo_button);
gtk_signal_connect (GTK_OBJECT (clist),
"unselect_row",
(GtkSignalFunc) unselect_clist,
- NULL);
+ undo_button);
+ */
+
+ gtk_clist_set_row_height (GTK_CLIST (clist), 18);
+ gtk_widget_set_usize (clist, -1, 300);
gtk_clist_set_column_width (GTK_CLIST (clist), 0, 100);
for (i = 1; i < TESTGTK_CLIST_COLUMNS; i++)
gtk_clist_set_column_width (GTK_CLIST (clist), i, 80);
- gtk_clist_set_selection_mode (GTK_CLIST (clist), GTK_SELECTION_BROWSE);
- gtk_clist_set_policy (GTK_CLIST (clist),
- GTK_POLICY_AUTOMATIC,
+ gtk_clist_set_selection_mode (GTK_CLIST (clist), GTK_SELECTION_EXTENDED);
+ gtk_clist_set_policy (GTK_CLIST (clist), GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
- gtk_clist_set_column_justification (GTK_CLIST (clist), 1, GTK_JUSTIFY_RIGHT);
- gtk_clist_set_column_justification (GTK_CLIST (clist), 2, GTK_JUSTIFY_CENTER);
+ gtk_clist_set_column_justification (GTK_CLIST (clist), 1,
+ GTK_JUSTIFY_RIGHT);
+ gtk_clist_set_column_justification (GTK_CLIST (clist), 2,
+ GTK_JUSTIFY_CENTER);
for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
{
@@ -3481,7 +3562,7 @@ create_clist (void)
sprintf (text[1], "Right");
sprintf (text[2], "Center");
- for (i = 0; i < 100; i++)
+ for (i = 0; i < 10; i++)
{
sprintf (text[0], "Row %d", clist_rows++);
gtk_clist_append (GTK_CLIST (clist), texts);
@@ -3489,17 +3570,13 @@ create_clist (void)
gtk_container_border_width (GTK_CONTAINER (clist), 5);
gtk_box_pack_start (GTK_BOX (box2), clist, TRUE, TRUE, 0);
- gtk_widget_show (clist);
-
separator = gtk_hseparator_new ();
gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
- gtk_widget_show (separator);
box2 = gtk_vbox_new (FALSE, 10);
gtk_container_border_width (GTK_CONTAINER (box2), 10);
gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
- gtk_widget_show (box2);
button = gtk_button_new_with_label ("close");
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
@@ -3509,21 +3586,17 @@ create_clist (void)
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_widget_grab_default (button);
-
- gtk_widget_show (button);
}
if (!GTK_WIDGET_VISIBLE (window))
- gtk_widget_show (window);
+ gtk_widget_show_all (window);
else
{
clist_rows = 0;
gtk_widget_destroy (window);
}
-
}
-
/*
* GtkCTree
*/
@@ -3621,26 +3694,6 @@ static GtkWidget *spin2;
static GtkWidget *spin3;
static GdkColor *col_bg;
-#define RADIOMENUTOGGLED(_rmi_, __i) { \
- GSList * __g; \
- __i = 0; \
- __g = gtk_radio_menu_item_group(_rmi_); \
- while( __g && !((GtkCheckMenuItem *)(__g->data))->active) { \
- __g = __g->next; \
- __i++; \
- }\
-}
-
-#define RADIOBUTTONTOGGLED(_rb_, __i) { \
- GSList * __g; \
- __i = 0; \
- __g = gtk_radio_button_group(_rb_); \
- while( __g && !((GtkToggleButton *)(__g->data))->active) { \
- __g = __g->next; \
- __i++; \
- }\
-}
-
void after_press (GtkCTree *ctree, gpointer data)
{
char buf[80];
@@ -3708,7 +3761,7 @@ gint button_press (GtkCTree *ctree, GdkEventButton *event, gpointer data)
else
gtk_ctree_expand_recursive (ctree, work);
after_press (ctree, NULL);
- gtk_signal_emit_stop_by_name (GTK_OBJECT (ctree),
+ gtk_signal_emit_stop_by_name (GTK_OBJECT (ctree),
"button_press_event");
}
break;
@@ -3907,7 +3960,7 @@ void toggle_sel_mode (GtkWidget *widget, GtkCTree *ctree)
RADIOMENUTOGGLED ((GtkRadioMenuItem *)
(((GtkOptionMenu *)omenu)->menu_item), i);
- gtk_ctree_set_selection_mode (ctree, (GtkSelectionMode) (3-i));
+ gtk_clist_set_selection_mode (GTK_CLIST (ctree), (GtkSelectionMode) (3-i));
after_press (ctree, NULL);
}
@@ -3996,14 +4049,14 @@ void rebuild_tree (GtkWidget *widget, GtkCTree *ctree)
n = ((pow (b, d) - 1) / (b - 1)) * (p + 1);
- if (n > 200000)
+ if (n > 100000)
{
g_print ("%d total items? Try less\n",n);
return;
}
gtk_clist_freeze (GTK_CLIST (ctree));
- gtk_ctree_clear (ctree);
+ gtk_clist_clear (GTK_CLIST (ctree));
books = 1;
pages = 0;
@@ -4117,9 +4170,20 @@ void create_ctree (void)
GTK_SIGNAL_FUNC (after_press), NULL);
gtk_signal_connect_after (GTK_OBJECT (ctree), "tree_move",
GTK_SIGNAL_FUNC (after_move), NULL);
+ gtk_signal_connect_after (GTK_OBJECT (ctree), "end_selection",
+ GTK_SIGNAL_FUNC (after_press), NULL);
+ gtk_signal_connect_after (GTK_OBJECT (ctree), "toggle_focus_row",
+ GTK_SIGNAL_FUNC (after_press), NULL);
+ gtk_signal_connect_after (GTK_OBJECT (ctree), "select_all",
+ GTK_SIGNAL_FUNC (after_press), NULL);
+ gtk_signal_connect_after (GTK_OBJECT (ctree), "unselect_all",
+ GTK_SIGNAL_FUNC (after_press), NULL);
+ gtk_signal_connect_after (GTK_OBJECT (ctree), "scroll_vertical",
+ GTK_SIGNAL_FUNC (after_press), NULL);
+
gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (ctree), TRUE, TRUE, 0);
gtk_clist_column_titles_passive (GTK_CLIST (ctree));
- gtk_clist_set_selection_mode (GTK_CLIST (ctree), GTK_SELECTION_MULTIPLE);
+ gtk_clist_set_selection_mode (GTK_CLIST (ctree), GTK_SELECTION_EXTENDED);
gtk_clist_set_policy (GTK_CLIST (ctree), GTK_POLICY_ALWAYS,
GTK_POLICY_AUTOMATIC);
gtk_clist_set_column_width (GTK_CLIST (ctree), 0, 200);
@@ -4299,7 +4363,6 @@ void create_ctree (void)
GTK_SIGNAL_FUNC (toggle_sel_mode), ctree);
group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
gtk_menu_append (GTK_MENU (menu), menu_item);
- gtk_check_menu_item_set_state (GTK_CHECK_MENU_ITEM (menu_item), TRUE);
gtk_widget_show (menu_item);
menu_item = gtk_radio_menu_item_new_with_label (group, "Extended");
@@ -4307,12 +4370,13 @@ void create_ctree (void)
GTK_SIGNAL_FUNC (toggle_sel_mode), ctree);
group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
gtk_menu_append (GTK_MENU (menu), menu_item);
+ gtk_check_menu_item_set_state (GTK_CHECK_MENU_ITEM (menu_item), TRUE);
gtk_widget_show (menu_item);
gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
gtk_box_pack_start (GTK_BOX (hbox), omenu, FALSE, TRUE, 0);
- gtk_option_menu_set_history (GTK_OPTION_MENU (omenu), 2);
+ gtk_option_menu_set_history (GTK_OPTION_MENU (omenu), 3);
gtk_widget_realize (window);
@@ -4403,7 +4467,6 @@ void create_ctree (void)
gtk_widget_destroy (window);
}
-
/*
* GtkColorSelect
*/
diff --git a/tests/testgtk.c b/tests/testgtk.c
index 2042ae874..5f99a8336 100644
--- a/tests/testgtk.c
+++ b/tests/testgtk.c
@@ -3034,12 +3034,14 @@ create_list (void)
gtk_widget_destroy (window);
}
+
/*
* GtkCList
*/
-#define TESTGTK_CLIST_COLUMNS 7
+
+#define TESTGTK_CLIST_COLUMNS 20
static gint clist_rows = 0;
-static gint clist_selected_row = 0;
+static GtkWidget *clist_omenu;
static void
add1000_clist (GtkWidget *widget, gpointer data)
@@ -3101,7 +3103,6 @@ add10000_clist (GtkWidget *widget, gpointer data)
gtk_clist_append (GTK_CLIST (data), texts);
}
gtk_clist_thaw (GTK_CLIST (data));
-
}
void
@@ -3114,7 +3115,7 @@ clear_clist (GtkWidget *widget, gpointer data)
void
remove_row_clist (GtkWidget *widget, gpointer data)
{
- gtk_clist_remove (GTK_CLIST (data), clist_selected_row);
+ gtk_clist_remove (GTK_CLIST (data), GTK_CLIST (data)->focus_row);
clist_rows--;
}
@@ -3134,7 +3135,8 @@ void
select_clist (GtkWidget *widget,
gint row,
gint column,
- GdkEventButton * bevent)
+ GdkEventButton * bevent,
+ GtkWidget *button)
{
gint i;
guint8 spacing;
@@ -3187,15 +3189,14 @@ select_clist (GtkWidget *widget,
}
g_print ("\n\n\n");
-
- clist_selected_row = row;
}
void
unselect_clist (GtkWidget *widget,
gint row,
gint column,
- GdkEventButton * bevent)
+ GdkEventButton * bevent,
+ GtkWidget *button)
{
gint i;
guint8 spacing;
@@ -3248,8 +3249,6 @@ unselect_clist (GtkWidget *widget,
}
g_print ("\n\n\n");
-
- clist_selected_row = row;
}
static void
@@ -3257,16 +3256,14 @@ insert_row_clist (GtkWidget *widget, gpointer data)
{
static char *text[] =
{
- "This",
- "is",
- "a",
- "inserted",
- "row",
- "la la la la la",
- "la la la la"
+ "This", "is", "a", "inserted", "row.",
+ "This", "is", "a", "inserted", "row.",
+ "This", "is", "a", "inserted", "row.",
+ "This", "is", "a", "inserted", "row."
};
- gtk_clist_insert (GTK_CLIST (data), clist_selected_row, text);
+ gtk_clist_insert (GTK_CLIST (data), GTK_CLIST (data)->focus_row, text);
+
clist_rows++;
}
@@ -3297,6 +3294,36 @@ clist_warning_test (GtkWidget *button,
}
static void
+undo_selection (GtkWidget *button, GtkCList *clist)
+{
+ gtk_clist_undo_selection (clist);
+}
+
+#define RADIOMENUTOGGLED(_rmi_, __i) { \
+ GSList * __g; \
+ __i = 0; \
+ __g = gtk_radio_menu_item_group(_rmi_); \
+ while( __g && !((GtkCheckMenuItem *)(__g->data))->active) { \
+ __g = __g->next; \
+ __i++; \
+ }\
+}
+
+static void
+clist_toggle_sel_mode (GtkWidget *widget, GtkCList *clist)
+{
+ gint i;
+
+ if (!GTK_WIDGET_MAPPED (widget))
+ return;
+
+ RADIOMENUTOGGLED ((GtkRadioMenuItem *)
+ (((GtkOptionMenu *)clist_omenu)->menu_item), i);
+
+ gtk_clist_set_selection_mode (clist, (GtkSelectionMode) (3-i));
+}
+
+static void
create_clist (void)
{
gint i;
@@ -3310,7 +3337,20 @@ create_clist (void)
"Title 3",
"Title 4",
"Title 5",
- "Title 6"
+ "Title 6",
+ "Title 7",
+ "Title 8",
+ "Title 9",
+ "Title 10",
+ "Title 11",
+ "Title 12",
+ "Title 13",
+ "Title 14",
+ "Title 15",
+ "Title 16",
+ "Title 17",
+ "Title 18",
+ "Title 19"
};
char text[TESTGTK_CLIST_COLUMNS][50];
@@ -3322,9 +3362,15 @@ create_clist (void)
GtkWidget *button;
GtkWidget *separator;
+ GtkWidget *undo_button;
+ GtkWidget *label;
+ GtkWidget *menu;
+ GtkWidget *menu_item;
+ GSList *group;
if (!window)
{
+ clist_rows = 0;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_signal_connect (GTK_OBJECT (window), "destroy",
@@ -3334,16 +3380,12 @@ create_clist (void)
gtk_window_set_title (GTK_WINDOW (window), "clist");
gtk_container_border_width (GTK_CONTAINER (window), 0);
-
box1 = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), box1);
- gtk_widget_show (box1);
-
box2 = gtk_hbox_new (FALSE, 10);
gtk_container_border_width (GTK_CONTAINER (box2), 10);
gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
- gtk_widget_show (box2);
/* create GtkCList here so we have a pointer to throw at the
* button callbacks -- more is done with it later */
@@ -3359,9 +3401,6 @@ create_clist (void)
(GtkSignalFunc) add1000_clist,
(gpointer) clist);
- gtk_widget_show (button);
-
-
button = gtk_button_new_with_label ("Add 10,000 Rows");
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
@@ -3370,8 +3409,6 @@ create_clist (void)
(GtkSignalFunc) add10000_clist,
(gpointer) clist);
- gtk_widget_show (button);
-
button = gtk_button_new_with_label ("Clear List");
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
@@ -3380,8 +3417,6 @@ create_clist (void)
(GtkSignalFunc) clear_clist,
(gpointer) clist);
- gtk_widget_show (button);
-
button = gtk_button_new_with_label ("Remove Row");
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
@@ -3390,13 +3425,10 @@ create_clist (void)
(GtkSignalFunc) remove_row_clist,
(gpointer) clist);
- gtk_widget_show (button);
-
/* second layer of buttons */
box2 = gtk_hbox_new (FALSE, 10);
gtk_container_border_width (GTK_CONTAINER (box2), 10);
gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
- gtk_widget_show (box2);
button = gtk_button_new_with_label ("Insert Row");
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
@@ -3406,8 +3438,6 @@ create_clist (void)
(GtkSignalFunc) insert_row_clist,
(gpointer) clist);
- gtk_widget_show (button);
-
button = gtk_button_new_with_label ("Show Title Buttons");
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
@@ -3416,8 +3446,6 @@ create_clist (void)
(GtkSignalFunc) show_titles_clist,
(gpointer) clist);
- gtk_widget_show (button);
-
button = gtk_button_new_with_label ("Hide Title Buttons");
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
@@ -3426,8 +3454,6 @@ create_clist (void)
(GtkSignalFunc) hide_titles_clist,
(gpointer) clist);
- gtk_widget_show (button);
-
button = gtk_button_new_with_label ("Warning Test");
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
@@ -3436,41 +3462,96 @@ create_clist (void)
(GtkSignalFunc) clist_warning_test,
(gpointer) clist);
- gtk_widget_show (button);
+ box2 = gtk_hbox_new (FALSE, 10);
+ gtk_container_border_width (GTK_CONTAINER (box2), 10);
+ gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
+
+ undo_button = gtk_button_new_with_label ("Undo last selection");
+ gtk_box_pack_start (GTK_BOX (box2), undo_button, TRUE, TRUE, 0);
+ gtk_signal_connect (GTK_OBJECT (undo_button),
+ "clicked",
+ (GtkSignalFunc) undo_selection,
+ (gpointer) clist);
+
+ label = gtk_label_new ("Selection Mode :");
+ gtk_box_pack_start (GTK_BOX (box2), label, FALSE, TRUE, 0);
+
+ clist_omenu = gtk_option_menu_new ();
+
+ menu = gtk_menu_new ();
+ group = NULL;
+
+ menu_item = gtk_radio_menu_item_new_with_label (group, "Single");
+ gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+ GTK_SIGNAL_FUNC (clist_toggle_sel_mode), clist);
+ group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+ gtk_menu_append (GTK_MENU (menu), menu_item);
+ gtk_widget_show (menu_item);
+
+ menu_item = gtk_radio_menu_item_new_with_label (group, "Browse");
+ gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+ GTK_SIGNAL_FUNC (clist_toggle_sel_mode), clist);
+ group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+ gtk_menu_append (GTK_MENU (menu), menu_item);
+ gtk_widget_show (menu_item);
+
+ menu_item = gtk_radio_menu_item_new_with_label (group, "Multiple");
+ gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+ GTK_SIGNAL_FUNC (clist_toggle_sel_mode), clist);
+ group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+ gtk_menu_append (GTK_MENU (menu), menu_item);
+ gtk_widget_show (menu_item);
+
+ menu_item = gtk_radio_menu_item_new_with_label (group, "Extended");
+ gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+ GTK_SIGNAL_FUNC (clist_toggle_sel_mode), clist);
+ group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+ gtk_menu_append (GTK_MENU (menu), menu_item);
+ gtk_check_menu_item_set_state (GTK_CHECK_MENU_ITEM (menu_item), TRUE);
+ gtk_widget_show (menu_item);
+
+ gtk_option_menu_set_menu (GTK_OPTION_MENU (clist_omenu), menu);
+ gtk_box_pack_start (GTK_BOX (box2), clist_omenu, FALSE, TRUE, 0);
+
+ gtk_option_menu_set_history (GTK_OPTION_MENU (clist_omenu), 3);
/* vbox for the list itself */
box2 = gtk_vbox_new (FALSE, 10);
gtk_container_border_width (GTK_CONTAINER (box2), 10);
gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
- gtk_widget_show (box2);
/*
* the rest of the clist configuration
*/
- gtk_clist_set_row_height (GTK_CLIST (clist), 20);
-
+
+ /*
gtk_signal_connect (GTK_OBJECT (clist),
"select_row",
(GtkSignalFunc) select_clist,
- NULL);
+ undo_button);
gtk_signal_connect (GTK_OBJECT (clist),
"unselect_row",
(GtkSignalFunc) unselect_clist,
- NULL);
+ undo_button);
+ */
+
+ gtk_clist_set_row_height (GTK_CLIST (clist), 18);
+ gtk_widget_set_usize (clist, -1, 300);
gtk_clist_set_column_width (GTK_CLIST (clist), 0, 100);
for (i = 1; i < TESTGTK_CLIST_COLUMNS; i++)
gtk_clist_set_column_width (GTK_CLIST (clist), i, 80);
- gtk_clist_set_selection_mode (GTK_CLIST (clist), GTK_SELECTION_BROWSE);
- gtk_clist_set_policy (GTK_CLIST (clist),
- GTK_POLICY_AUTOMATIC,
+ gtk_clist_set_selection_mode (GTK_CLIST (clist), GTK_SELECTION_EXTENDED);
+ gtk_clist_set_policy (GTK_CLIST (clist), GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
- gtk_clist_set_column_justification (GTK_CLIST (clist), 1, GTK_JUSTIFY_RIGHT);
- gtk_clist_set_column_justification (GTK_CLIST (clist), 2, GTK_JUSTIFY_CENTER);
+ gtk_clist_set_column_justification (GTK_CLIST (clist), 1,
+ GTK_JUSTIFY_RIGHT);
+ gtk_clist_set_column_justification (GTK_CLIST (clist), 2,
+ GTK_JUSTIFY_CENTER);
for (i = 0; i < TESTGTK_CLIST_COLUMNS; i++)
{
@@ -3481,7 +3562,7 @@ create_clist (void)
sprintf (text[1], "Right");
sprintf (text[2], "Center");
- for (i = 0; i < 100; i++)
+ for (i = 0; i < 10; i++)
{
sprintf (text[0], "Row %d", clist_rows++);
gtk_clist_append (GTK_CLIST (clist), texts);
@@ -3489,17 +3570,13 @@ create_clist (void)
gtk_container_border_width (GTK_CONTAINER (clist), 5);
gtk_box_pack_start (GTK_BOX (box2), clist, TRUE, TRUE, 0);
- gtk_widget_show (clist);
-
separator = gtk_hseparator_new ();
gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
- gtk_widget_show (separator);
box2 = gtk_vbox_new (FALSE, 10);
gtk_container_border_width (GTK_CONTAINER (box2), 10);
gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
- gtk_widget_show (box2);
button = gtk_button_new_with_label ("close");
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
@@ -3509,21 +3586,17 @@ create_clist (void)
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_widget_grab_default (button);
-
- gtk_widget_show (button);
}
if (!GTK_WIDGET_VISIBLE (window))
- gtk_widget_show (window);
+ gtk_widget_show_all (window);
else
{
clist_rows = 0;
gtk_widget_destroy (window);
}
-
}
-
/*
* GtkCTree
*/
@@ -3621,26 +3694,6 @@ static GtkWidget *spin2;
static GtkWidget *spin3;
static GdkColor *col_bg;
-#define RADIOMENUTOGGLED(_rmi_, __i) { \
- GSList * __g; \
- __i = 0; \
- __g = gtk_radio_menu_item_group(_rmi_); \
- while( __g && !((GtkCheckMenuItem *)(__g->data))->active) { \
- __g = __g->next; \
- __i++; \
- }\
-}
-
-#define RADIOBUTTONTOGGLED(_rb_, __i) { \
- GSList * __g; \
- __i = 0; \
- __g = gtk_radio_button_group(_rb_); \
- while( __g && !((GtkToggleButton *)(__g->data))->active) { \
- __g = __g->next; \
- __i++; \
- }\
-}
-
void after_press (GtkCTree *ctree, gpointer data)
{
char buf[80];
@@ -3708,7 +3761,7 @@ gint button_press (GtkCTree *ctree, GdkEventButton *event, gpointer data)
else
gtk_ctree_expand_recursive (ctree, work);
after_press (ctree, NULL);
- gtk_signal_emit_stop_by_name (GTK_OBJECT (ctree),
+ gtk_signal_emit_stop_by_name (GTK_OBJECT (ctree),
"button_press_event");
}
break;
@@ -3907,7 +3960,7 @@ void toggle_sel_mode (GtkWidget *widget, GtkCTree *ctree)
RADIOMENUTOGGLED ((GtkRadioMenuItem *)
(((GtkOptionMenu *)omenu)->menu_item), i);
- gtk_ctree_set_selection_mode (ctree, (GtkSelectionMode) (3-i));
+ gtk_clist_set_selection_mode (GTK_CLIST (ctree), (GtkSelectionMode) (3-i));
after_press (ctree, NULL);
}
@@ -3996,14 +4049,14 @@ void rebuild_tree (GtkWidget *widget, GtkCTree *ctree)
n = ((pow (b, d) - 1) / (b - 1)) * (p + 1);
- if (n > 200000)
+ if (n > 100000)
{
g_print ("%d total items? Try less\n",n);
return;
}
gtk_clist_freeze (GTK_CLIST (ctree));
- gtk_ctree_clear (ctree);
+ gtk_clist_clear (GTK_CLIST (ctree));
books = 1;
pages = 0;
@@ -4117,9 +4170,20 @@ void create_ctree (void)
GTK_SIGNAL_FUNC (after_press), NULL);
gtk_signal_connect_after (GTK_OBJECT (ctree), "tree_move",
GTK_SIGNAL_FUNC (after_move), NULL);
+ gtk_signal_connect_after (GTK_OBJECT (ctree), "end_selection",
+ GTK_SIGNAL_FUNC (after_press), NULL);
+ gtk_signal_connect_after (GTK_OBJECT (ctree), "toggle_focus_row",
+ GTK_SIGNAL_FUNC (after_press), NULL);
+ gtk_signal_connect_after (GTK_OBJECT (ctree), "select_all",
+ GTK_SIGNAL_FUNC (after_press), NULL);
+ gtk_signal_connect_after (GTK_OBJECT (ctree), "unselect_all",
+ GTK_SIGNAL_FUNC (after_press), NULL);
+ gtk_signal_connect_after (GTK_OBJECT (ctree), "scroll_vertical",
+ GTK_SIGNAL_FUNC (after_press), NULL);
+
gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (ctree), TRUE, TRUE, 0);
gtk_clist_column_titles_passive (GTK_CLIST (ctree));
- gtk_clist_set_selection_mode (GTK_CLIST (ctree), GTK_SELECTION_MULTIPLE);
+ gtk_clist_set_selection_mode (GTK_CLIST (ctree), GTK_SELECTION_EXTENDED);
gtk_clist_set_policy (GTK_CLIST (ctree), GTK_POLICY_ALWAYS,
GTK_POLICY_AUTOMATIC);
gtk_clist_set_column_width (GTK_CLIST (ctree), 0, 200);
@@ -4299,7 +4363,6 @@ void create_ctree (void)
GTK_SIGNAL_FUNC (toggle_sel_mode), ctree);
group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
gtk_menu_append (GTK_MENU (menu), menu_item);
- gtk_check_menu_item_set_state (GTK_CHECK_MENU_ITEM (menu_item), TRUE);
gtk_widget_show (menu_item);
menu_item = gtk_radio_menu_item_new_with_label (group, "Extended");
@@ -4307,12 +4370,13 @@ void create_ctree (void)
GTK_SIGNAL_FUNC (toggle_sel_mode), ctree);
group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
gtk_menu_append (GTK_MENU (menu), menu_item);
+ gtk_check_menu_item_set_state (GTK_CHECK_MENU_ITEM (menu_item), TRUE);
gtk_widget_show (menu_item);
gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
gtk_box_pack_start (GTK_BOX (hbox), omenu, FALSE, TRUE, 0);
- gtk_option_menu_set_history (GTK_OPTION_MENU (omenu), 2);
+ gtk_option_menu_set_history (GTK_OPTION_MENU (omenu), 3);
gtk_widget_realize (window);
@@ -4403,7 +4467,6 @@ void create_ctree (void)
gtk_widget_destroy (window);
}
-
/*
* GtkColorSelect
*/