This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/editors/space_file/file_ops.c
Andrea Weikert b1cb844e05 2.5 - Start of filebrowser.
- basic drawing of list and thumbnail view (switchable through 'favourits' icon in header)
- selection of files and directories (bookmarks) works with the RMB (right mouse button)
- load operator for files still unstable (no check for correct file type) and incomplete. (WM_operator_free missing)
immediate TODOS:
- fix load file operator
- finish drawing of buttons in header
- drawing of detailed list with all file info.
- finish selection and execute operators (LMB and MMB execute)
later todos:
- parent dir
- keymap for all the shortcuts
- append/link and databrowse
- ...
2009-01-06 14:42:54 +00:00

269 lines
7.8 KiB
C

/**
* $Id:
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2008 Blender Foundation.
* All rights reserved.
*
*
* Contributor(s): Andrea Weikert (c) 2008 Blender Foundation
*
* ***** END GPL LICENSE BLOCK *****
*/
#include "BKE_context.h"
#include "BKE_screen.h"
#include "BKE_global.h"
#include "BLI_blenlib.h"
#include "BLI_storage_types.h"
#ifdef WIN32
#include "BLI_winstuff.h"
#endif
#include "DNA_space_types.h"
#include "DNA_userdef_types.h"
#include "ED_space_api.h"
#include "ED_screen.h"
#include "ED_fileselect.h"
#include "WM_api.h"
#include "WM_types.h"
#include "file_intern.h"
#include "filelist.h"
#include "fsmenu.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/* for events */
#define NOTACTIVE 0
#define ACTIVATE 1
#define INACTIVATE 2
static void set_active_file_thumbs(SpaceFile *sfile, FileSelectParams* params, struct ARegion* ar, short mval[])
{
float x,y;
int active_file = -1;
int stridex, stridey;
struct direntry* file;
int offsetx, offsety;
int numfiles = filelist_numfiles(params->files);
int columns;
View2D* v2d = &ar->v2d;
UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y);
offsetx = (x - (v2d->cur.xmin+sfile->tile_border_x))/(sfile->tile_w + sfile->tile_border_x);
offsety = (-y+sfile->tile_border_y)/(sfile->tile_h + sfile->tile_border_y);
columns = (v2d->cur.xmax - v2d->cur.xmin) / (sfile->tile_w+ sfile->tile_border_x);
printf("tile (%d, %d, %d)\n", offsetx, offsety, columns);
active_file = offsetx + columns*offsety;
if (active_file >= 0 && active_file < numfiles )
{
printf("active file: %d\n", active_file);
params->active_file = active_file;
if (params->selstate & ACTIVATE) {
file = filelist_file(params->files, params->active_file);
printf("active file: %s\n", file->relname);
file->flags |= ACTIVE;
}
}
}
static void set_active_file(SpaceFile *sfile, FileSelectParams* params, struct ARegion* ar, short mval[])
{
int offsetx, offsety;
float x,y;
int active_file = -1;
int numfiles = filelist_numfiles(params->files);
int rows;
struct direntry* file;
View2D* v2d = &ar->v2d;
UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y);
offsetx = (x-sfile->tile_border_x)/(sfile->tile_w + sfile->tile_border_x);
offsety = (v2d->cur.ymax-y-sfile->tile_border_y)/(sfile->tile_h + sfile->tile_border_y);
rows = (v2d->cur.ymax - v2d->cur.ymin - 2*sfile->tile_border_y) / (sfile->tile_h+sfile->tile_border_y);
active_file = rows*offsetx + offsety;
printf("offsets (%d, %d)\n", offsetx, offsety);
printf("active_file (%d)\n", active_file);
if ( (active_file >= 0) && (active_file < numfiles) )
{
params->active_file = active_file;
if (params->selstate & ACTIVATE) {
file = filelist_file(params->files, params->active_file);
file->flags |= ACTIVE;
}
}
}
static void set_active_bookmark(SpaceFile *sfile, FileSelectParams* params, struct ARegion* ar, short y)
{
int nentries = fsmenu_get_nentries();
short posy = ar->v2d.mask.ymax - TILE_BORDER_Y - y;
params->active_bookmark = ((float)posy / (U.fontsize*3.0f/2.0f));
printf("active bookmark: %d\n", params->active_bookmark);
if (params->active_bookmark < 0 || params->active_bookmark > nentries) {
params->active_bookmark = -1;
}
}
static void mouse_select(SpaceFile* sfile, FileSelectParams* params, ARegion* ar, short *mval)
{
int numfiles = filelist_numfiles(params->files);
if(mval[0]>ar->v2d.mask.xmin && mval[0]<ar->v2d.mask.xmax
&& mval[1]>ar->v2d.mask.ymin && mval[1]<ar->v2d.mask.ymax) {
params->selstate = NOTACTIVE;
if (params->display) {
set_active_file_thumbs(sfile, params, ar, mval);
} else {
set_active_file(sfile, params, ar, mval);
}
if (params->active_file >= 0 && params->active_file < numfiles) {
struct direntry* file = filelist_file(params->files, params->active_file);
if(file && S_ISDIR(file->type)) {
/* the path is too long and we are not going up! */
if (strcmp(file->relname, ".") &&
strcmp(file->relname, "..") &&
strlen(params->dir) + strlen(file->relname) >= FILE_MAX )
{
// XXX error("Path too long, cannot enter this directory");
} else {
if (strcmp(file->relname, "..")==0) {
/* avoids /../../ */
BLI_parent_dir(params->dir);
} else {
strcat(params->dir, file->relname);
strcat(params->dir,"/");
params->file[0] = '\0';
BLI_cleanup_dir(G.sce, params->dir);
}
filelist_setdir(params->files, params->dir);
filelist_free(params->files);
params->active_file = -1;
}
}
else if (file)
{
if (file->relname) {
BLI_strncpy(params->file, file->relname, FILE_MAXFILE);
/* XXX
if(event==MIDDLEMOUSE && filelist_gettype(sfile->files))
imasel_execute(sfile);
*/
}
}
/* XXX
if(BIF_filelist_gettype(sfile->files)==FILE_MAIN) {
active_imasel_object(sfile);
}
*/
}
}
}
static void mouse_select_bookmark(SpaceFile* sfile, ARegion* ar, short *mval)
{
if(mval[0]>ar->v2d.mask.xmin && mval[0]<ar->v2d.mask.xmax
&& mval[1]>ar->v2d.mask.ymin && mval[1]<ar->v2d.mask.ymax) {
int nentries = fsmenu_get_nentries();
char *selected;
printf("selecting...\n");
set_active_bookmark(sfile, sfile->params, ar, mval[1]);
selected= fsmenu_get_entry(sfile->params->active_bookmark);
/* which string */
if (selected) {
FileSelectParams* params = sfile->params;
BLI_strncpy(params->dir, selected, sizeof(params->dir));
BLI_cleanup_dir(G.sce, params->dir);
filelist_free(params->files);
filelist_setdir(params->files, params->dir);
params->file[0] = '\0';
params->active_file = -1;
}
}
}
static int file_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
ScrArea *sa= CTX_wm_area(C);
ARegion *ar= CTX_wm_region(C);
SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
short mval[2];
/* note; otherwise opengl select won't work. do this for every glSelectBuffer() */
wmSubWindowSet(CTX_wm_window(C), ar->swinid);
mval[0]= event->x - ar->winrct.xmin;
mval[1]= event->y - ar->winrct.ymin;
mouse_select(sfile, sfile->params, ar, mval);
WM_event_add_notifier(C, NC_WINDOW, 0, NULL);
return OPERATOR_FINISHED;
}
void ED_FILE_OT_select(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Activate/Select File";
ot->idname= "ED_FILE_OT_select";
/* api callbacks */
ot->invoke= file_select_invoke;
ot->poll= ED_operator_file_active;
}
static int bookmark_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
ScrArea *sa= CTX_wm_area(C);
ARegion *ar= CTX_wm_region(C);
SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
short mval[2];
/* note; otherwise opengl select won't work. do this for every glSelectBuffer() */
wmSubWindowSet(CTX_wm_window(C), ar->swinid);
mval[0]= event->x - ar->winrct.xmin;
mval[1]= event->y - ar->winrct.ymin;
mouse_select_bookmark(sfile, ar, mval);
ED_area_tag_redraw(sa);
return OPERATOR_FINISHED;
}
void ED_FILE_OT_select_bookmark(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Select Directory";
ot->idname= "ED_FILE_OT_select_bookmark";
/* api callbacks */
ot->invoke= bookmark_select_invoke;
ot->poll= ED_operator_file_active;
}