📄 collect-table.c
字号:
return info;}static CollectInfo *collection_table_insert_point(CollectTable *ct, gint x, gint y){ CollectInfo *info; GdkRectangle cell; gint after = FALSE; info = collection_table_insert_find(ct, NULL, &after, &cell, TRUE, x, y); if (info && after) { GList *work; work = g_list_find(ct->cd->list, info); if (work && work->next) { info = work->next->data; } else { info = NULL; } } return info;}static void collection_table_insert_marker(CollectTable *ct, CollectInfo *info, gint enable){ gint row, col; gint after = FALSE; GdkRectangle cell; if (!enable) { if (ct->marker_window) gdk_window_destroy(ct->marker_window); ct->marker_window = NULL; return; } info = collection_table_insert_find(ct, info, &after, &cell, FALSE, 0, 0); /* this setting does not take into account (after), but since it is not really used... */ ct->marker_info = info; row = -1; col = -1; if (!ct->marker_window) { GdkWindow *parent; GdkWindowAttr attributes; gint attributes_mask; GdkPixmap *pixmap; GdkBitmap *mask; GdkPixbuf *pb; gint w, h; parent = gtk_tree_view_get_bin_window(GTK_TREE_VIEW(ct->listview)); pb = gdk_pixbuf_new_from_xpm_data((const char **)marker_xpm); gdk_pixbuf_render_pixmap_and_mask(pb, &pixmap, &mask, 128); gdk_pixbuf_unref(pb); gdk_drawable_get_size(pixmap, &w, &h); attributes.window_type = GDK_WINDOW_CHILD; attributes.wclass = GDK_INPUT_OUTPUT; attributes.width = w; attributes.height = h; attributes.event_mask = gtk_widget_get_events(ct->listview); attributes_mask = 0; ct->marker_window = gdk_window_new(parent, &attributes, attributes_mask); gdk_window_set_back_pixmap(ct->marker_window, pixmap, FALSE); gdk_window_shape_combine_mask(ct->marker_window, mask, 0, 0); g_object_unref(pixmap); if (mask) g_object_unref(mask); } if (info) { gint x, y; gint w, h; gdk_drawable_get_size(ct->marker_window, &w, &h); if (!after) { x = cell.x; } else { x = cell.x + cell.width; } x -= (w / 2); y = cell.y + (cell.height / 2) - (h / 2); gdk_window_move(ct->marker_window, x, y); gdk_window_clear(ct->marker_window); if (!gdk_window_is_visible(ct->marker_window)) gdk_window_show(ct->marker_window); } else { if (gdk_window_is_visible(ct->marker_window)) gdk_window_hide(ct->marker_window); }}/* *------------------------------------------------------------------- * mouse drag auto-scroll *------------------------------------------------------------------- */static void collection_table_motion_update(CollectTable *ct, gint x, gint y, gint drop_event){ CollectInfo *info; info = collection_table_find_data_by_coord(ct, x, y, NULL); if (drop_event) { tip_unschedule(ct); collection_table_insert_marker(ct, info, TRUE); } else { tip_update(ct, info); }}static gint collection_table_auto_scroll_idle_cb(gpointer data){ CollectTable *ct = data; GdkWindow *window; gint x, y; gint w, h; if (ct->drop_idle_id == -1) return FALSE; window = ct->listview->window; gdk_window_get_pointer(window, &x, &y, NULL); gdk_drawable_get_size(window, &w, &h); if (x >= 0 && x < w && y >= 0 && y < h) { collection_table_motion_update(ct, x, y, TRUE); } ct->drop_idle_id = -1; return FALSE;}static gint collection_table_auto_scroll_notify_cb(GtkWidget *widget, gint x, gint y, gpointer data){ CollectTable *ct = data; if (ct->drop_idle_id == -1) ct->drop_idle_id = g_idle_add(collection_table_auto_scroll_idle_cb, ct); return TRUE;}static void collection_table_scroll(CollectTable *ct, gint scroll){ if (!scroll) { if (ct->drop_idle_id != -1) { g_source_remove(ct->drop_idle_id); ct->drop_idle_id = -1; } widget_auto_scroll_stop(ct->listview); collection_table_insert_marker(ct, NULL, FALSE); } else { GtkAdjustment *adj = gtk_tree_view_get_vadjustment(GTK_TREE_VIEW(ct->listview)); widget_auto_scroll_start(ct->listview, adj, -1, thumb_max_height / 2, collection_table_auto_scroll_notify_cb, ct); }}/* *------------------------------------------------------------------- * mouse callbacks *------------------------------------------------------------------- */static gint collection_table_motion_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data){ CollectTable *ct = data; collection_table_motion_update(ct, (gint)bevent->x, (gint)bevent->y, FALSE); return FALSE;}static gint collection_table_press_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data){ CollectTable *ct = data; GtkTreeIter iter; CollectInfo *info; tip_unschedule(ct); info = collection_table_find_data_by_coord(ct, (gint)bevent->x, (gint)bevent->y, &iter); ct->click_info = info; collection_table_selection_add(ct, ct->click_info, SELECTION_PRELIGHT, &iter); switch (bevent->button) { case 1: if (bevent->type == GDK_2BUTTON_PRESS) { if (info) { layout_image_set_collection(NULL, ct->cd, info); } } else if (!GTK_WIDGET_HAS_FOCUS(ct->listview)) { gtk_widget_grab_focus(ct->listview); } break; case 3: ct->popup = collection_table_popup_menu(ct, (info != NULL)); gtk_menu_popup(GTK_MENU(ct->popup), NULL, NULL, NULL, NULL, bevent->button, bevent->time); break; default: break; } return TRUE;}static gint collection_table_release_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data){ CollectTable *ct = data; GtkTreeIter iter; CollectInfo *info = NULL; tip_schedule(ct); if ((gint)bevent->x != 0 || (gint) bevent->y != 0) { info = collection_table_find_data_by_coord(ct, (gint)bevent->x, (gint)bevent->y, &iter); } if (ct->click_info) { collection_table_selection_remove(ct, ct->click_info, SELECTION_PRELIGHT, NULL); } if (bevent->button == 1 && info && ct->click_info == info) { collection_table_set_focus(ct, info); if (bevent->state & GDK_CONTROL_MASK) { gint select; select = !INFO_SELECTED(info); if ((bevent->state & GDK_SHIFT_MASK) && ct->prev_selection) { collection_table_select_region_util(ct, ct->prev_selection, info, select); } else { collection_table_select_util(ct, info, select); } } else { collection_table_unselect_all(ct); if ((bevent->state & GDK_SHIFT_MASK) && ct->prev_selection) { collection_table_select_region_util(ct, ct->prev_selection, info, TRUE); } else { collection_table_select_util(ct, info, TRUE); } } } else if (bevent->button == 2 && info && ct->click_info == info) { collection_table_select_util(ct, info, !INFO_SELECTED(info)); } return TRUE;}static gint collection_table_leave_cb(GtkWidget *widget, GdkEventCrossing *event, gpointer data){ CollectTable *ct = data; tip_unschedule(ct); return FALSE;}/* *------------------------------------------------------------------- * populate, add, insert, etc. *------------------------------------------------------------------- */static gboolean collection_table_destroy_node_cb(GtkTreeModel *store, GtkTreePath *tpath, GtkTreeIter *iter, gpointer data){ GList *list; gtk_tree_model_get(store, iter, CTABLE_COLUMN_POINTER, &list, -1); g_list_free(list); return FALSE;}static void collection_table_clear_store(CollectTable *ct){ GtkTreeModel *store; store = gtk_tree_view_get_model(GTK_TREE_VIEW(ct->listview)); gtk_tree_model_foreach(store, collection_table_destroy_node_cb, NULL); gtk_list_store_clear(GTK_LIST_STORE(store));}static GList *collection_table_add_row(CollectTable *ct, GtkTreeIter *iter){ GtkListStore *store; GList *list = NULL; gint i; for (i = 0; i < ct->columns; i++) list = g_list_prepend(list, NULL); store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(ct->listview))); gtk_list_store_append(store, iter); gtk_list_store_set(store, iter, CTABLE_COLUMN_POINTER, list, -1); return list;}static void collection_table_populate(CollectTable *ct, gint resize){ gint row; GList *work; collection_table_verify_selections(ct); collection_table_clear_store(ct); if (resize) { gint i; gint thumb_width; thumb_width = collection_table_get_icon_width(ct); for (i = 0; i < COLLECT_TABLE_MAX_COLUMNS; i++) { GtkTreeViewColumn *column; GtkCellRenderer *cell; GList *list; column = gtk_tree_view_get_column(GTK_TREE_VIEW(ct->listview), i); gtk_tree_view_column_set_visible(column, (i < ct->columns)); gtk_tree_view_column_set_fixed_width(column, thumb_width + (THUMB_BORDER_PADDING * 6)); list = gtk_tree_view_column_get_cell_renderers(column); cell = (list) ? list->data : NULL; g_list_free(list); if (cell && GQV_IS_CELL_RENDERER_ICON(cell)) { g_object_set(G_OBJECT(cell), "fixed_width", thumb_width, "fixed_height", thumb_max_height, "show_text", ct->show_text, NULL); } } if (GTK_WIDGET_REALIZED(ct->listview)) gtk_tree_view_columns_autosize(GTK_TREE_VIEW(ct->listview)); } row = -1; work = ct->cd->list; while (work) { GList *list; GtkTreeIter iter; row++; list = collection_table_add_row(ct, &iter); while (work && list) { list->data = work->data; list = list->next; work = work->next; } } ct->rows = row + 1; collection_table_update_focus(ct); collection_table_update_status(ct);}static void collection_table_populate_at_new_size(CollectTable *ct, gint w, gint h, gint force){ gint new_cols; gint thumb_width; thumb_width = collection_table_get_icon_width(ct); new_cols = w / (thumb_width + (THUMB_BORDER_PADDING * 6)); if (new_cols < 1) new_cols = 1; if (!force && new_cols == ct->columns) return; ct->columns = new_cols; collection_table_populate(ct, TRUE); if (debug) printf("col tab pop cols=%d rows=%d\n", ct->columns, ct->rows);}static void collection_table_sync(CollectTable *ct){ GtkTreeModel *store; GtkTreeIter iter; GList *work; gint r, c; store = gtk_tree_view_get_model(GTK_TREE_VIEW(ct->listview)); r = -1; c = 0; work = ct->cd->list; while (work) { GList *list; r++; c = 0; if (gtk_tree_model_iter_nth_child(store, &iter, NULL, r)) { gtk_tree_model_get(store, &iter, CTABLE_COLUMN_POINTER, &list, -1); gtk_list_store_set(GTK_LIST_STORE(store), &iter, CTABLE_COLUMN_POINTER, list, -1); } else { list = collection_table_add_row(ct, &iter); } while (list) { CollectInfo *info; if (work) { info = work->data; work = work->next; c++; } else { info = NULL; } if (list) { list->data = info; list = list->next; } } } r++; while (gtk_tree_model_iter_nth_child(store, &iter, NULL, r)) { GList *list; gtk_tree_model_get(store, &iter, CTABLE_COLUMN_POINTER, &list, -1); gtk_list_store_remove(GTK_LIST_STORE(store), &iter); g_list_free(list); } ct->rows = r; collection_table_update_focus(ct); collection_table_update_status(ct);}static gint collection_table_sync_idle_cb(gpointer data){ CollectTable *ct = data; if (ct->sync_idle_id == -1) return FALSE; ct->sync_idle_id = -1; collection_table_sync(ct); return FALSE;}static void collection_table_sync_idle(CollectTable *ct){ if (ct->sync_idle_id == -1) { /* high priority, the view needs to be resynced before a redraw * may contain invalid pointers at this time */ ct->sync_idle_id = g_idle_add_full(G_PRIORITY_HIGH, collection_table_sync_idle_cb, ct, NULL); }}void collection_table_add_path_list(CollectTable *ct, GList *list){ GList *work; if (!list) return; work = list; while (work) { collection_add(ct->cd, (gchar *)work->data, FALSE); work = work->next; }}static void collection_table_insert_path_list(CollectTable *ct, GList *list, CollectInfo *insert_info){ GList *work; if (!list) return; work = list; while (work) { collection_insert(ct->cd, (gchar *)work->data, insert_info, FALSE); work = work->next; } collection_table_sync_idle(ct);}static void collection_table_move_by_info_list(CollectTable *ct, GList *info_list, gint row, gint col){ GList *work; GList *insert_pos = NULL; GList *temp; CollectInfo *info; if (!info_list) return; info = collection_table_find_data(ct, row, col, NULL); if (!info_list->next && info_list->data == info) return; if (info) insert_pos = g_list_find(ct->cd->list, info); /* FIXME: this may get slow for large lists */ work = info_list; while (insert_pos && work) { if (insert_pos->data == work->data) { insert_pos = insert_pos->next; work = info_list; } else { work = work->next; } } work = info_list; while (work) { ct->cd->list = g_list_remove(ct->cd->list, work->data); work = work->next; } /* place them back in */ temp = g_list_copy(info_list); if (insert_pos) { ct->cd->list = uig_list_insert_list(ct->cd->list, insert_pos, temp); } else if (info) { ct->cd->list = g_list_concat(temp, ct->cd->list); } else { ct->cd->list = g_list_concat(ct->cd->list, temp); } ct->cd->changed = TRUE; collection_table_sync_idle(ct);}/* *------------------------------------------------------------------- * updating *------------------------------------------------------------------- */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -