📄 view_file_icon.c
字号:
ViewFileIcon *vfi = data; vficon_selection_remove(vfi, vfi->click_fd, SELECTION_PRELIGHT, NULL); if (context->action == GDK_ACTION_MOVE) { vficon_refresh(vfi); } tip_unschedule(vfi);}static void vficon_dnd_init(ViewFileIcon *vfi){ gtk_drag_source_set(vfi->listview, GDK_BUTTON1_MASK | GDK_BUTTON2_MASK, dnd_file_drag_types, dnd_file_drag_types_count, GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK); g_signal_connect(G_OBJECT(vfi->listview), "drag_data_get", G_CALLBACK(vficon_dnd_get), vfi); g_signal_connect(G_OBJECT(vfi->listview), "drag_begin", G_CALLBACK(vficon_dnd_begin), vfi); g_signal_connect(G_OBJECT(vfi->listview), "drag_end", G_CALLBACK(vficon_dnd_end), vfi);}/* *------------------------------------------------------------------- * cell updates *------------------------------------------------------------------- */static void vficon_selection_set(ViewFileIcon *vfi, FileData *fd, SelectionType value, GtkTreeIter *iter){ IconData *id; GtkTreeModel *store; GList *list; if (!fd) return; id = ICON_DATA(fd); if (id->selected == value) return; id->selected = value; store = gtk_tree_view_get_model(GTK_TREE_VIEW(vfi->listview)); if (iter) { gtk_tree_model_get(store, iter, FILE_COLUMN_POINTER, &list, -1); if (list) gtk_list_store_set(GTK_LIST_STORE(store), iter, FILE_COLUMN_POINTER, list, -1); } else { GtkTreeIter row; if (vficon_find_iter(vfi, fd, &row, NULL)) { gtk_tree_model_get(store, &row, FILE_COLUMN_POINTER, &list, -1); if (list) gtk_list_store_set(GTK_LIST_STORE(store), &row, FILE_COLUMN_POINTER, list, -1); } }}static void vficon_selection_add(ViewFileIcon *vfi, FileData *fd, SelectionType mask, GtkTreeIter *iter){ if (!fd) return; vficon_selection_set(vfi, fd, ICON_DATA(fd)->selected | mask, iter);}static void vficon_selection_remove(ViewFileIcon *vfi, FileData *fd, SelectionType mask, GtkTreeIter *iter){ if (!fd) return; vficon_selection_set(vfi, fd, ICON_DATA(fd)->selected & ~mask, iter);}/* *------------------------------------------------------------------- * selections *------------------------------------------------------------------- */static void vficon_verify_selections(ViewFileIcon *vfi){ GList *work; work = vfi->selection; while (work) { FileData *fd = work->data; work = work->next; if (!g_list_find(vfi->list, fd)) { vfi->selection = g_list_remove(vfi->selection, fd); } }}void vficon_select_all(ViewFileIcon *vfi){ GList *work; g_list_free(vfi->selection); vfi->selection = NULL; work = vfi->list; while (work) { vfi->selection = g_list_append(vfi->selection, work->data); vficon_selection_add(vfi, work->data, SELECTION_SELECTED, NULL); work = work->next; } vficon_send_update(vfi);}void vficon_select_none(ViewFileIcon *vfi){ GList *work; work = vfi->selection; while (work) { vficon_selection_remove(vfi, work->data, SELECTION_SELECTED, NULL); work = work->next; } g_list_free(vfi->selection); vfi->selection = NULL; vficon_send_update(vfi);}static void vficon_select(ViewFileIcon *vfi, FileData *fd){ vfi->prev_selection = fd; if (!fd || ICON_DATA(fd)->selected & SELECTION_SELECTED) return; vfi->selection = g_list_append(vfi->selection, fd); vficon_selection_add(vfi, fd, SELECTION_SELECTED, NULL); vficon_send_update(vfi);}static void vficon_unselect(ViewFileIcon *vfi, FileData *fd){ vfi->prev_selection = fd; if (!fd || !(ICON_DATA(fd)->selected & SELECTION_SELECTED) ) return; vfi->selection = g_list_remove(vfi->selection, fd); vficon_selection_remove(vfi, fd, SELECTION_SELECTED, NULL); vficon_send_update(vfi);}static void vficon_select_util(ViewFileIcon *vfi, FileData *fd, gint select){ if (select) { vficon_select(vfi, fd); } else { vficon_unselect(vfi, fd); }}static void vficon_select_region_util(ViewFileIcon *vfi, FileData *start, FileData *end, gint select){ gint row1, col1; gint row2, col2; gint t; gint i, j; if (!vficon_find_position(vfi, start, &row1, &col1) || !vficon_find_position(vfi, end, &row2, &col2) ) return; vfi->prev_selection = end; if (!collection_rectangular_selection) { GList *work; FileData *fd; if (g_list_index(vfi->list, start) > g_list_index(vfi->list, end)) { fd = start; start = end; end = fd; } work = g_list_find(vfi->list, start); while (work) { fd = work->data; vficon_select_util(vfi, fd, select); if (work->data != end) work = work->next; else work = NULL; } return; } if (row2 < row1) { t = row1; row1 = row2; row2 = t; } if (col2 < col1) { t = col1; col1 = col2; col2 = t; } if (debug) printf("table: %d x %d to %d x %d\n", row1, col1, row2, col2); for (i = row1; i <= row2; i++) { for (j = col1; j <= col2; j++) { FileData *fd = vficon_find_data(vfi, i, j, NULL); if (fd) vficon_select_util(vfi, fd, select); } }}gint vficon_index_is_selected(ViewFileIcon *vfi, gint row){ FileData *fd = g_list_nth_data(vfi->list, row); if (!fd) return FALSE; return (ICON_DATA(fd)->selected & SELECTION_SELECTED);}gint vficon_selection_count(ViewFileIcon *vfi, gint64 *bytes){ if (bytes) { gint64 b = 0; GList *work; work = vfi->selection; while (work) { FileData *fd = work->data; b += fd->size; work = work->next; } *bytes = b; } return g_list_length(vfi->selection);}GList *vficon_selection_get_list(ViewFileIcon *vfi){ GList *list = NULL; GList *work; work = vfi->selection; while (work) { FileData *fd = work->data; list = g_list_prepend(list, g_strdup(fd->path)); work = work->next; } list = g_list_reverse(list); return list;}GList *vficon_selection_get_list_by_index(ViewFileIcon *vfi){ GList *list = NULL; GList *work; work = vfi->selection; while (work) { list = g_list_prepend(list, GINT_TO_POINTER(g_list_index(vfi->list, work->data))); work = work->next; } return g_list_reverse(list);}void vficon_select_by_path(ViewFileIcon *vfi, const gchar *path){ FileData *fd; GList *work; if (!path) return; fd = NULL; work = vfi->list; while (work && !fd) { FileData *chk = work->data; work = work->next; if (strcmp(chk->path, path) == 0) fd = chk; } if (!fd) return; if (!(ICON_DATA(fd)->selected & SELECTION_SELECTED)) { vficon_select_none(vfi); vficon_select(vfi, fd); } vficon_set_focus(vfi, fd);}/* *------------------------------------------------------------------- * focus *------------------------------------------------------------------- */static void vficon_move_focus(ViewFileIcon *vfi, gint row, gint col, gint relative){ gint new_row; gint new_col; if (relative) { new_row = vfi->focus_row; new_col = vfi->focus_column; new_row += row; if (new_row < 0) new_row = 0; if (new_row >= vfi->rows) new_row = vfi->rows - 1; while(col != 0) { if (col < 0) { new_col--; col++; } else { new_col++; col--; } if (new_col < 0) { if (new_row > 0) { new_row--; new_col = vfi->columns - 1; } else { new_col = 0; } } if (new_col >= vfi->columns) { if (new_row < vfi->rows - 1) { new_row++; new_col = 0; } else { new_col = vfi->columns - 1; } } } } else { new_row = row; new_col = col; if (new_row >= vfi->rows) { if (vfi->rows > 0) new_row = vfi->rows - 1; else new_row = 0; new_col = vfi->columns - 1; } if (new_col >= vfi->columns) new_col = vfi->columns - 1; } if (new_row == vfi->rows - 1) { gint l; /* if we moved beyond the last image, go to the last image */ l = g_list_length(vfi->list); if (vfi->rows > 1) l -= (vfi->rows - 1) * vfi->columns; if (new_col >= l) new_col = l - 1; } vficon_set_focus(vfi, vficon_find_data(vfi, new_row, new_col, NULL));}static void vficon_set_focus(ViewFileIcon *vfi, FileData *fd){ GtkTreeIter iter; gint row, col; if (g_list_find(vfi->list, vfi->focus_fd)) { if (fd == vfi->focus_fd) { /* ensure focus row col are correct */ vficon_find_position(vfi, vfi->focus_fd, &vfi->focus_row, &vfi->focus_column); return; } vficon_selection_remove(vfi, vfi->focus_fd, SELECTION_FOCUS, NULL); } if (!vficon_find_position(vfi, fd, &row, &col)) { vfi->focus_fd = NULL; vfi->focus_row = -1; vfi->focus_column = -1; return; } vfi->focus_fd = fd; vfi->focus_row = row; vfi->focus_column = col; vficon_selection_add(vfi, vfi->focus_fd, SELECTION_FOCUS, NULL); if (vficon_find_iter(vfi, vfi->focus_fd, &iter, NULL)) { GtkTreePath *tpath; GtkTreeViewColumn *column; GtkTreeModel *store; tree_view_row_make_visible(GTK_TREE_VIEW(vfi->listview), &iter, FALSE); store = gtk_tree_view_get_model(GTK_TREE_VIEW(vfi->listview)); tpath = gtk_tree_model_get_path(store, &iter); /* focus is set to an extra column with 0 width to hide focus, we draw it ourself */ column = gtk_tree_view_get_column(GTK_TREE_VIEW(vfi->listview), VFICON_MAX_COLUMNS); gtk_tree_view_set_cursor(GTK_TREE_VIEW(vfi->listview), tpath, column, FALSE); gtk_tree_path_free(tpath); }}static void vficon_update_focus(ViewFileIcon *vfi){ gint new_row = 0; gint new_col = 0; if (vfi->focus_fd && vficon_find_position(vfi, vfi->focus_fd, &new_row, &new_col)) { /* first find the old focus, if it exists and is valid */ } else { /* (try to) stay where we were */ new_row = vfi->focus_row; new_col = vfi->focus_column; } vficon_move_focus(vfi, new_row, new_col, FALSE);}/* used to figure the page up/down distances */static gint page_height(ViewFileIcon *vfi){ GtkAdjustment *adj; gint page_size; gint row_height; gint ret; adj = gtk_tree_view_get_vadjustment(GTK_TREE_VIEW(vfi->listview)); page_size = (gint)adj->page_increment; row_height = thumb_max_height + THUMB_BORDER_PADDING * 2; if (vfi->show_text) row_height += thumb_max_height / 3; ret = page_size / row_height; if (ret < 1) ret = 1; return ret;}/* *------------------------------------------------------------------- * keyboard *------------------------------------------------------------------- */static void vfi_menu_position_cb(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer data){ ViewFileIcon *vfi = data; GtkTreeModel *store; GtkTreeIter iter; gint column; GtkTreePath *tpath; gint cw, ch; if (!vficon_find_iter(vfi, vfi->click_fd, &iter, &column)) return; store = gtk_tree_view_get_model(GTK_TREE_VIEW(vfi->listview)); tpath = gtk_tree_model_get_path(store, &iter); tree_view_get_cell_clamped(GTK_TREE_VIEW(vfi->listview), tpath, column, FALSE, x, y, &cw, &ch); gtk_tree_path_free(tpath); *y += ch; popup_menu_position_clamp(menu, x, y, 0);}static gint vficon_press_key_cb(GtkWidget *widget, GdkEventKey *event, gpointer data){ ViewFileIcon *vfi = data; gint stop_signal = FALSE; gint focus_row = 0; gint focus_col = 0; FileData *fd; switch (event->keyval) { case GDK_Left: case GDK_KP_Left: focus_col = -1; stop_signal = TRUE; break; case GDK_Right: case GDK_KP_Right: focus_col = 1; stop_signal = TRUE; break; case GDK_Up: case GDK_KP_Up: focus_row = -1; stop_signal = TRUE; break; case GDK_Down: case GDK_KP_Down: focus_row = 1; stop_signal = TRUE; break; case GDK_Page_Up: case GDK_KP_Page_Up: focus_row = -page_height(vfi); stop_signal = TRUE; break; case GDK_Page_Down: case GDK_KP_Page_Down: focus_row = page_height(vfi); stop_signal = TRUE; break; case GDK_Home: case GDK_KP_Home: focus_row = -vfi->focus_row; focus_col = -vfi->focus_column; stop_signal = TRUE; break; case GDK_End: case GDK_KP_End: focus_row = vfi->rows - 1 - vfi->focus_row; focus_col = vfi->columns - 1 - vfi->focus_column; stop_signal = TRUE; break; case GDK_space: fd = vficon_find_data(vfi, vfi->focus_row, vfi->focus_column, NULL); if (fd) { vfi->click_fd = fd; if (event->state & GDK_CONTROL_MASK) { gint selected; selected = ICON_DATA(fd)->selected & SELECTION_SELECTED; if (selected) { vficon_unselect(vfi, fd); } else { vficon_select(vfi, fd); vficon_send_layout_select(vfi, fd); } } else { vficon_select_none(vfi); vficon_select(vfi, fd); vficon_send_layout_select(vfi, fd); } } stop_signal = TRUE; break; case GDK_Menu: fd = vficon_find_data(vfi, vfi->focus_row, vfi->focus_column, NULL); vfi->click_fd = fd; vficon_selection_add(vfi, vfi->click_fd, SELECTION_PRELIGHT, NULL); tip_unschedule(vfi); vfi->popup = vficon_pop_menu(vfi, (fd != NULL)); gtk_menu_popup(GTK_MENU(vfi->popup), NULL, NULL, vfi_menu_position_cb, vfi, 0, GDK_CURRENT_TIME); stop_signal = TRUE; break; default: break; } if (focus_row != 0 || focus_col != 0) { FileData *new_fd; FileData *old_fd; old_fd = vficon_find_data(vfi, vfi->focus_row, vfi->focus_column, NULL); vficon_move_focus(vfi, focus_row, focus_col, TRUE); new_fd = vficon_find_data(vfi, vfi->focus_row, vfi->focus_column, NULL); if (new_fd != old_fd) { if (event->state & GDK_SHIFT_MASK) { if (!collection_rectangular_selection) { vficon_select_region_util(vfi, old_fd, new_fd, FALSE); } else { vficon_select_region_util(vfi, vfi->click_fd, old_fd, FALSE); } vficon_select_region_util(vfi, vfi->click_fd, new_fd, TRUE); vficon_send_layout_select(vfi, new_fd); } else if (event->state & GDK_CONTROL_MASK) { vfi->click_fd = new_fd; } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -