* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
+
+/*
+ * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
#include <stdlib.h>
#include <string.h>
#include "config.h"
#include "gtkclist.h"
#include "gtkbindings.h"
#include "gtkdnd.h"
-#include <gdk/gdkx.h>
#include <gdk/gdkkeysyms.h>
/* length of button_actions array */
#define MAX_BUTTON 5
/* the number rows memchunk expands at a time */
-#define CLIST_OPTIMUM_SIZE 512
+#define CLIST_OPTIMUM_SIZE 64
/* the width of the column resize windows */
#define DRAG_WIDTH 6
return 0;
}
+/* returns the GList item for the nth row */
+#define ROW_ELEMENT(clist, row) (((row) == (clist)->rows - 1) ? \
+ (clist)->row_list_end : \
+ g_list_nth ((clist)->row_list, (row)))
+
+
#define GTK_CLIST_CLASS_FW(_widget_) GTK_CLIST_CLASS (((GtkObject*) (_widget_))->klass)
/* redraw the list if it's not frozen */
/* Signals */
-enum
-{
+enum {
SELECT_ROW,
UNSELECT_ROW,
ROW_MOVE,
LAST_SIGNAL
};
-enum
-{
+enum {
SYNC_REMOVE,
SYNC_INSERT
};
ARG_SHADOW_TYPE,
ARG_SELECTION_MODE,
ARG_ROW_HEIGHT,
+ ARG_TITLES_ACTIVE,
ARG_REORDERABLE,
- ARG_USE_DRAG_ICONS
+ ARG_USE_DRAG_ICONS,
+ ARG_SORT_TYPE
};
/* GtkCList Methods */
gint y,
GtkSelectionData *selection_data,
guint info,
- guint32 time);
+ guint time);
/* GtkContainer Methods */
static void gtk_clist_set_focus_child (GtkContainer *container,
GList *list,
gint num);
/* Misc */
-static gboolean title_focus (GtkCList *clist,
- gint dir);
-static void real_row_move (GtkCList *clist,
- gint source_row,
- gint dest_row);
+static gboolean title_focus (GtkCList *clist,
+ gint dir);
+static void real_row_move (GtkCList *clist,
+ gint source_row,
+ gint dest_row);
+static gint column_title_passive_func (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer data);
+static void drag_dest_cell (GtkCList *clist,
+ gint x,
+ gint y,
+ GtkCListDestInfo *dest_info);
GTK_TYPE_BOOL,
GTK_ARG_READWRITE,
ARG_REORDERABLE);
+ gtk_object_add_arg_type ("GtkCList::titles_active",
+ GTK_TYPE_BOOL,
+ GTK_ARG_READWRITE,
+ ARG_TITLES_ACTIVE);
gtk_object_add_arg_type ("GtkCList::use_drag_icons",
GTK_TYPE_BOOL,
GTK_ARG_READWRITE,
ARG_USE_DRAG_ICONS);
-
+ gtk_object_add_arg_type ("GtkCList::sort_type",
+ GTK_TYPE_SORT_TYPE,
+ GTK_ARG_READWRITE,
+ ARG_SORT_TYPE);
object_class->set_arg = gtk_clist_set_arg;
object_class->get_arg = gtk_clist_get_arg;
object_class->destroy = gtk_clist_destroy;
case ARG_REORDERABLE:
gtk_clist_set_reorderable (clist, GTK_VALUE_BOOL (*arg));
break;
+ case ARG_TITLES_ACTIVE:
+ if (GTK_VALUE_BOOL (*arg))
+ gtk_clist_column_titles_active (clist);
+ else
+ gtk_clist_column_titles_passive (clist);
+ break;
case ARG_USE_DRAG_ICONS:
gtk_clist_set_use_drag_icons (clist, GTK_VALUE_BOOL (*arg));
break;
- default:
+ case ARG_SORT_TYPE:
+ gtk_clist_set_sort_type (clist, GTK_VALUE_ENUM (*arg));
break;
}
}
switch (arg_id)
{
+ guint i;
+
case ARG_N_COLUMNS:
GTK_VALUE_UINT (*arg) = clist->columns;
break;
case ARG_REORDERABLE:
GTK_VALUE_BOOL (*arg) = GTK_CLIST_REORDERABLE (clist);
break;
+ case ARG_TITLES_ACTIVE:
+ GTK_VALUE_BOOL (*arg) = TRUE;
+ for (i = 0; i < clist->columns; i++)
+ if (clist->column[i].button &&
+ !GTK_WIDGET_SENSITIVE (clist->column[i].button))
+ {
+ GTK_VALUE_BOOL (*arg) = FALSE;
+ break;
+ }
+ break;
case ARG_USE_DRAG_ICONS:
GTK_VALUE_BOOL (*arg) = GTK_CLIST_USE_DRAG_ICONS (clist);
break;
+ case ARG_SORT_TYPE:
+ GTK_VALUE_ENUM (*arg) = clist->sort_type;
+ break;
default:
arg->type = GTK_TYPE_INVALID;
break;
if (column < 0 || column >= clist->columns)
return;
- if (!clist->column[column].button)
+ if (!clist->column[column].button || !clist->column[column].button_passive)
return;
- if (!GTK_WIDGET_SENSITIVE (clist->column[column].button) ||
- !GTK_WIDGET_CAN_FOCUS (clist->column[column].button))
- {
- GTK_WIDGET_SET_FLAGS (clist->column[column].button,
- GTK_SENSITIVE | GTK_CAN_FOCUS);
- if (GTK_WIDGET_VISIBLE (clist))
- gtk_widget_queue_draw (clist->column[column].button);
- }
+ clist->column[column].button_passive = FALSE;
+
+ gtk_signal_disconnect_by_func (GTK_OBJECT (clist->column[column].button),
+ (GtkSignalFunc) column_title_passive_func,
+ NULL);
+
+ GTK_WIDGET_SET_FLAGS (clist->column[column].button, GTK_CAN_FOCUS);
+ if (GTK_WIDGET_VISIBLE (clist))
+ gtk_widget_queue_draw (clist->column[column].button);
}
void
gtk_clist_column_title_passive (GtkCList *clist,
gint column)
{
+ GtkButton *button;
+
g_return_if_fail (clist != NULL);
g_return_if_fail (GTK_IS_CLIST (clist));
if (column < 0 || column >= clist->columns)
return;
- if (!clist->column[column].button)
+ if (!clist->column[column].button || clist->column[column].button_passive)
return;
- if (GTK_WIDGET_SENSITIVE (clist->column[column].button) ||
- GTK_WIDGET_CAN_FOCUS (clist->column[column].button))
- {
- GTK_WIDGET_UNSET_FLAGS (clist->column[column].button,
- GTK_SENSITIVE | GTK_CAN_FOCUS);
- if (GTK_WIDGET_VISIBLE (clist))
- gtk_widget_queue_draw (clist->column[column].button);
- }
+ button = GTK_BUTTON (clist->column[column].button);
+
+ clist->column[column].button_passive = TRUE;
+
+ if (button->button_down)
+ gtk_button_released (button);
+ if (button->in_button)
+ gtk_button_leave (button);
+
+ gtk_signal_connect (GTK_OBJECT (clist->column[column].button), "event",
+ (GtkSignalFunc) column_title_passive_func, NULL);
+
+ GTK_WIDGET_UNSET_FLAGS (clist->column[column].button, GTK_CAN_FOCUS);
+ if (GTK_WIDGET_VISIBLE (clist))
+ gtk_widget_queue_draw (clist->column[column].button);
}
void
void
gtk_clist_set_column_resizeable (GtkCList *clist,
gint column,
- gint resizeable)
+ gboolean resizeable)
{
g_return_if_fail (clist != NULL);
g_return_if_fail (GTK_IS_CLIST (clist));
* new_column_width
* column_button_create
* column_button_clicked
+ * column_title_passive_func
*/
static void
column_auto_resize (GtkCList *clist,
gtk_signal_connect (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) column_button_clicked,
(gpointer) clist);
-
gtk_widget_show (button);
}
gtk_signal_emit (GTK_OBJECT (clist), clist_signals[CLICK_COLUMN], i);
}
-void
-gtk_clist_set_row_height (GtkCList *clist,
- guint height)
+static gint
+column_title_passive_func (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer data)
{
- GtkWidget *widget;
-
- g_return_if_fail (clist != NULL);
- g_return_if_fail (GTK_IS_CLIST (clist));
-
- widget = GTK_WIDGET (clist);
-
- if (height > 0)
- {
- clist->row_height = height;
- GTK_CLIST_SET_FLAG (clist, CLIST_ROW_HEIGHT_SET);
- }
- else
- {
- GTK_CLIST_UNSET_FLAG (clist, CLIST_ROW_HEIGHT_SET);
- clist->row_height = 0;
- }
-
- if (GTK_WIDGET_REALIZED (clist))
- {
- if (!GTK_CLIST_ROW_HEIGHT_SET(clist))
- {
- clist->row_height = (widget->style->font->ascent +
- widget->style->font->descent + 1);
- clist->row_center_offset = widget->style->font->ascent + 1.5;
- }
- else
- clist->row_center_offset = 1.5 + (clist->row_height +
- widget->style->font->ascent -
- widget->style->font->descent - 1) / 2;
+ g_return_val_if_fail (event != NULL, FALSE);
+
+ switch (event->type)
+ {
+ case GDK_MOTION_NOTIFY:
+ case GDK_BUTTON_PRESS:
+ case GDK_2BUTTON_PRESS:
+ case GDK_3BUTTON_PRESS:
+ case GDK_BUTTON_RELEASE:
+ case GDK_ENTER_NOTIFY:
+ case GDK_LEAVE_NOTIFY:
+ return TRUE;
+ default:
+ break;
}
-
- CLIST_REFRESH (clist);
+ return FALSE;
}
-void
-gtk_clist_moveto (GtkCList *clist,
- gint row,
- gint column,
- gfloat row_align,
- gfloat col_align)
-{
- 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;
-
- row_align = CLAMP (row_align, 0, 1);
- col_align = CLAMP (col_align, 0, 1);
-
- /* adjust horizontal scrollbar */
- if (clist->hadjustment && column >= 0)
- {
- gint x;
-
- 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 (clist->hadjustment, 0.0);
- else if (x > LIST_WIDTH (clist) - clist->clist_window_width)
- gtk_adjustment_set_value
- (clist->hadjustment, LIST_WIDTH (clist) - clist->clist_window_width);
- else
- gtk_adjustment_set_value (clist->hadjustment, x);
- }
-
- /* adjust vertical scrollbar */
- if (clist->vadjustment && row >= 0)
- move_vertical (clist, row, row_align);
-}
/* PUBLIC CELL FUNCTIONS
* gtk_clist_get_cell_type
if (column < 0 || column >= clist->columns)
return -1;
- clist_row = (g_list_nth (clist->row_list, row))->data;
+ clist_row = ROW_ELEMENT (clist, row)->data;
return clist_row->cell[column].type;
}
if (column < 0 || column >= clist->columns)
return;
- clist_row = (g_list_nth (clist->row_list, row))->data;
+ clist_row = ROW_ELEMENT (clist, row)->data;
/* if text is null, then the cell is empty */
GTK_CLIST_CLASS_FW (clist)->set_cell_contents
if (column < 0 || column >= clist->columns)
return 0;
- clist_row = (g_list_nth (clist->row_list, row))->data;
+ clist_row = ROW_ELEMENT (clist, row)->data;
if (clist_row->cell[column].type != GTK_CELL_TEXT)
return 0;
if (column < 0 || column >= clist->columns)
return;
- clist_row = (g_list_nth (clist->row_list, row))->data;
+ clist_row = ROW_ELEMENT (clist, row)->data;
gdk_pixmap_ref (pixmap);
if (column < 0 || column >= clist->columns)
return 0;
- clist_row = (g_list_nth (clist->row_list, row))->data;
+ clist_row = ROW_ELEMENT (clist, row)->data;
if (clist_row->cell[column].type != GTK_CELL_PIXMAP)
return 0;
if (column < 0 || column >= clist->columns)
return;
- clist_row = (g_list_nth (clist->row_list, row))->data;
+ clist_row = ROW_ELEMENT (clist, row)->data;
gdk_pixmap_ref (pixmap);
if (mask) gdk_pixmap_ref (mask);
if (column < 0 || column >= clist->columns)
return 0;
- clist_row = (g_list_nth (clist->row_list, row))->data;
+ clist_row = ROW_ELEMENT (clist, row)->data;
if (clist_row->cell[column].type != GTK_CELL_PIXTEXT)
return 0;
gint vertical,
gint horizontal)
{
- GtkRequisition requisition;
+ GtkRequisition requisition = { 0 };
GtkCListRow *clist_row;
g_return_if_fail (clist != NULL);
if (column < 0 || column >= clist->columns)
return;
- clist_row = (g_list_nth (clist->row_list, row))->data;
+ clist_row = ROW_ELEMENT (clist, row)->data;
if (clist->column[column].auto_resize &&
!GTK_CLIST_AUTO_RESIZE_BLOCKED(clist))
was_selected = 0;
/* get the row we're going to delete */
- list = g_list_nth (clist->row_list, row);
+ list = ROW_ELEMENT (clist, row);
g_assert (list != NULL);
clist_row = list->data;
gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNSELECT_ROW],
row, -1, NULL);
- /* reset the row end pointer if we're removing at the
- * end of the list */
+ /* reset the row end pointer if we're removing at the end of the list */
clist->rows--;
if (clist->row_list == list)
clist->row_list = g_list_next (list);
gtk_clist_freeze (clist);
/* unlink source row */
- clist_row = g_list_nth_data (clist->row_list, source_row);
+ clist_row = ROW_ELEMENT (clist, source_row)->data;
if (source_row == clist->rows - 1)
clist->row_list_end = clist->row_list_end->prev;
clist->row_list = g_list_remove (clist->row_list, clist_row);
}
/* PUBLIC ROW FUNCTIONS
+ * gtk_clist_moveto
+ * gtk_clist_set_row_height
* gtk_clist_set_row_data
* gtk_clist_set_row_data_full
* gtk_clist_get_row_data
* gtk_clist_set_foreground
* gtk_clist_set_background
*/
+void
+gtk_clist_moveto (GtkCList *clist,
+ gint row,
+ gint column,
+ gfloat row_align,
+ gfloat col_align)
+{
+ 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;
+
+ row_align = CLAMP (row_align, 0, 1);
+ col_align = CLAMP (col_align, 0, 1);
+
+ /* adjust horizontal scrollbar */
+ if (clist->hadjustment && column >= 0)
+ {
+ gint x;
+
+ 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 (clist->hadjustment, 0.0);
+ else if (x > LIST_WIDTH (clist) - clist->clist_window_width)
+ gtk_adjustment_set_value
+ (clist->hadjustment, LIST_WIDTH (clist) - clist->clist_window_width);
+ else
+ gtk_adjustment_set_value (clist->hadjustment, x);
+ }
+
+ /* adjust vertical scrollbar */
+ if (clist->vadjustment && row >= 0)
+ move_vertical (clist, row, row_align);
+}
+
+void
+gtk_clist_set_row_height (GtkCList *clist,
+ guint height)
+{
+ GtkWidget *widget;
+
+ g_return_if_fail (clist != NULL);
+ g_return_if_fail (GTK_IS_CLIST (clist));
+
+ widget = GTK_WIDGET (clist);
+
+ if (height > 0)
+ {
+ clist->row_height = height;
+ GTK_CLIST_SET_FLAG (clist, CLIST_ROW_HEIGHT_SET);
+ }
+ else
+ {
+ GTK_CLIST_UNSET_FLAG (clist, CLIST_ROW_HEIGHT_SET);
+ clist->row_height = 0;
+ }
+
+ if (GTK_WIDGET_REALIZED (clist))
+ {
+ if (!GTK_CLIST_ROW_HEIGHT_SET(clist))
+ {
+ clist->row_height = (widget->style->font->ascent +
+ widget->style->font->descent + 1);
+ clist->row_center_offset = widget->style->font->ascent + 1.5;
+ }
+ else
+ clist->row_center_offset = 1.5 + (clist->row_height +
+ widget->style->font->ascent -
+ widget->style->font->descent - 1) / 2;
+ }
+
+ CLIST_REFRESH (clist);
+}
+
void
gtk_clist_set_row_data (GtkCList *clist,
gint row,
if (row < 0 || row > (clist->rows - 1))
return;
- clist_row = (g_list_nth (clist->row_list, row))->data;
+ clist_row = ROW_ELEMENT (clist, row)->data;
+
+ if (clist_row->destroy)
+ clist_row->destroy (clist_row->data);
+
clist_row->data = data;
clist_row->destroy = destroy;
}
if (row < 0 || row > (clist->rows - 1))
return NULL;
- clist_row = (g_list_nth (clist->row_list, row))->data;
+ clist_row = ROW_ELEMENT (clist, row)->data;
return clist_row->data;
}
if (row < 0 || row >= clist->rows)
return;
- clist_row = (g_list_nth (clist->row_list, row))->data;
+ clist_row = ROW_ELEMENT (clist, row)->data;
if (color)
{
if (row < 0 || row >= clist->rows)
return;
- clist_row = (g_list_nth (clist->row_list, row))->data;
+ clist_row = ROW_ELEMENT (clist, row)->data;
if (color)
{
gint column,
GtkStyle *style)
{
- GtkRequisition requisition;
+ GtkRequisition requisition = { 0 };
GtkCListRow *clist_row;
g_return_if_fail (clist != NULL);
if (column < 0 || column >= clist->columns)
return;
- clist_row = (g_list_nth (clist->row_list, row))->data;
+ clist_row = ROW_ELEMENT (clist, row)->data;
if (clist_row->cell[column].style == style)
return;
if (row < 0 || row >= clist->rows || column < 0 || column >= clist->columns)
return NULL;
- clist_row = (g_list_nth (clist->row_list, row))->data;
+ clist_row = ROW_ELEMENT (clist, row)->data;
return clist_row->cell[column].style;
}
if (row < 0 || row >= clist->rows)
return;
- clist_row = (g_list_nth (clist->row_list, row))->data;
+ clist_row = ROW_ELEMENT (clist, row)->data;
if (clist_row->style == style)
return;
if (row < 0 || row >= clist->rows)
return NULL;
- clist_row = (g_list_nth (clist->row_list, row))->data;
+ clist_row = ROW_ELEMENT (clist, row)->data;
return clist_row->style;
}
if (row < 0 || row >= clist->rows)
return;
- clist_row = (g_list_nth (clist->row_list, row))->data;
+ clist_row = ROW_ELEMENT (clist, row)->data;
if (selectable == clist_row->selectable)
return;
if (row < 0 || row >= clist->rows)
return FALSE;
- return GTK_CLIST_ROW (g_list_nth (clist->row_list, row))->selectable;
+ return GTK_CLIST_ROW (ROW_ELEMENT (clist, row))->selectable;
}
void
case GTK_SELECTION_EXTENDED:
case GTK_SELECTION_MULTIPLE:
case GTK_SELECTION_SINGLE:
- clist_row = g_list_nth (clist->row_list, row)->data;
+ clist_row = ROW_ELEMENT (clist, row)->data;
if (!clist_row)
return;
{
GList *work;
- work = g_list_nth (clist->row_list, row);
+ work = ROW_ELEMENT (clist, row);
if (!work || !GTK_CLIST_ROW (work)->selectable)
return;
break;
}
- clist_row = (g_list_nth (clist->row_list, row))->data;
+ clist_row = ROW_ELEMENT (clist, row)->data;
if (clist_row->state != GTK_STATE_NORMAL || !clist_row->selectable)
return;
if (row < 0 || row > (clist->rows - 1))
return;
- clist_row = (g_list_nth (clist->row_list, row))->data;
+ clist_row = ROW_ELEMENT (clist, row)->data;
if (clist_row->state == GTK_STATE_SELECTED)
{
GList *work;
gint i;
- if (row >= 0 && (work = g_list_nth (clist->row_list, row)))
+ if (row >= 0 && (work = ROW_ELEMENT (clist, row)))
{
if (GTK_CLIST_ROW (work)->state == GTK_STATE_NORMAL &&
GTK_CLIST_ROW (work)->selectable)
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 ||
clist->selection_mode != GTK_SELECTION_EXTENDED)
return;
- if (clist->anchor >= 0)
- GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+ GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
if (!(clist->undo_selection || clist->undo_unselection))
{
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);
+ {
+ /* g_print ("unselect %d\n",GPOINTER_TO_INT (work->data)); */
+ 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)
{
GList *list;
GtkCListRow *clist_row;
- if (clist->anchor < 0)
+ if (clist->selection_mode != GTK_SELECTION_EXTENDED)
+ return;
+
+ if (clist->anchor < 0 || clist->drag_pos < 0)
return;
gtk_clist_freeze (clist);
}
}
}
-
- for (list = g_list_reverse (clist->undo_unselection); list;
- list = list->next)
+
+ clist->undo_unselection = g_list_reverse (clist->undo_unselection);
+ 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);
g_return_if_fail (clist != NULL);
g_return_if_fail (GTK_IS_CLIST (clist));
- if ((gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_FOCUS(clist)) ||
- clist->anchor == -1)
+ if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_FOCUS(clist))
return;
-
+
GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
}
clist->focus_row = clist->rows - 1;
}
- if (clist->selection_mode == GTK_SELECTION_BROWSE && clist->anchor != -1)
- GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+ GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
g_list_free (clist->undo_selection);
g_list_free (clist->undo_unselection);
/* We'll use this gc to do scrolling as well */
gdk_gc_set_exposures (clist->fg_gc, TRUE);
- values.foreground = widget->style->white;
+ values.foreground = (widget->style->white.pixel==0 ?
+ widget->style->black:widget->style->white);
values.function = GDK_XOR;
values.subwindow_mode = GDK_INCLUDE_INFERIORS;
clist->xor_gc = gdk_gc_new_with_values (widget->window,
/* freeze the list */
clist->freeze_count++;
- /* detach optional row/cell styles */
+ if (GTK_WIDGET_MAPPED (widget))
+ gtk_clist_unmap (widget);
+ GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
+
+ /* detach optional row/cell styles */
if (GTK_WIDGET_REALIZED (widget))
{
GtkCListRow *clist_row;
gdk_gc_destroy (clist->bg_gc);
for (i = 0; i < clist->columns; i++)
- if (clist->column[i].window)
- {
- gdk_window_set_user_data (clist->column[i].window, NULL);
- gdk_window_destroy (clist->column[i].window);
- clist->column[i].window = NULL;
- }
+ {
+ if (clist->column[i].button)
+ gtk_widget_unrealize (clist->column[i].button);
+ if (clist->column[i].window)
+ {
+ gdk_window_set_user_data (clist->column[i].window, NULL);
+ gdk_window_destroy (clist->column[i].window);
+ clist->column[i].window = NULL;
+ }
+ }
gdk_window_set_user_data (clist->clist_window, NULL);
gdk_window_destroy (clist->clist_window);
/* map column buttons */
for (i = 0; i < clist->columns; i++)
- if (clist->column[i].button &&
- GTK_WIDGET_VISIBLE (clist->column[i].button) &&
- !GTK_WIDGET_MAPPED (clist->column[i].button))
- gtk_widget_map (clist->column[i].button);
+ {
+ if (clist->column[i].button &&
+ GTK_WIDGET_VISIBLE (clist->column[i].button) &&
+ !GTK_WIDGET_MAPPED (clist->column[i].button))
+ gtk_widget_map (clist->column[i].button);
+ }
for (i = 0; i < clist->columns; i++)
if (clist->column[i].window && clist->column[i].button)
{
remove_grab (clist);
- if (clist->anchor != -1 &&
- clist->selection_mode == GTK_SELECTION_EXTENDED)
- GTK_CLIST_CLASS_FW (widget)->resync_selection (clist, NULL);
+ GTK_CLIST_CLASS_FW (widget)->resync_selection (clist, NULL);
clist->click_cell.row = -1;
clist->click_cell.column = -1;
(2 * widget->style->klass->ythickness) +
clist->column_title_area.height);
- gdk_window_clear_area (clist->clist_window, 0, 0, -1, -1);
+ gdk_window_clear_area (clist->clist_window, 0, 0, 0, 0);
draw_rows (clist, NULL);
for (i = 0; i < clist->columns; i++)
case GTK_SELECTION_SINGLE:
case GTK_SELECTION_MULTIPLE:
if (event->type != GDK_BUTTON_PRESS)
- gtk_signal_emit (GTK_OBJECT (clist),
- clist_signals[SELECT_ROW],
- row, column, event);
+ {
+ gtk_signal_emit (GTK_OBJECT (clist),
+ clist_signals[SELECT_ROW],
+ row, column, event);
+ clist->anchor = -1;
+ }
else
clist->anchor = row;
break;
{
case GTK_SELECTION_EXTENDED:
if (!(event->state & GDK_SHIFT_MASK) ||
+ !GTK_WIDGET_CAN_FOCUS (widget) ||
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
gdk_draw_pixmap (window, fg_gc, pixmap, xsrc, ysrc, x, y, width, height);
gdk_gc_set_clip_origin (fg_gc, 0, 0);
+ if (mask)
+ gdk_gc_set_clip_mask (fg_gc, NULL);
return x + MAX (width, 0);
}
/* if the function is passed the pointer to the row instead of null,
* it avoids this expensive lookup */
if (!clist_row)
- clist_row = (g_list_nth (clist->row_list, row))->data;
+ clist_row = ROW_ELEMENT (clist, row)->data;
/* rectangle of the entire row */
row_rectangle.x = 0;
cell_rectangle.width = row_rectangle.width;
cell_rectangle.height = CELL_SPACING;
- /* rectangle used to clip drawing operations, it's y and height
+ /* rectangle used to clip drawing operations, its y and height
* positions only need to be set once, so we set them once here.
* the x and width are set withing the drawing loop below once per
* column */
intersect_rectangle.width,
intersect_rectangle.height);
- /* the last row has to clear it's bottom cell spacing too */
+ /* the last row has to clear its bottom cell spacing too */
if (clist_row == clist->row_list_end->data)
{
cell_rectangle.y += clist->row_height + CELL_SPACING;
cell_rectangle.width,
cell_rectangle.height);
- /* the last row has to clear it's bottom cell spacing too */
+ /* the last row has to clear its bottom cell spacing too */
if (clist_row == clist->row_list_end->data)
{
cell_rectangle.y += clist->row_height + CELL_SPACING;
if (clist->rows == first_row)
first_row--;
- list = g_list_nth (clist->row_list, first_row);
+ list = ROW_ELEMENT (clist, first_row);
i = first_row;
while (list)
{
}
if (!area)
- gdk_window_clear_area (clist->clist_window,
- 0, ROW_TOP_YPIXEL (clist, i), -1, -1);
+ gdk_window_clear_area (clist->clist_window, 0,
+ ROW_TOP_YPIXEL (clist, i), 0, 0);
}
static void
clist->vadjustment->lower = 0;
clist->vadjustment->upper = LIST_HEIGHT (clist);
- if (clist->clist_window_height - clist->voffset > LIST_HEIGHT (clist))
+ if (clist->clist_window_height - clist->voffset > LIST_HEIGHT (clist) ||
+ (clist->voffset + (gint)clist->vadjustment->value) != 0)
{
clist->vadjustment->value = MAX (0, (LIST_HEIGHT (clist) -
clist->clist_window_height));
clist->hadjustment->lower = 0;
clist->hadjustment->upper = LIST_WIDTH (clist);
- if (clist->clist_window_width - clist->hoffset > LIST_WIDTH (clist))
+ if (clist->clist_window_width - clist->hoffset > LIST_WIDTH (clist) ||
+ (clist->hoffset + (gint)clist->hadjustment->value) != 0)
{
clist->hadjustment->value = MAX (0, (LIST_WIDTH (clist) -
clist->clist_window_width));
column[i].width_set = FALSE;
column[i].resizeable = TRUE;
column[i].auto_resize = FALSE;
+ column[i].button_passive = FALSE;
column[i].justification = GTK_JUSTIFY_LEFT;
}
clist = GTK_CLIST (widget);
- if (clist->anchor != -1 && clist->selection_mode == GTK_SELECTION_EXTENDED)
- GTK_CLIST_CLASS_FW (widget)->resync_selection (clist, (GdkEvent *) event);
+ GTK_CLIST_CLASS_FW (widget)->resync_selection (clist, (GdkEvent *) event);
return FALSE;
}
static gint
horizontal_timeout (GtkCList *clist)
{
- gint x, y;
- GdkEventMotion event;
- GdkModifierType mask;
+ GdkEventMotion event = { 0 };
GDK_THREADS_ENTER ();
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;
+ event.type = GDK_MOTION_NOTIFY;
+ event.send_event = TRUE;
gtk_clist_motion (GTK_WIDGET (clist), &event);
static gint
vertical_timeout (GtkCList *clist)
{
- gint x, y;
- GdkEventMotion event;
- GdkModifierType mask;
+ GdkEventMotion event = { 0 };
GDK_THREADS_ENTER ();
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;
+ event.type = GDK_MOTION_NOTIFY;
+ event.send_event = TRUE;
gtk_clist_motion (GTK_WIDGET (clist), &event);
g_free (info);
}
+static void
+drag_dest_cell (GtkCList *clist,
+ gint x,
+ gint y,
+ GtkCListDestInfo *dest_info)
+{
+ GtkWidget *widget;
+
+ widget = GTK_WIDGET (clist);
+
+ dest_info->insert_pos = GTK_CLIST_DRAG_NONE;
+
+ y -= (GTK_CONTAINER (clist)->border_width +
+ widget->style->klass->ythickness +
+ clist->column_title_area.height);
+
+ dest_info->cell.row = ROW_FROM_YPIXEL (clist, y);
+ if (dest_info->cell.row >= clist->rows)
+ {
+ dest_info->cell.row = clist->rows - 1;
+ y = ROW_TOP_YPIXEL (clist, dest_info->cell.row) + clist->row_height;
+ }
+ if (dest_info->cell.row < -1)
+ dest_info->cell.row = -1;
+
+ x -= GTK_CONTAINER (widget)->border_width + widget->style->klass->xthickness;
+ dest_info->cell.column = COLUMN_FROM_XPIXEL (clist, x);
+
+ if (dest_info->cell.row >= 0)
+ {
+ gint y_delta;
+ gint h = 0;
+
+ y_delta = y - ROW_TOP_YPIXEL (clist, dest_info->cell.row);
+
+ if (GTK_CLIST_DRAW_DRAG_RECT(clist))
+ {
+ dest_info->insert_pos = GTK_CLIST_DRAG_INTO;
+ h = clist->row_height / 4;
+ }
+ else if (GTK_CLIST_DRAW_DRAG_LINE(clist))
+ {
+ dest_info->insert_pos = GTK_CLIST_DRAG_BEFORE;
+ h = clist->row_height / 2;
+ }
+
+ if (GTK_CLIST_DRAW_DRAG_LINE(clist))
+ {
+ if (y_delta < h)
+ dest_info->insert_pos = GTK_CLIST_DRAG_BEFORE;
+ else if (clist->row_height - y_delta < h)
+ dest_info->insert_pos = GTK_CLIST_DRAG_AFTER;
+ }
+ }
+}
+
static void
gtk_clist_drag_begin (GtkWidget *widget,
GdkDragContext *context)
guint time)
{
GtkCList *clist;
- gint row, column;
+ GtkCListDestInfo new_info;
GtkCListDestInfo *dest_info;
- gint h = 0;
- gint insert_pos = GTK_CLIST_DRAG_NONE;
- gint y_delta;
g_return_val_if_fail (widget != NULL, FALSE);
g_return_val_if_fail (GTK_IS_CLIST (widget), FALSE);
clist = GTK_CLIST (widget);
- y -= (GTK_CONTAINER (widget)->border_width +
- widget->style->klass->ythickness + clist->column_title_area.height);
- row = ROW_FROM_YPIXEL (clist, y);
-
- if (row >= clist->rows)
- {
- row = clist->rows - 1;
- y = ROW_TOP_YPIXEL (clist, row) + clist->row_height;
- }
- if (row < -1)
- row = -1;
-
- x -= GTK_CONTAINER (widget)->border_width + widget->style->klass->xthickness;
- column = COLUMN_FROM_XPIXEL (clist, x);
-
- if (row >= 0)
- {
- y_delta = y - ROW_TOP_YPIXEL (clist, row);
-
- if (GTK_CLIST_DRAW_DRAG_RECT(clist))
- {
- insert_pos = GTK_CLIST_DRAG_INTO;
- h = clist->row_height / 4;
- }
- else if (GTK_CLIST_DRAW_DRAG_LINE(clist))
- {
- insert_pos = GTK_CLIST_DRAG_BEFORE;
- h = clist->row_height / 2;
- }
-
- if (GTK_CLIST_DRAW_DRAG_LINE(clist))
- {
- if (y_delta < h)
- insert_pos = GTK_CLIST_DRAG_BEFORE;
- else if (clist->row_height - y_delta < h)
- insert_pos = GTK_CLIST_DRAG_AFTER;
- }
- }
-
dest_info = g_dataset_get_data (context, "gtk-clist-drag-dest");
if (!dest_info)
drag_dest_info_destroy);
}
+ drag_dest_cell (clist, x, y, &new_info);
+
if (GTK_CLIST_REORDERABLE (clist))
{
GList *list;
if (list)
{
if (gtk_drag_get_source_widget (context) != widget ||
- insert_pos == GTK_CLIST_DRAG_NONE ||
- row == clist->click_cell.row ||
- (row == clist->click_cell.row - 1 &&
- insert_pos == GTK_CLIST_DRAG_AFTER) ||
- (row == clist->click_cell.row + 1 &&
- insert_pos == GTK_CLIST_DRAG_BEFORE))
+ new_info.insert_pos == GTK_CLIST_DRAG_NONE ||
+ new_info.cell.row == clist->click_cell.row ||
+ (new_info.cell.row == clist->click_cell.row - 1 &&
+ new_info.insert_pos == GTK_CLIST_DRAG_AFTER) ||
+ (new_info.cell.row == clist->click_cell.row + 1 &&
+ new_info.insert_pos == GTK_CLIST_DRAG_BEFORE))
{
if (dest_info->cell.row < 0)
{
return TRUE;
}
- if (row != dest_info->cell.row ||
- (row == dest_info->cell.row &&
- dest_info->insert_pos != insert_pos))
+ if (new_info.cell.row != dest_info->cell.row ||
+ (new_info.cell.row == dest_info->cell.row &&
+ dest_info->insert_pos != new_info.insert_pos))
{
if (dest_info->cell.row >= 0)
GTK_CLIST_CLASS_FW (clist)->draw_drag_highlight
dest_info->cell.row)->data,
dest_info->cell.row, dest_info->insert_pos);
- dest_info->insert_pos = insert_pos;
- dest_info->cell.row = row;
- dest_info->cell.column = column;
+ dest_info->insert_pos = new_info.insert_pos;
+ dest_info->cell.row = new_info.cell.row;
+ dest_info->cell.column = new_info.cell.column;
GTK_CLIST_CLASS_FW (clist)->draw_drag_highlight
(clist, g_list_nth (clist->row_list,
}
}
- dest_info->insert_pos = insert_pos;
- dest_info->cell.row = row;
- dest_info->cell.column = column;
+ dest_info->insert_pos = new_info.insert_pos;
+ dest_info->cell.row = new_info.cell.row;
+ dest_info->cell.column = new_info.cell.column;
return TRUE;
}
gint y,
GtkSelectionData *selection_data,
guint info,
- guint32 time)
+ guint time)
{
GtkCList *clist;
selection_data->length == sizeof (GtkCListCellInfo))
{
GtkCListCellInfo *source_info;
- GtkCListDestInfo *dest_info;
source_info = (GtkCListCellInfo *)(selection_data->data);
- dest_info = g_dataset_get_data (context, "gtk-clist-drag-dest");
-
- if (dest_info && source_info)
+ if (source_info)
{
- if (dest_info->insert_pos == GTK_CLIST_DRAG_AFTER)
- dest_info->cell.row++;
- if (source_info->row < dest_info->cell.row)
- dest_info->cell.row--;
-
- if (dest_info->cell.row != source_info->row)
- gtk_clist_row_move (GTK_CLIST (widget),
- source_info->row,
- dest_info->cell.row);
+ GtkCListDestInfo dest_info;
+
+ drag_dest_cell (clist, x, y, &dest_info);
+
+ if (dest_info.insert_pos == GTK_CLIST_DRAG_AFTER)
+ dest_info.cell.row++;
+ if (source_info->row < dest_info.cell.row)
+ dest_info.cell.row--;
+ if (dest_info.cell.row != source_info->row)
+ gtk_clist_row_move (clist, source_info->row, dest_info.cell.row);
+
g_dataset_remove_data (context, "gtk-clist-drag-dest");
}
}
if (info)
{
- GtkCListCellInfo *ret_info;
+ GtkCListCellInfo ret_info;
- ret_info = g_new (GtkCListCellInfo, 1);
- ret_info->row = info->row;
- ret_info->column = info->column;
+ ret_info.row = info->row;
+ ret_info.column = info->column;
- gtk_selection_data_set (selection_data,
- selection_data->target,
- GTK_TYPE_POINTER,
- (guchar *) ret_info,
+ gtk_selection_data_set (selection_data, selection_data->target,
+ GTK_TYPE_POINTER, (guchar *) &ret_info,
sizeof (GtkCListCellInfo));
}
else
gtk_selection_data_set (selection_data, selection_data->target,
- GTK_TYPE_POINTER, NULL, 0);
+ GTK_TYPE_POINTER, NULL, 0);
}
}
g_return_if_fail (clist != NULL);
g_return_if_fail (GTK_IS_CLIST (clist));
- if (button <= MAX_BUTTON)
+ if (button < MAX_BUTTON)
{
if (gdk_pointer_is_grabbed () || GTK_WIDGET_HAS_GRAB (clist))
{
clist->drag_button = 0;
}
- if (clist->anchor >= 0 &&
- clist->selection_mode == GTK_SELECTION_EXTENDED)
- GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+ GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
clist->button_actions[button] = button_actions;
}