#include "gtkclist.h"
#include "gtkbindings.h"
#include "gtkdnd.h"
-#include "gdkx.h"
#include <gdk/gdkkeysyms.h>
/* length of button_actions array */
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_ROW_HEIGHT,
ARG_TITLES_ACTIVE,
ARG_REORDERABLE,
- ARG_USE_DRAG_ICONS
+ ARG_USE_DRAG_ICONS,
+ ARG_SORT_TYPE
};
/* GtkCList Methods */
GtkCListDestInfo *dest_info);
+
static GtkContainerClass *parent_class = NULL;
static guint clist_signals[LAST_SIGNAL] = {0};
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_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;
}
}
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;
gtk_clist_column_title_active (GtkCList *clist,
gint column)
{
- GtkObject *object;
-
g_return_if_fail (clist != NULL);
g_return_if_fail (GTK_IS_CLIST (clist));
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;
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);
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)
{
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))
{
for (work = clist->undo_unselection; work; work = work->next)
{
- g_print ("unselect %d\n",GPOINTER_TO_INT (work->data));
+ /* 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);
}
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);
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,
{
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;
/* 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));
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;
}
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;
}