2002-10-12 11:37:38 +00:00
|
|
|
/**
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
|
|
|
* Foundation also sells licenses for use in proprietary software under
|
|
|
|
* the Blender License. See http://www.blender.org/BL/ for information
|
|
|
|
* about this.
|
|
|
|
*
|
|
|
|
* 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) 2001-2002 by NaN Holding BV.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* The Original Code is: all of this file.
|
|
|
|
*
|
|
|
|
* Contributor(s): none yet.
|
|
|
|
*
|
|
|
|
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <math.h>
|
|
|
|
|
2002-11-25 12:02:15 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include <config.h>
|
|
|
|
#endif
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
#ifdef WIN32
|
|
|
|
#include <io.h>
|
|
|
|
#include <direct.h>
|
|
|
|
#include "BLI_winstuff.h"
|
|
|
|
#else
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/times.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
|
|
#include "BMF_Api.h"
|
|
|
|
|
|
|
|
#include "BLI_blenlib.h"
|
|
|
|
#include "BLI_arithb.h"
|
|
|
|
#include "BLI_linklist.h"
|
|
|
|
#include "BLI_storage_types.h"
|
|
|
|
#include "BLI_dynstr.h"
|
|
|
|
|
|
|
|
#include "IMB_imbuf.h"
|
|
|
|
|
|
|
|
#include "DNA_curve_types.h"
|
|
|
|
#include "DNA_image_types.h"
|
|
|
|
#include "DNA_ipo_types.h"
|
|
|
|
#include "DNA_vfont_types.h"
|
Biiig commit! Thanks to 2-3 weeks of cvs freeze...
Render:
- New; support for dual CPU render (SDL thread)
Currently only works with alternating scanlines, but gives excellent
performance. For both normal render as unified implemented.
Note the "mutex" locks on z-transp buffer render and imbuf loads.
- This has been made possible by major cleanups in render code, especially
getting rid of globals (example Tin Tr Tg Tb Ta for textures) or struct
OSA or using Materials or Texture data to write to.
- Made normal render fully 4x32 floats too, and removed all old optimizes
with chars or shorts.
- Made normal render and unified render use same code for sky and halo
render, giving equal (and better) results for halo render. Old render
now also uses PostProcess options (brightness, mul, gamma)
- Added option ("FBuf") in F10 Output Panel, this keeps a 4x32 bits buffer
after render. Using PostProcess menu you will note an immediate re-
display of image too (32 bits RGBA)
- Added "Hue" and "Saturation" sliders to PostProcess options
- Render module is still not having a "nice" API, but amount of dependencies
went down a lot. Next todo: remove abusive "previewrender" code.
The last main global in Render (struct Render) now can be re-used for fully
controlling a render, to allow multiple "instances" of render to open.
- Renderwindow now displays a smal bar on top with the stats, and keeps the
stats after render too. Including "spare" page support.
Not only easier visible that way, but also to remove the awkward code that
was drawing stats in the Info header (extreme slow on some ATIs too)
- Cleaned up blendef.h and BKE_utildefines.h, these two had overlapping
defines.
- I might have forgotten stuff... and will write a nice doc on the architecture!
2004-12-27 19:28:52 +00:00
|
|
|
#include "DNA_material_types.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "DNA_mesh_types.h"
|
|
|
|
#include "DNA_object_types.h"
|
|
|
|
#include "DNA_texture_types.h"
|
|
|
|
#include "DNA_space_types.h"
|
|
|
|
#include "DNA_scene_types.h"
|
|
|
|
#include "DNA_screen_types.h"
|
|
|
|
#include "DNA_view3d_types.h"
|
|
|
|
#include "DNA_userdef_types.h"
|
|
|
|
|
|
|
|
#include "BKE_utildefines.h"
|
|
|
|
#include "BKE_global.h"
|
|
|
|
#include "BKE_main.h"
|
|
|
|
#include "BKE_library.h"
|
|
|
|
#include "BKE_curve.h"
|
|
|
|
#include "BKE_font.h"
|
|
|
|
#include "BKE_material.h"
|
|
|
|
|
|
|
|
#include "BIF_gl.h"
|
|
|
|
#include "BIF_interface.h"
|
|
|
|
#include "BIF_toolbox.h"
|
|
|
|
#include "BIF_mywindow.h"
|
|
|
|
#include "BIF_editview.h"
|
|
|
|
#include "BIF_space.h"
|
|
|
|
#include "BIF_screen.h"
|
2003-10-04 20:35:50 +00:00
|
|
|
#include "BIF_resources.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
#include "BLO_readfile.h"
|
|
|
|
|
|
|
|
#include "BDR_editcurve.h"
|
2004-01-21 04:38:03 +00:00
|
|
|
#include "BPI_script.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "BSE_filesel.h"
|
|
|
|
#include "BSE_view.h"
|
|
|
|
|
|
|
|
#include "mydevice.h"
|
|
|
|
#include "blendef.h"
|
|
|
|
#include "nla.h"
|
|
|
|
|
2005-03-09 19:45:59 +00:00
|
|
|
#include "BIF_fsmenu.h" /* include ourselves */
|
2003-10-04 20:35:50 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
#if defined WIN32 || defined __BeOS
|
|
|
|
int fnmatch(){return 0;}
|
|
|
|
#else
|
|
|
|
#include <fnmatch.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef WIN32
|
|
|
|
#include <sys/param.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define FILESELHEAD 60
|
|
|
|
#define FILESEL_DY 16
|
|
|
|
|
2004-05-29 16:17:46 +00:00
|
|
|
/* for events */
|
2002-10-12 11:37:38 +00:00
|
|
|
#define NOTACTIVE 0
|
|
|
|
#define ACTIVATE 1
|
|
|
|
#define INACTIVATE 2
|
2004-05-29 16:17:46 +00:00
|
|
|
/* for state of file */
|
|
|
|
#define ACTIVE 2
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
#define STARTSWITH(x, y) (strncmp(x, y, sizeof(x) - 1) == 0)
|
|
|
|
|
|
|
|
static int is_a_library(SpaceFile *sfile, char *dir, char *group);
|
|
|
|
static void do_library_append(SpaceFile *sfile);
|
|
|
|
static void library_to_filelist(SpaceFile *sfile);
|
|
|
|
static void filesel_select_objects(struct SpaceFile *sfile);
|
|
|
|
static void active_file_object(struct SpaceFile *sfile);
|
|
|
|
static int groupname_to_code(char *group);
|
|
|
|
|
2005-03-09 19:45:59 +00:00
|
|
|
extern void countall(void);
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
/* local globals */
|
|
|
|
|
|
|
|
static rcti scrollrct, textrct, bar;
|
|
|
|
static int filebuty1, filebuty2, page_ofs, collumwidth, selecting=0;
|
|
|
|
static int filetoname= 0;
|
|
|
|
static float pixels_to_ofs;
|
|
|
|
static char otherdir[FILE_MAXDIR];
|
|
|
|
static ScrArea *otherarea;
|
|
|
|
|
|
|
|
/* FSMENU HANDLING */
|
|
|
|
|
|
|
|
/* FSMenuEntry's without paths indicate seperators */
|
|
|
|
typedef struct _FSMenuEntry FSMenuEntry;
|
|
|
|
struct _FSMenuEntry {
|
|
|
|
FSMenuEntry *next;
|
|
|
|
|
|
|
|
char *path;
|
|
|
|
};
|
|
|
|
|
2003-03-25 17:43:08 +00:00
|
|
|
static FSMenuEntry *fsmenu= 0;
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
int fsmenu_get_nentries(void)
|
|
|
|
{
|
|
|
|
FSMenuEntry *fsme;
|
|
|
|
int count= 0;
|
|
|
|
|
|
|
|
for (fsme= fsmenu; fsme; fsme= fsme->next)
|
|
|
|
count++;
|
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
int fsmenu_is_entry_a_seperator(int idx)
|
|
|
|
{
|
|
|
|
FSMenuEntry *fsme;
|
|
|
|
|
|
|
|
for (fsme= fsmenu; fsme && idx; fsme= fsme->next)
|
|
|
|
idx--;
|
|
|
|
|
|
|
|
return (fsme && !fsme->path)?1:0;
|
|
|
|
}
|
|
|
|
char *fsmenu_get_entry(int idx)
|
|
|
|
{
|
|
|
|
FSMenuEntry *fsme;
|
|
|
|
|
|
|
|
for (fsme= fsmenu; fsme && idx; fsme= fsme->next)
|
|
|
|
idx--;
|
|
|
|
|
|
|
|
return fsme?fsme->path:NULL;
|
|
|
|
}
|
|
|
|
char *fsmenu_build_menu(void)
|
|
|
|
{
|
|
|
|
DynStr *ds= BLI_dynstr_new();
|
|
|
|
FSMenuEntry *fsme;
|
|
|
|
char *menustr;
|
|
|
|
|
|
|
|
for (fsme= fsmenu; fsme; fsme= fsme->next) {
|
|
|
|
if (!fsme->path) {
|
2003-03-25 17:43:08 +00:00
|
|
|
/* clean consecutive seperators and ignore trailing ones */
|
|
|
|
if (fsme->next) {
|
|
|
|
if (fsme->next->path) {
|
|
|
|
BLI_dynstr_append(ds, "%l|");
|
|
|
|
} else {
|
|
|
|
FSMenuEntry *next= fsme->next;
|
|
|
|
fsme->next= next->next;
|
|
|
|
MEM_freeN(next);
|
|
|
|
}
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
} else {
|
|
|
|
BLI_dynstr_append(ds, fsme->path);
|
|
|
|
if (fsme->next) BLI_dynstr_append(ds, "|");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
menustr= BLI_dynstr_get_cstring(ds);
|
|
|
|
BLI_dynstr_free(ds);
|
|
|
|
return menustr;
|
|
|
|
}
|
2003-03-25 17:43:08 +00:00
|
|
|
static FSMenuEntry *fsmenu_get_last_separator(void)
|
|
|
|
{
|
|
|
|
FSMenuEntry *fsme, *lsep=NULL;
|
|
|
|
|
|
|
|
for (fsme= fsmenu; fsme; fsme= fsme->next)
|
|
|
|
if (!fsme->path)
|
|
|
|
lsep= fsme;
|
|
|
|
|
|
|
|
return lsep;
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
void fsmenu_insert_entry(char *path, int sorted)
|
|
|
|
{
|
2003-03-25 17:43:08 +00:00
|
|
|
FSMenuEntry *prev= fsmenu_get_last_separator();
|
|
|
|
FSMenuEntry *fsme= prev?prev->next:fsmenu;
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
for (; fsme; prev= fsme, fsme= fsme->next) {
|
|
|
|
if (fsme->path) {
|
|
|
|
if (BLI_streq(path, fsme->path)) {
|
|
|
|
return;
|
|
|
|
} else if (sorted && strcmp(path, fsme->path)<0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fsme= MEM_mallocN(sizeof(*fsme), "fsme");
|
|
|
|
fsme->path= BLI_strdup(path);
|
|
|
|
|
|
|
|
if (prev) {
|
|
|
|
fsme->next= prev->next;
|
|
|
|
prev->next= fsme;
|
|
|
|
} else {
|
|
|
|
fsme->next= fsmenu;
|
|
|
|
fsmenu= fsme;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void fsmenu_append_seperator(void)
|
|
|
|
{
|
|
|
|
if (fsmenu) {
|
|
|
|
FSMenuEntry *fsme= fsmenu;
|
|
|
|
|
|
|
|
while (fsme->next) fsme= fsme->next;
|
|
|
|
|
2003-03-25 17:43:08 +00:00
|
|
|
fsme->next= MEM_mallocN(sizeof(*fsme), "fsme");
|
|
|
|
fsme->next->next= NULL;
|
|
|
|
fsme->next->path= NULL;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
void fsmenu_remove_entry(int idx)
|
|
|
|
{
|
|
|
|
FSMenuEntry *prev= NULL, *fsme= fsmenu;
|
|
|
|
|
|
|
|
for (fsme= fsmenu; fsme && idx; prev= fsme, fsme= fsme->next)
|
|
|
|
if (fsme->path)
|
|
|
|
idx--;
|
|
|
|
|
|
|
|
if (fsme) {
|
|
|
|
if (prev) {
|
|
|
|
prev->next= fsme->next;
|
|
|
|
} else {
|
|
|
|
fsmenu= fsme->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
MEM_freeN(fsme->path);
|
|
|
|
MEM_freeN(fsme);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void fsmenu_free(void)
|
|
|
|
{
|
|
|
|
FSMenuEntry *fsme= fsmenu;
|
|
|
|
|
|
|
|
while (fsme) {
|
|
|
|
FSMenuEntry *n= fsme->next;
|
|
|
|
|
|
|
|
if (fsme->path) MEM_freeN(fsme->path);
|
|
|
|
MEM_freeN(fsme);
|
|
|
|
|
|
|
|
fsme= n;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ******************* SORT ******************* */
|
|
|
|
|
|
|
|
static int compare_name(const void *a1, const void *a2)
|
|
|
|
{
|
|
|
|
const struct direntry *entry1=a1, *entry2=a2;
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* type is is equal to stat.st_mode */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
if (S_ISDIR(entry1->type)){
|
|
|
|
if (S_ISDIR(entry2->type)==0) return (-1);
|
|
|
|
} else{
|
|
|
|
if (S_ISDIR(entry2->type)) return (1);
|
|
|
|
}
|
|
|
|
if (S_ISREG(entry1->type)){
|
|
|
|
if (S_ISREG(entry2->type)==0) return (-1);
|
|
|
|
} else{
|
|
|
|
if (S_ISREG(entry2->type)) return (1);
|
|
|
|
}
|
|
|
|
if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1);
|
|
|
|
if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1);
|
2005-01-03 14:17:33 +00:00
|
|
|
|
|
|
|
/* make sure "." and ".." are always first */
|
|
|
|
if( strcmp(entry1->relname, ".")==0 ) return (-1);
|
|
|
|
if( strcmp(entry2->relname, ".")==0 ) return (1);
|
|
|
|
if( strcmp(entry1->relname, "..")==0 ) return (-1);
|
|
|
|
|
2005-04-02 15:36:57 +00:00
|
|
|
return (BLI_strcasecmp(entry1->relname,entry2->relname));
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int compare_date(const void *a1, const void *a2)
|
|
|
|
{
|
|
|
|
const struct direntry *entry1=a1, *entry2=a2;
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* type is equal to stat.st_mode */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
if (S_ISDIR(entry1->type)){
|
|
|
|
if (S_ISDIR(entry2->type)==0) return (-1);
|
|
|
|
} else{
|
|
|
|
if (S_ISDIR(entry2->type)) return (1);
|
|
|
|
}
|
|
|
|
if (S_ISREG(entry1->type)){
|
|
|
|
if (S_ISREG(entry2->type)==0) return (-1);
|
|
|
|
} else{
|
|
|
|
if (S_ISREG(entry2->type)) return (1);
|
|
|
|
}
|
|
|
|
if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1);
|
|
|
|
if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1);
|
|
|
|
|
2005-01-03 14:17:33 +00:00
|
|
|
/* make sure "." and ".." are always first */
|
|
|
|
if( strcmp(entry1->relname, ".")==0 ) return (-1);
|
|
|
|
if( strcmp(entry2->relname, ".")==0 ) return (1);
|
|
|
|
if( strcmp(entry1->relname, "..")==0 ) return (-1);
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if ( entry1->s.st_mtime < entry2->s.st_mtime) return 1;
|
|
|
|
if ( entry1->s.st_mtime > entry2->s.st_mtime) return -1;
|
2005-01-03 14:17:33 +00:00
|
|
|
|
2005-04-02 15:36:57 +00:00
|
|
|
else return BLI_strcasecmp(entry1->relname,entry2->relname);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int compare_size(const void *a1, const void *a2)
|
|
|
|
{
|
|
|
|
const struct direntry *entry1=a1, *entry2=a2;
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* type is equal to stat.st_mode */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
if (S_ISDIR(entry1->type)){
|
|
|
|
if (S_ISDIR(entry2->type)==0) return (-1);
|
|
|
|
} else{
|
|
|
|
if (S_ISDIR(entry2->type)) return (1);
|
|
|
|
}
|
|
|
|
if (S_ISREG(entry1->type)){
|
|
|
|
if (S_ISREG(entry2->type)==0) return (-1);
|
|
|
|
} else{
|
|
|
|
if (S_ISREG(entry2->type)) return (1);
|
|
|
|
}
|
|
|
|
if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1);
|
|
|
|
if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1);
|
|
|
|
|
2005-01-03 14:17:33 +00:00
|
|
|
/* make sure "." and ".." are always first */
|
|
|
|
if( strcmp(entry1->relname, ".")==0 ) return (-1);
|
|
|
|
if( strcmp(entry2->relname, ".")==0 ) return (1);
|
|
|
|
if( strcmp(entry1->relname, "..")==0 ) return (-1);
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if ( entry1->s.st_size < entry2->s.st_size) return 1;
|
|
|
|
if ( entry1->s.st_size > entry2->s.st_size) return -1;
|
2005-04-02 15:36:57 +00:00
|
|
|
else return BLI_strcasecmp(entry1->relname,entry2->relname);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
2005-09-26 16:17:14 +00:00
|
|
|
static int compare_extension(const void *a1, const void *a2) {
|
|
|
|
const struct direntry *entry1=a1, *entry2=a2;
|
|
|
|
char *sufix1, *sufix2;
|
|
|
|
char *nil="";
|
|
|
|
|
|
|
|
if (!(sufix1= strstr (entry1->relname, ".blend.gz")))
|
|
|
|
sufix1= strrchr (entry1->relname, '.');
|
|
|
|
if (!(sufix2= strstr (entry2->relname, ".blend.gz")))
|
|
|
|
sufix2= strrchr (entry2->relname, '.');
|
|
|
|
if (!sufix1) sufix1= nil;
|
|
|
|
if (!sufix2) sufix2= nil;
|
|
|
|
|
|
|
|
/* type is is equal to stat.st_mode */
|
|
|
|
|
|
|
|
if (S_ISDIR(entry1->type)){
|
|
|
|
if (S_ISDIR(entry2->type)==0) return (-1);
|
|
|
|
} else{
|
|
|
|
if (S_ISDIR(entry2->type)) return (1);
|
|
|
|
}
|
|
|
|
if (S_ISREG(entry1->type)){
|
|
|
|
if (S_ISREG(entry2->type)==0) return (-1);
|
|
|
|
} else{
|
|
|
|
if (S_ISREG(entry2->type)) return (1);
|
|
|
|
}
|
|
|
|
if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1);
|
|
|
|
if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1);
|
|
|
|
|
|
|
|
/* make sure "." and ".." are always first */
|
|
|
|
if( strcmp(entry1->relname, ".")==0 ) return (-1);
|
|
|
|
if( strcmp(entry2->relname, ".")==0 ) return (1);
|
|
|
|
if( strcmp(entry1->relname, "..")==0 ) return (-1);
|
|
|
|
if( strcmp(entry2->relname, "..")==0 ) return (-1);
|
|
|
|
|
|
|
|
return (BLI_strcasecmp(sufix1, sufix2));
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
/* **************************************** */
|
|
|
|
|
|
|
|
void clear_global_filesel_vars()
|
|
|
|
{
|
|
|
|
selecting= 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void filesel_statistics(SpaceFile *sfile, int *totfile, int *selfile, float *totlen, float *sellen)
|
|
|
|
{
|
2005-04-30 09:57:35 +00:00
|
|
|
double len;
|
|
|
|
int a;
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
*totfile= *selfile= 0;
|
|
|
|
*totlen= *sellen= 0;
|
|
|
|
|
|
|
|
if(sfile->filelist==0) return;
|
|
|
|
|
|
|
|
for(a=0; a<sfile->totfile; a++) {
|
|
|
|
if( (sfile->filelist[a].type & S_IFDIR)==0 ) {
|
|
|
|
(*totfile) ++;
|
|
|
|
|
|
|
|
len = sfile->filelist[a].s.st_size;
|
2005-07-14 06:25:02 +00:00
|
|
|
(*totlen) += (float)(len/1048576.0);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
if(sfile->filelist[a].flags & ACTIVE) {
|
|
|
|
(*selfile) ++;
|
2005-07-14 06:25:02 +00:00
|
|
|
(*sellen) += (float)(len/1048576.0);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* *************** HELP FUNCTIONS ******************* */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
/* This is a really ugly function... its purpose is to
|
|
|
|
* take the space file name and clean it up, replacing
|
|
|
|
* excess file entry stuff (like /tmp/../tmp/../)
|
|
|
|
*/
|
|
|
|
|
|
|
|
void checkdir(char *dir)
|
|
|
|
{
|
|
|
|
short a;
|
|
|
|
char *start, *eind;
|
|
|
|
char tmp[FILE_MAXDIR+FILE_MAXFILE];
|
|
|
|
|
|
|
|
BLI_make_file_string(G.sce, tmp, dir, "");
|
|
|
|
strcpy(dir, tmp);
|
|
|
|
|
|
|
|
#ifdef WIN32
|
2003-04-30 13:22:26 +00:00
|
|
|
if(dir[0]=='.') { /* happens for example in FILE_MAIN */
|
2002-10-12 11:37:38 +00:00
|
|
|
dir[0]= '\\';
|
|
|
|
dir[1]= 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-07-28 03:20:21 +00:00
|
|
|
while ( (start = strstr(dir, "\\..\\")) ) {
|
2002-10-12 11:37:38 +00:00
|
|
|
eind = start + strlen("\\..\\") - 1;
|
|
|
|
a = start-dir-1;
|
|
|
|
while (a>0) {
|
|
|
|
if (dir[a] == '\\') break;
|
|
|
|
a--;
|
|
|
|
}
|
|
|
|
strcpy(dir+a,eind);
|
|
|
|
}
|
|
|
|
|
2005-07-28 03:20:21 +00:00
|
|
|
while ( (start = strstr(dir,"\\.\\")) ){
|
2002-10-12 11:37:38 +00:00
|
|
|
eind = start + strlen("\\.\\") - 1;
|
|
|
|
strcpy(start,eind);
|
|
|
|
}
|
|
|
|
|
2005-07-28 03:20:21 +00:00
|
|
|
while ( (start = strstr(dir,"\\\\" )) ){
|
2002-10-12 11:37:38 +00:00
|
|
|
eind = start + strlen("\\\\") - 1;
|
|
|
|
strcpy(start,eind);
|
|
|
|
}
|
|
|
|
|
2005-07-28 03:20:21 +00:00
|
|
|
if((a = strlen(dir))){ /* remove the '\\' at the end */
|
2002-10-12 11:37:38 +00:00
|
|
|
while(a>0 && dir[a-1] == '\\'){
|
|
|
|
a--;
|
|
|
|
dir[a] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
strcat(dir, "\\");
|
|
|
|
#else
|
2003-04-30 13:22:26 +00:00
|
|
|
if(dir[0]=='.') { /* happens, for example in FILE_MAIN */
|
2002-10-12 11:37:38 +00:00
|
|
|
dir[0]= '/';
|
|
|
|
dir[1]= 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
while ( (start = strstr(dir, "/../")) ) {
|
|
|
|
eind = start + strlen("/../") - 1;
|
|
|
|
a = start-dir-1;
|
|
|
|
while (a>0) {
|
|
|
|
if (dir[a] == '/') break;
|
|
|
|
a--;
|
|
|
|
}
|
|
|
|
strcpy(dir+a,eind);
|
|
|
|
}
|
|
|
|
|
|
|
|
while ( (start = strstr(dir,"/./")) ){
|
|
|
|
eind = start + strlen("/./") - 1;
|
|
|
|
strcpy(start,eind);
|
|
|
|
}
|
|
|
|
|
|
|
|
while ( (start = strstr(dir,"//" )) ){
|
|
|
|
eind = start + strlen("//") - 1;
|
|
|
|
strcpy(start,eind);
|
|
|
|
}
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
if( (a = strlen(dir)) ){ /* remove all '/' at the end */
|
2002-10-12 11:37:38 +00:00
|
|
|
while(dir[a-1] == '/'){
|
|
|
|
a--;
|
|
|
|
dir[a] = 0;
|
|
|
|
if (a<=0) break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
strcat(dir, "/");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2004-07-23 10:49:04 +00:00
|
|
|
/* not called when browsing .blend itself */
|
2002-10-12 11:37:38 +00:00
|
|
|
void test_flags_file(SpaceFile *sfile)
|
|
|
|
{
|
|
|
|
struct direntry *file;
|
|
|
|
int num;
|
|
|
|
|
|
|
|
file= sfile->filelist;
|
|
|
|
|
|
|
|
for(num=0; num<sfile->totfile; num++, file++) {
|
|
|
|
file->flags= 0;
|
2003-04-30 13:22:26 +00:00
|
|
|
file->type= file->s.st_mode; /* restore the mess below */
|
2004-07-23 10:49:04 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
/* Don't check extensions for directories */
|
2004-07-23 10:49:04 +00:00
|
|
|
if (file->type & S_IFDIR)
|
2002-10-12 11:37:38 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
if(sfile->type==FILE_BLENDER || sfile->type==FILE_LOADLIB) {
|
|
|
|
if(BLO_has_bfile_extension(file->relname)) {
|
|
|
|
file->flags |= BLENDERFILE;
|
2004-04-05 11:25:25 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(sfile->type==FILE_LOADLIB) {
|
2004-04-05 11:25:25 +00:00
|
|
|
char name[FILE_MAXDIR+FILE_MAXFILE];
|
|
|
|
strcpy(name, sfile->dir);
|
|
|
|
strcat(name, file->relname);
|
2004-07-23 10:49:04 +00:00
|
|
|
|
2004-04-05 11:25:25 +00:00
|
|
|
/* prevent current file being used as acceptable dir */
|
|
|
|
if (BLI_streq(G.main->name, name)==0) {
|
|
|
|
file->type &= ~S_IFMT;
|
|
|
|
file->type |= S_IFDIR;
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (sfile->type==FILE_SPECIAL){
|
2003-04-28 02:15:46 +00:00
|
|
|
if(BLI_testextensie(file->relname, ".py")) {
|
2003-02-06 14:04:47 +00:00
|
|
|
file->flags |= PYSCRIPTFILE;
|
2003-04-28 02:15:46 +00:00
|
|
|
} else if( BLI_testextensie(file->relname, ".ttf")
|
2003-05-11 15:44:23 +00:00
|
|
|
|| BLI_testextensie(file->relname, ".ttc")
|
2003-04-28 02:15:46 +00:00
|
|
|
|| BLI_testextensie(file->relname, ".pfb")
|
2003-05-11 15:44:23 +00:00
|
|
|
|| BLI_testextensie(file->relname, ".otf")
|
2003-04-28 02:15:46 +00:00
|
|
|
|| BLI_testextensie(file->relname, ".otc")) {
|
|
|
|
file->flags |= FTFONTFILE;
|
|
|
|
} else if (G.have_quicktime){
|
|
|
|
if( BLI_testextensie(file->relname, ".jpg")
|
|
|
|
|| BLI_testextensie(file->relname, ".jpeg")
|
|
|
|
|| BLI_testextensie(file->relname, ".tga")
|
|
|
|
|| BLI_testextensie(file->relname, ".rgb")
|
|
|
|
|| BLI_testextensie(file->relname, ".bmp")
|
|
|
|
|| BLI_testextensie(file->relname, ".png")
|
|
|
|
|| BLI_testextensie(file->relname, ".iff")
|
|
|
|
|| BLI_testextensie(file->relname, ".lbm")
|
|
|
|
|| BLI_testextensie(file->relname, ".gif")
|
|
|
|
|| BLI_testextensie(file->relname, ".psd")
|
|
|
|
|| BLI_testextensie(file->relname, ".tif")
|
|
|
|
|| BLI_testextensie(file->relname, ".tiff")
|
|
|
|
|| BLI_testextensie(file->relname, ".pct")
|
|
|
|
|| BLI_testextensie(file->relname, ".pict")
|
|
|
|
|| BLI_testextensie(file->relname, ".pntg") //macpaint
|
|
|
|
|| BLI_testextensie(file->relname, ".qtif")
|
|
|
|
|| BLI_testextensie(file->relname, ".sgi")) {
|
|
|
|
file->flags |= IMAGEFILE;
|
|
|
|
}
|
|
|
|
else if(BLI_testextensie(file->relname, ".avi")
|
|
|
|
|| BLI_testextensie(file->relname, ".flc")
|
|
|
|
|| BLI_testextensie(file->relname, ".mov")
|
|
|
|
|| BLI_testextensie(file->relname, ".movie")
|
|
|
|
|| BLI_testextensie(file->relname, ".mv")) {
|
|
|
|
file->flags |= MOVIEFILE;
|
|
|
|
}
|
|
|
|
} else { // no quicktime
|
|
|
|
if(BLI_testextensie(file->relname, ".jpg")
|
|
|
|
|| BLI_testextensie(file->relname, ".tga")
|
|
|
|
|| BLI_testextensie(file->relname, ".rgb")
|
|
|
|
|| BLI_testextensie(file->relname, ".bmp")
|
|
|
|
|| BLI_testextensie(file->relname, ".png")
|
|
|
|
|| BLI_testextensie(file->relname, ".iff")
|
|
|
|
|| BLI_testextensie(file->relname, ".lbm")
|
|
|
|
|| BLI_testextensie(file->relname, ".sgi")) {
|
|
|
|
file->flags |= IMAGEFILE;
|
|
|
|
}
|
|
|
|
else if(BLI_testextensie(file->relname, ".avi")
|
|
|
|
|| BLI_testextensie(file->relname, ".mv")) {
|
|
|
|
file->flags |= MOVIEFILE;
|
|
|
|
}
|
Commit message and the brunt of the code courtesy of intrr, apologies for the
size of this;
Finally, the Sequencer audio support and global audio/animation sync stuff!
(See http://intrr.org/blender/audiosequencer.html)
Stuff that has been done:
./source/blender/blenloader/intern/writefile.c
./source/blender/blenloader/intern/readfile.c
Added code to make it handle sounds used by audio strips, and to convert
Scene data from older (<2.28) versions to init Scene global audio settings
(Scene->audio) to defaults.
./source/blender/include/BSE_seqaudio.h
./source/blender/src/seqaudio.c
The main audio routines that start/stop/scrub the audio stream at
a certain frame position, provide the frame reference for the current
stream position, mix the audio, convert the audio, mixdown the audio
into a file.
./source/blender/makesdna/DNA_sound_types.h
Introduced new variables in the bSound struct to accomodate the sample
data after converted to the scene's global mixing format (stream, streamlen).
Also added a new flag SOUND_FLAGS_SEQUENCE that gets set if the Sound
belongs to a sequence strip.
./source/blender/makesdna/DNA_scene_types.h
Added AudioData struct, which holds scene-global audio settings.
./source/blender/makesdna/DNA_sequence_types.h
Added support for audio strips. Some variables to hold Panning/Attenuation
information, position information, reference to the sample, and some flags.
./source/blender/makesdna/DNA_userdef_types.h
./source/blender/src/usiblender.c
Added a "Mixing buffer size" userpref. Made the versions stuff initialize
it to a default for versions <2.28.
./source/blender/makesdna/DNA_space_types.h
./source/blender/src/filesel.c
Added a Cyan dot to .WAV files. Any other suggestions on a better color? :)
./source/blender/src/editsound.c
Changes (fixes) to the WAV file loader, re-enabled some gameengine code that
is needed for dealing with bSounds and bSamples.
./source/blender/src/editipo.c
./source/blender/src/drawseq.c
./source/blender/src/editnla.c
./source/blender/src/space.c
./source/blender/src/drawview.c
./source/blender/src/renderwin.c
./source/blender/src/headerbuttons.c
- Created two different wrappers for update_for_newframe(), one which scrubs
the audio, one which doesn't.
- Replaced some of the occurences of update_for_newframe() with
update_for_newframe_muted(), which doesn't scrub the audio.
- In drawview.c: Changed the synchronization scheme to get the current audio
position from the audio engine, and use that as a reference for setting
CFRA. Implements a/v sync and framedrop.
- In editipo.c: Changed handling of Fac IPOs to be usable for audio strips as
volume envelopes.
- In space.c: Added the mixing buffer size Userpref, enabled audio scrubbing
(update_for_newframe()) for moving the sequence editor framebar.
./source/blender/src/editseq.c
Added support for audio strips and a default directory for WAV files which
gets saved from the last Shift-A operation.
./source/blender/src/buttons.c
Added Scene-global audio sequencer settings in Sound buttons.
./source/blender/src/sequence.c
Various stuff that deals with handling audio strips differently than
usual strips.
2003-07-13 20:16:56 +00:00
|
|
|
else if(BLI_testextensie(file->relname, ".wav")) {
|
|
|
|
file->flags |= SOUNDFILE;
|
|
|
|
}
|
2003-02-06 14:04:47 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void sort_filelist(SpaceFile *sfile)
|
|
|
|
{
|
|
|
|
struct direntry *file;
|
|
|
|
int num;/* , act= 0; */
|
|
|
|
|
|
|
|
switch(sfile->sort) {
|
|
|
|
case FILE_SORTALPHA:
|
|
|
|
qsort(sfile->filelist, sfile->totfile, sizeof(struct direntry), compare_name);
|
|
|
|
break;
|
|
|
|
case FILE_SORTDATE:
|
|
|
|
qsort(sfile->filelist, sfile->totfile, sizeof(struct direntry), compare_date);
|
|
|
|
break;
|
|
|
|
case FILE_SORTSIZE:
|
|
|
|
qsort(sfile->filelist, sfile->totfile, sizeof(struct direntry), compare_size);
|
|
|
|
break;
|
|
|
|
case FILE_SORTEXTENS:
|
2005-09-26 16:17:14 +00:00
|
|
|
qsort(sfile->filelist, sfile->totfile, sizeof(struct direntry), compare_extension);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sfile->act= -1;
|
|
|
|
|
|
|
|
file= sfile->filelist;
|
|
|
|
for(num=0; num<sfile->totfile; num++, file++) {
|
|
|
|
file->flags &= ~HILITE;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void read_dir(SpaceFile *sfile)
|
|
|
|
{
|
|
|
|
int num, len;
|
|
|
|
char wdir[FILE_MAXDIR];
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* sfile->act is used for example in databrowse: double names of library objects */
|
2002-10-12 11:37:38 +00:00
|
|
|
sfile->act= -1;
|
|
|
|
|
|
|
|
if(sfile->type==FILE_MAIN) {
|
|
|
|
main_to_filelist(sfile);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if(sfile->type==FILE_LOADLIB) {
|
|
|
|
library_to_filelist(sfile);
|
|
|
|
if(sfile->libfiledata) return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BLI_hide_dot_files(sfile->flag & FILE_HIDE_DOT);
|
|
|
|
|
|
|
|
BLI_getwdN(wdir);
|
|
|
|
sfile->totfile= BLI_getdir(sfile->dir, &(sfile->filelist));
|
|
|
|
chdir(wdir);
|
|
|
|
|
|
|
|
if(sfile->sort!=FILE_SORTALPHA) sort_filelist(sfile);
|
|
|
|
|
|
|
|
sfile->maxnamelen= 0;
|
|
|
|
|
|
|
|
for (num=0; num<sfile->totfile; num++) {
|
|
|
|
|
|
|
|
len = BMF_GetStringWidth(G.font, sfile->filelist[num].relname);
|
|
|
|
if (len > sfile->maxnamelen) sfile->maxnamelen = len;
|
|
|
|
|
|
|
|
if(filetoname) {
|
|
|
|
if(strcmp(sfile->file, sfile->filelist[num].relname)==0) {
|
|
|
|
|
|
|
|
sfile->ofs= num-( sfile->collums*(curarea->winy-FILESELHEAD-20)/(2*FILESEL_DY));
|
|
|
|
filetoname= 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
test_flags_file(sfile);
|
|
|
|
|
|
|
|
filetoname= 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void freefilelist(SpaceFile *sfile)
|
|
|
|
{
|
|
|
|
int num;
|
|
|
|
|
|
|
|
num= sfile->totfile-1;
|
|
|
|
|
|
|
|
if (sfile->filelist==0) return;
|
|
|
|
|
|
|
|
for(; num>=0; num--){
|
2005-04-17 15:50:52 +00:00
|
|
|
MEM_freeN(sfile->filelist[num].relname);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-04-17 15:50:52 +00:00
|
|
|
if (sfile->filelist[num].string) MEM_freeN(sfile->filelist[num].string);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
free(sfile->filelist);
|
|
|
|
sfile->filelist= 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void split_sfile(SpaceFile *sfile, char *s1)
|
|
|
|
{
|
|
|
|
char string[FILE_MAXDIR+FILE_MAXFILE], dir[FILE_MAXDIR], file[FILE_MAXFILE];
|
|
|
|
|
|
|
|
strcpy(string, s1);
|
|
|
|
|
|
|
|
BLI_split_dirfile(string, dir, file);
|
|
|
|
|
|
|
|
if(sfile->filelist) {
|
|
|
|
if(strcmp(dir, sfile->dir)!=0) {
|
|
|
|
freefilelist(sfile);
|
|
|
|
}
|
|
|
|
else test_flags_file(sfile);
|
|
|
|
}
|
|
|
|
strcpy(sfile->file, file);
|
Patch provided by Shaul Kedem: Compressed files are back!
He even made a nice doc in wiki:
http://wiki.blender.org/bin/view.pl/Blenderdev/Blendgz
Usage: set the option "Compress File" in the main "File" pulldown menu.
This setting is a user-def, meaning it is not changed on reading files.
If you want it default, save it with CTRL+U.
The longest debate went over the file naming convention. Shaul started
with .blend.gz files, which gave issues in Blender because of the code
hanging out everywhere that detects blender files, and that appends the
.blend extension if needed.
Daniel Dunbar proposed to just save it as .blend, and not bother users
with such details. This is indeed the most elegant solution, with as
only drawback that old Blender executables cannot read it.
This drawback isn't very relevant at the moment, since we're heading
towards a release that isn't upward compatible anyway... the recode
going on on Meshes, Modfiers, Armatures, Poses, Actions, NLA already
have upward compatibility issues.
We might check - during the next month(s) - on a builtin system to
warn users in the future when we change things that make a file risky
to read in an older release.
2005-07-27 19:46:06 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
BLI_make_file_string(G.sce, sfile->dir, dir, "");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void parent(SpaceFile *sfile)
|
|
|
|
{
|
|
|
|
short a;
|
|
|
|
char *dir;
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* if databrowse: no parent */
|
2002-10-12 11:37:38 +00:00
|
|
|
if(sfile->type==FILE_MAIN && sfile->returnfunc) return;
|
|
|
|
|
|
|
|
dir= sfile->dir;
|
|
|
|
|
|
|
|
#ifdef WIN32
|
2005-07-28 03:20:21 +00:00
|
|
|
if( (a = strlen(dir)) ) { /* remove all '/' at the end */
|
2002-10-12 11:37:38 +00:00
|
|
|
while(dir[a-1] == '\\') {
|
|
|
|
a--;
|
|
|
|
dir[a] = 0;
|
|
|
|
if (a<=0) break;
|
|
|
|
}
|
|
|
|
}
|
2005-07-28 03:20:21 +00:00
|
|
|
if( (a = strlen(dir)) ) { /* then remove all until '/' */
|
2002-10-12 11:37:38 +00:00
|
|
|
while(dir[a-1] != '\\') {
|
|
|
|
a--;
|
|
|
|
dir[a] = 0;
|
|
|
|
if (a<=0) break;
|
|
|
|
}
|
|
|
|
}
|
2005-07-28 03:20:21 +00:00
|
|
|
if( (a = strlen(dir)) ) {
|
2002-10-12 11:37:38 +00:00
|
|
|
if (dir[a-1] != '\\') strcat(dir,"\\");
|
|
|
|
}
|
|
|
|
else if(sfile->type!=FILE_MAIN) strcpy(dir,"\\");
|
|
|
|
#else
|
2003-04-30 13:22:26 +00:00
|
|
|
if( (a = strlen(dir)) ) { /* remove all '/' at the end */
|
2002-10-12 11:37:38 +00:00
|
|
|
while(dir[a-1] == '/') {
|
|
|
|
a--;
|
|
|
|
dir[a] = 0;
|
|
|
|
if (a<=0) break;
|
|
|
|
}
|
|
|
|
}
|
2003-04-30 13:22:26 +00:00
|
|
|
if( (a = strlen(dir)) ) { /* then remove until '/' */
|
2002-10-12 11:37:38 +00:00
|
|
|
while(dir[a-1] != '/') {
|
|
|
|
a--;
|
|
|
|
dir[a] = 0;
|
|
|
|
if (a<=0) break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( (a = strlen(dir)) ) {
|
|
|
|
if (dir[a-1] != '/') strcat(dir,"/");
|
|
|
|
}
|
|
|
|
else if(sfile->type!=FILE_MAIN) strcpy(dir,"/");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* to be sure */
|
|
|
|
BLI_make_exist(sfile->dir);
|
|
|
|
|
|
|
|
freefilelist(sfile);
|
|
|
|
sfile->ofs= 0;
|
|
|
|
scrarea_queue_winredraw(curarea);
|
|
|
|
}
|
|
|
|
|
|
|
|
void swapselect_file(SpaceFile *sfile)
|
|
|
|
{
|
|
|
|
struct direntry *file;
|
|
|
|
int num, act= 0;
|
|
|
|
|
|
|
|
file= sfile->filelist;
|
|
|
|
for(num=0; num<sfile->totfile; num++, file++) {
|
|
|
|
if(file->flags & ACTIVE) {
|
|
|
|
act= 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
file= sfile->filelist+2;
|
|
|
|
for(num=2; num<sfile->totfile; num++, file++) {
|
|
|
|
if(act) file->flags &= ~ACTIVE;
|
|
|
|
else file->flags |= ACTIVE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int find_active_file(SpaceFile *sfile, short x, short y)
|
|
|
|
{
|
|
|
|
int ofs;
|
|
|
|
|
|
|
|
if(y > textrct.ymax) y= textrct.ymax;
|
|
|
|
if(y <= textrct.ymin) y= textrct.ymin+1;
|
|
|
|
|
|
|
|
ofs= (x-textrct.xmin)/collumwidth;
|
|
|
|
if(ofs<0) ofs= 0;
|
|
|
|
ofs*= (textrct.ymax-textrct.ymin);
|
|
|
|
|
|
|
|
return sfile->ofs+ (ofs+textrct.ymax-y)/FILESEL_DY;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ********************** DRAW ******************************* */
|
|
|
|
|
|
|
|
static void calc_file_rcts(SpaceFile *sfile)
|
|
|
|
{
|
|
|
|
int tot, h, len;
|
|
|
|
float fac, start, totfile;
|
|
|
|
|
|
|
|
scrollrct.xmin= 15;
|
|
|
|
scrollrct.xmax= 35;
|
|
|
|
scrollrct.ymin= 10;
|
|
|
|
scrollrct.ymax= curarea->winy-10-FILESELHEAD;
|
|
|
|
|
|
|
|
textrct.xmin= scrollrct.xmax+10;
|
|
|
|
textrct.xmax= curarea->winx-10;
|
|
|
|
textrct.ymin= scrollrct.ymin;
|
|
|
|
textrct.ymax= scrollrct.ymax;
|
|
|
|
|
|
|
|
if(textrct.xmax-textrct.xmin <60) textrct.xmax= textrct.xmin+60;
|
|
|
|
|
|
|
|
len= (textrct.ymax-textrct.ymin) % FILESEL_DY;
|
|
|
|
textrct.ymin+= len;
|
|
|
|
scrollrct.ymin+= len;
|
|
|
|
|
|
|
|
filebuty1= curarea->winy-FILESELHEAD;
|
|
|
|
filebuty2= filebuty1+FILESELHEAD/2 -6;
|
|
|
|
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* amount of collums */
|
2002-10-12 11:37:38 +00:00
|
|
|
len= sfile->maxnamelen+25;
|
|
|
|
|
|
|
|
if(sfile->type==FILE_MAIN) len+= 100;
|
|
|
|
else if(sfile->flag & FILE_SHOWSHORT) len+= 100;
|
|
|
|
else len+= 380;
|
|
|
|
|
|
|
|
sfile->collums= (textrct.xmax-textrct.xmin)/len;
|
|
|
|
|
|
|
|
if(sfile->collums<1) sfile->collums= 1;
|
|
|
|
else if(sfile->collums>8) sfile->collums= 8;
|
|
|
|
|
2005-01-10 12:34:39 +00:00
|
|
|
/* this flag aint yet defined in user menu, needed? */
|
|
|
|
// if((U.flag & USER_FSCOLLUM)==0) sfile->collums= 1;
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
collumwidth= (textrct.xmax-textrct.xmin)/sfile->collums;
|
|
|
|
|
|
|
|
|
2005-07-14 06:25:02 +00:00
|
|
|
totfile= sfile->totfile + 0.5f;
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-07-14 06:25:02 +00:00
|
|
|
tot= (int)(FILESEL_DY*totfile);
|
2002-10-12 11:37:38 +00:00
|
|
|
if(tot) fac= ((float)sfile->collums*(scrollrct.ymax-scrollrct.ymin))/( (float)tot);
|
|
|
|
else fac= 1.0;
|
|
|
|
|
|
|
|
if(sfile->ofs<0) sfile->ofs= 0;
|
|
|
|
|
|
|
|
if(tot) start= ( (float)sfile->ofs)/(totfile);
|
|
|
|
else start= 0.0;
|
2005-07-14 06:25:02 +00:00
|
|
|
if(fac>1.0) fac= 1.0f;
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
if(start+fac>1.0) {
|
2005-07-14 06:25:02 +00:00
|
|
|
sfile->ofs= (short)ceil((1.0-fac)*totfile);
|
2002-10-12 11:37:38 +00:00
|
|
|
start= ( (float)sfile->ofs)/(totfile);
|
2005-07-14 06:25:02 +00:00
|
|
|
fac= 1.0f-start;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bar.xmin= scrollrct.xmin+2;
|
|
|
|
bar.xmax= scrollrct.xmax-2;
|
|
|
|
h= (scrollrct.ymax-scrollrct.ymin)-4;
|
2005-07-14 06:25:02 +00:00
|
|
|
bar.ymax= (int)(scrollrct.ymax-2- start*h);
|
|
|
|
bar.ymin= (int)(bar.ymax- fac*h);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
pixels_to_ofs= (totfile)/(float)(h+3);
|
2005-07-14 06:25:02 +00:00
|
|
|
page_ofs= (int)(fac*totfile);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int filescrollselect= 0;
|
|
|
|
|
|
|
|
static void draw_filescroll(SpaceFile *sfile)
|
|
|
|
{
|
|
|
|
|
|
|
|
if(scrollrct.ymin+10 >= scrollrct.ymax) return;
|
|
|
|
|
2003-10-19 09:19:58 +00:00
|
|
|
BIF_ThemeColor(TH_BACK);
|
2002-10-12 11:37:38 +00:00
|
|
|
glRecti(scrollrct.xmin, scrollrct.ymin, scrollrct.xmax, scrollrct.ymax);
|
|
|
|
|
|
|
|
uiEmboss(scrollrct.xmin, scrollrct.ymin, scrollrct.xmax, scrollrct.ymax, 1);
|
|
|
|
|
2003-10-19 09:19:58 +00:00
|
|
|
BIF_ThemeColor(TH_HEADER);
|
2002-10-12 11:37:38 +00:00
|
|
|
glRecti(bar.xmin+2, bar.ymin+2, bar.xmax-2, bar.ymax-2);
|
|
|
|
|
|
|
|
uiEmboss(bar.xmin+2, bar.ymin+2, bar.xmax-2, bar.ymax-2, filescrollselect);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2004-07-23 10:49:04 +00:00
|
|
|
static void linerect(int id, int x, int y)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2003-10-18 12:21:41 +00:00
|
|
|
if(id & ACTIVE) {
|
2003-10-19 09:19:58 +00:00
|
|
|
if(id & HILITE) BIF_ThemeColorShade(TH_HILITE, 20);
|
|
|
|
else BIF_ThemeColor(TH_HILITE);
|
2003-10-18 12:21:41 +00:00
|
|
|
}
|
2003-10-19 09:19:58 +00:00
|
|
|
else if(id & HILITE) BIF_ThemeColorShade(TH_BACK, 20);
|
|
|
|
else BIF_ThemeColor(TH_BACK);
|
2003-10-18 12:21:41 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
glRects(x-17, y-3, x+collumwidth-21, y+11);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2004-07-23 10:49:04 +00:00
|
|
|
static void print_line(SpaceFile *sfile, struct direntry *files, int x, int y)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2003-10-18 12:21:41 +00:00
|
|
|
int boxcol=0;
|
2002-10-12 11:37:38 +00:00
|
|
|
char *s;
|
|
|
|
|
2003-10-18 12:21:41 +00:00
|
|
|
boxcol= files->flags & (HILITE + ACTIVE);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
if(boxcol) {
|
2004-07-23 10:49:04 +00:00
|
|
|
linerect(boxcol, x, y);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
Patch provided by Shaul Kedem: Compressed files are back!
He even made a nice doc in wiki:
http://wiki.blender.org/bin/view.pl/Blenderdev/Blendgz
Usage: set the option "Compress File" in the main "File" pulldown menu.
This setting is a user-def, meaning it is not changed on reading files.
If you want it default, save it with CTRL+U.
The longest debate went over the file naming convention. Shaul started
with .blend.gz files, which gave issues in Blender because of the code
hanging out everywhere that detects blender files, and that appends the
.blend extension if needed.
Daniel Dunbar proposed to just save it as .blend, and not bother users
with such details. This is indeed the most elegant solution, with as
only drawback that old Blender executables cannot read it.
This drawback isn't very relevant at the moment, since we're heading
towards a release that isn't upward compatible anyway... the recode
going on on Meshes, Modfiers, Armatures, Poses, Actions, NLA already
have upward compatibility issues.
We might check - during the next month(s) - on a builtin system to
warn users in the future when we change things that make a file risky
to read in an older release.
2005-07-27 19:46:06 +00:00
|
|
|
// this is where the little boxes in the file view are being drawn according to the file type
|
2002-10-12 11:37:38 +00:00
|
|
|
if(files->flags & BLENDERFILE) {
|
|
|
|
cpack(0xA0A0);
|
|
|
|
glRects(x-14, y, x-8, y+7);
|
|
|
|
}
|
|
|
|
else if(files->flags & PSXFILE) {
|
|
|
|
cpack(0xA060B0);
|
|
|
|
glRects(x-14, y, x-8, y+7);
|
|
|
|
}
|
|
|
|
else if(files->flags & IMAGEFILE) {
|
|
|
|
cpack(0xF08040);
|
|
|
|
glRects(x-14, y, x-8, y+7);
|
|
|
|
}
|
|
|
|
else if(files->flags & MOVIEFILE) {
|
|
|
|
cpack(0x70A070);
|
|
|
|
glRects(x-14, y, x-8, y+7);
|
|
|
|
}
|
2003-02-06 14:04:47 +00:00
|
|
|
else if(files->flags & PYSCRIPTFILE) {
|
|
|
|
cpack(0x4477dd);
|
|
|
|
glRects(x-14, y, x-8, y+7);
|
|
|
|
}
|
Commit message and the brunt of the code courtesy of intrr, apologies for the
size of this;
Finally, the Sequencer audio support and global audio/animation sync stuff!
(See http://intrr.org/blender/audiosequencer.html)
Stuff that has been done:
./source/blender/blenloader/intern/writefile.c
./source/blender/blenloader/intern/readfile.c
Added code to make it handle sounds used by audio strips, and to convert
Scene data from older (<2.28) versions to init Scene global audio settings
(Scene->audio) to defaults.
./source/blender/include/BSE_seqaudio.h
./source/blender/src/seqaudio.c
The main audio routines that start/stop/scrub the audio stream at
a certain frame position, provide the frame reference for the current
stream position, mix the audio, convert the audio, mixdown the audio
into a file.
./source/blender/makesdna/DNA_sound_types.h
Introduced new variables in the bSound struct to accomodate the sample
data after converted to the scene's global mixing format (stream, streamlen).
Also added a new flag SOUND_FLAGS_SEQUENCE that gets set if the Sound
belongs to a sequence strip.
./source/blender/makesdna/DNA_scene_types.h
Added AudioData struct, which holds scene-global audio settings.
./source/blender/makesdna/DNA_sequence_types.h
Added support for audio strips. Some variables to hold Panning/Attenuation
information, position information, reference to the sample, and some flags.
./source/blender/makesdna/DNA_userdef_types.h
./source/blender/src/usiblender.c
Added a "Mixing buffer size" userpref. Made the versions stuff initialize
it to a default for versions <2.28.
./source/blender/makesdna/DNA_space_types.h
./source/blender/src/filesel.c
Added a Cyan dot to .WAV files. Any other suggestions on a better color? :)
./source/blender/src/editsound.c
Changes (fixes) to the WAV file loader, re-enabled some gameengine code that
is needed for dealing with bSounds and bSamples.
./source/blender/src/editipo.c
./source/blender/src/drawseq.c
./source/blender/src/editnla.c
./source/blender/src/space.c
./source/blender/src/drawview.c
./source/blender/src/renderwin.c
./source/blender/src/headerbuttons.c
- Created two different wrappers for update_for_newframe(), one which scrubs
the audio, one which doesn't.
- Replaced some of the occurences of update_for_newframe() with
update_for_newframe_muted(), which doesn't scrub the audio.
- In drawview.c: Changed the synchronization scheme to get the current audio
position from the audio engine, and use that as a reference for setting
CFRA. Implements a/v sync and framedrop.
- In editipo.c: Changed handling of Fac IPOs to be usable for audio strips as
volume envelopes.
- In space.c: Added the mixing buffer size Userpref, enabled audio scrubbing
(update_for_newframe()) for moving the sequence editor framebar.
./source/blender/src/editseq.c
Added support for audio strips and a default directory for WAV files which
gets saved from the last Shift-A operation.
./source/blender/src/buttons.c
Added Scene-global audio sequencer settings in Sound buttons.
./source/blender/src/sequence.c
Various stuff that deals with handling audio strips differently than
usual strips.
2003-07-13 20:16:56 +00:00
|
|
|
else if(files->flags & SOUNDFILE) {
|
|
|
|
cpack(0xa0a000);
|
|
|
|
glRects(x-14, y, x-8, y+7);
|
|
|
|
}
|
2003-04-28 02:15:46 +00:00
|
|
|
else if(files->flags & FTFONTFILE) {
|
|
|
|
cpack(0xff2371);
|
|
|
|
glRects(x-14, y, x-8, y+7);
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2003-10-19 09:19:58 +00:00
|
|
|
if(S_ISDIR(files->type)) BIF_ThemeColor(TH_TEXT_HI);
|
|
|
|
else BIF_ThemeColor(TH_TEXT);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
s = files->string;
|
|
|
|
if(s) {
|
|
|
|
glRasterPos2i(x, y);
|
|
|
|
BMF_DrawString(G.font, files->relname);
|
|
|
|
|
|
|
|
x += sfile->maxnamelen + 100;
|
|
|
|
|
|
|
|
glRasterPos2i(x - BMF_GetStringWidth(G.font, files->size), y);
|
|
|
|
BMF_DrawString(G.font, files->size);
|
|
|
|
|
|
|
|
if(sfile->flag & FILE_SHOWSHORT) return;
|
|
|
|
|
|
|
|
#ifndef WIN32
|
|
|
|
/* rwx rwx rwx */
|
|
|
|
x += 20; glRasterPos2i(x, y);
|
|
|
|
BMF_DrawString(G.font, files->mode1);
|
|
|
|
|
|
|
|
x += 30; glRasterPos2i(x, y);
|
|
|
|
BMF_DrawString(G.font, files->mode2);
|
|
|
|
|
|
|
|
x += 30; glRasterPos2i(x, y);
|
|
|
|
BMF_DrawString(G.font, files->mode3);
|
|
|
|
|
|
|
|
/* owner time date */
|
|
|
|
x += 30; glRasterPos2i(x, y);
|
|
|
|
BMF_DrawString(G.font, files->owner);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
x += 60; glRasterPos2i(x, y);
|
|
|
|
BMF_DrawString(G.font, files->time);
|
|
|
|
|
|
|
|
x += 50; glRasterPos2i(x, y);
|
|
|
|
BMF_DrawString(G.font, files->date);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
glRasterPos2i(x, y);
|
|
|
|
BMF_DrawString(G.font, files->relname);
|
|
|
|
|
|
|
|
if(files->nr) { /* extra info */
|
|
|
|
x+= sfile->maxnamelen+20;
|
|
|
|
glRasterPos2i(x, y);
|
|
|
|
BMF_DrawString(G.font, files->extra);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-07-23 10:49:04 +00:00
|
|
|
static int calc_filesel_line(SpaceFile *sfile, int nr, int *valx, int *valy)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2004-07-23 10:49:04 +00:00
|
|
|
/* get screen coordinate of a line */
|
2002-10-12 11:37:38 +00:00
|
|
|
int val, coll;
|
|
|
|
|
|
|
|
nr-= sfile->ofs;
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* amount of lines */
|
2002-10-12 11:37:38 +00:00
|
|
|
val= (textrct.ymax-textrct.ymin)/FILESEL_DY;
|
2004-03-02 16:49:50 +00:00
|
|
|
if (val == 0) coll = 0;
|
|
|
|
else coll= nr/val;
|
2002-10-12 11:37:38 +00:00
|
|
|
nr -= coll*val;
|
|
|
|
|
|
|
|
*valy= textrct.ymax-FILESEL_DY+3 - nr*FILESEL_DY;
|
|
|
|
*valx= coll*collumwidth + textrct.xmin+20;
|
|
|
|
|
|
|
|
if(nr<0 || coll > sfile->collums) return 0;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void set_active_file(SpaceFile *sfile, int act)
|
|
|
|
{
|
|
|
|
struct direntry *file;
|
2005-06-04 16:22:50 +00:00
|
|
|
int num, redraw= 0;
|
|
|
|
unsigned int newflag;
|
2002-10-12 11:37:38 +00:00
|
|
|
int old=0, newi=0;
|
|
|
|
|
|
|
|
file= sfile->filelist;
|
|
|
|
if(file==0) return;
|
|
|
|
|
|
|
|
for(num=0; num<sfile->totfile; num++, file++) {
|
|
|
|
if(num==act) {
|
|
|
|
|
|
|
|
if(selecting && num>1) {
|
|
|
|
newflag= HILITE | (file->flags & ~ACTIVE);
|
|
|
|
if(selecting==ACTIVATE) newflag |= ACTIVE;
|
|
|
|
|
|
|
|
if(file->flags != newflag) redraw|= 1;
|
|
|
|
file->flags= newflag;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if(file->flags & HILITE);
|
|
|
|
else {
|
|
|
|
file->flags |= HILITE;
|
|
|
|
redraw|= 2;
|
|
|
|
newi= num;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if(file->flags & HILITE) {
|
|
|
|
file->flags &= ~HILITE;
|
|
|
|
redraw|= 2;
|
|
|
|
old= num;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2005-05-11 20:51:11 +00:00
|
|
|
// removed frontbuffer draw here
|
|
|
|
if(redraw) {
|
2002-10-12 11:37:38 +00:00
|
|
|
scrarea_queue_winredraw(curarea);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void draw_filetext(SpaceFile *sfile)
|
|
|
|
{
|
|
|
|
struct direntry *files;
|
|
|
|
int a, x, y;
|
|
|
|
short mval[2];
|
|
|
|
|
|
|
|
if(textrct.ymin+10 >= textrct.ymax) return;
|
|
|
|
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* box */
|
2003-10-19 09:19:58 +00:00
|
|
|
BIF_ThemeColor(TH_BACK);
|
2002-10-12 11:37:38 +00:00
|
|
|
glRecti(textrct.xmin, textrct.ymin, textrct.xmax, textrct.ymax);
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* collums */
|
2002-10-12 11:37:38 +00:00
|
|
|
x= textrct.xmin+collumwidth;
|
|
|
|
for(a=1; a<sfile->collums; a++, x+= collumwidth) {
|
|
|
|
cpack(0x303030);
|
|
|
|
sdrawline(x, textrct.ymin, x, textrct.ymax);
|
|
|
|
cpack(0xB0B0B0);
|
|
|
|
sdrawline(x+1, textrct.ymin, x+1, textrct.ymax);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(sfile->filelist==0) return;
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* test: if mouse is not in area: clear HILITE */
|
2002-10-12 11:37:38 +00:00
|
|
|
getmouseco_areawin(mval);
|
|
|
|
|
|
|
|
if(mval[0]<0 || mval[0]>curarea->winx) {
|
|
|
|
files= sfile->filelist+sfile->ofs;
|
|
|
|
for(a= sfile->ofs; a<sfile->totfile; a++, files++) files->flags &= ~HILITE;
|
|
|
|
}
|
|
|
|
|
|
|
|
files= sfile->filelist+sfile->ofs;
|
|
|
|
for(a= sfile->ofs; a<sfile->totfile; a++, files++) {
|
|
|
|
|
2004-07-23 10:49:04 +00:00
|
|
|
if( calc_filesel_line(sfile, a, &x, &y)==0 ) break;
|
|
|
|
print_line(sfile, files, x, y);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* clear drawing errors, with text at the right hand side: */
|
2003-10-19 09:19:58 +00:00
|
|
|
BIF_ThemeColor(TH_HEADER);
|
2003-11-17 20:20:14 +00:00
|
|
|
glRecti(textrct.xmax, textrct.ymin, textrct.xmax+10, textrct.ymax);
|
|
|
|
uiEmboss(textrct.xmin, textrct.ymin, textrct.xmax, textrct.ymax, 1);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
2003-03-24 01:46:05 +00:00
|
|
|
void drawfilespace(ScrArea *sa, void *spacedata)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
|
|
|
SpaceFile *sfile;
|
|
|
|
uiBlock *block;
|
2003-10-18 12:21:41 +00:00
|
|
|
float col[3];
|
2002-10-12 11:37:38 +00:00
|
|
|
int act, loadbutton;
|
|
|
|
short mval[2];
|
|
|
|
char name[20];
|
|
|
|
char *menu;
|
|
|
|
|
2003-11-18 11:22:17 +00:00
|
|
|
myortho2(-0.375, sa->winx-0.375, -0.375, sa->winy-0.375);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2003-10-19 09:19:58 +00:00
|
|
|
BIF_GetThemeColor3fv(TH_HEADER, col); // basic undrawn color is border
|
2003-10-18 12:21:41 +00:00
|
|
|
glClearColor(col[0], col[1], col[2], 0.0);
|
2002-10-12 11:37:38 +00:00
|
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
|
2005-01-11 12:14:45 +00:00
|
|
|
sfile= sa->spacedata.first;
|
2004-07-23 10:49:04 +00:00
|
|
|
if(sfile->filelist==NULL) {
|
2002-10-12 11:37:38 +00:00
|
|
|
read_dir(sfile);
|
|
|
|
|
|
|
|
calc_file_rcts(sfile);
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* calculate act */
|
2002-10-12 11:37:38 +00:00
|
|
|
getmouseco_areawin(mval);
|
|
|
|
act= find_active_file(sfile, mval[0], mval[1]);
|
|
|
|
if(act>=0 && act<sfile->totfile)
|
|
|
|
sfile->filelist[act].flags |= HILITE;
|
|
|
|
}
|
|
|
|
else calc_file_rcts(sfile);
|
|
|
|
|
|
|
|
/* HEADER */
|
2005-01-11 12:14:45 +00:00
|
|
|
sprintf(name, "win %d", sa->win);
|
|
|
|
block= uiNewBlock(&sa->uiblocks, name, UI_EMBOSS, UI_HELV, sa->win);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
uiSetButLock( sfile->type==FILE_MAIN && sfile->returnfunc, NULL);
|
|
|
|
|
|
|
|
/* space available for load/save buttons? */
|
|
|
|
loadbutton= MAX2(80, 20+BMF_GetStringWidth(G.font, sfile->title));
|
|
|
|
if(textrct.xmax-textrct.xmin > loadbutton+20) {
|
|
|
|
if(sfile->title[0]==0) loadbutton= 0;
|
|
|
|
}
|
|
|
|
else loadbutton= 0;
|
|
|
|
|
Patch provided by Shaul Kedem: Compressed files are back!
He even made a nice doc in wiki:
http://wiki.blender.org/bin/view.pl/Blenderdev/Blendgz
Usage: set the option "Compress File" in the main "File" pulldown menu.
This setting is a user-def, meaning it is not changed on reading files.
If you want it default, save it with CTRL+U.
The longest debate went over the file naming convention. Shaul started
with .blend.gz files, which gave issues in Blender because of the code
hanging out everywhere that detects blender files, and that appends the
.blend extension if needed.
Daniel Dunbar proposed to just save it as .blend, and not bother users
with such details. This is indeed the most elegant solution, with as
only drawback that old Blender executables cannot read it.
This drawback isn't very relevant at the moment, since we're heading
towards a release that isn't upward compatible anyway... the recode
going on on Meshes, Modfiers, Armatures, Poses, Actions, NLA already
have upward compatibility issues.
We might check - during the next month(s) - on a builtin system to
warn users in the future when we change things that make a file risky
to read in an older release.
2005-07-27 19:46:06 +00:00
|
|
|
uiDefBut(block, TEX,1,"", textrct.xmin, filebuty1, textrct.xmax-textrct.xmin-loadbutton, 21, sfile->file, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
|
|
|
|
uiDefBut(block, TEX,2,"", textrct.xmin, filebuty2, textrct.xmax-textrct.xmin-loadbutton, 21, sfile->dir, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(loadbutton) {
|
|
|
|
uiSetCurFont(block, UI_HELV);
|
|
|
|
uiDefBut(block, BUT, 5, sfile->title, textrct.xmax-loadbutton, filebuty2, loadbutton, 21, sfile->dir, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
|
|
|
|
uiDefBut(block, BUT, 6, "Cancel", textrct.xmax-loadbutton, filebuty1, loadbutton, 21, sfile->file, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
|
|
|
|
}
|
|
|
|
|
|
|
|
menu= fsmenu_build_menu();
|
2003-07-05 10:50:42 +00:00
|
|
|
if(menu[0]) // happens when no .Bfs is there, and first time browse
|
|
|
|
uiDefButS(block, MENU, 3, menu, scrollrct.xmin, filebuty1, scrollrct.xmax-scrollrct.xmin, 21, &sfile->menu, 0, 0, 0, 0, "");
|
2002-10-12 11:37:38 +00:00
|
|
|
MEM_freeN(menu);
|
|
|
|
|
|
|
|
uiDefBut(block, BUT, 4, "P", scrollrct.xmin, filebuty2, scrollrct.xmax-scrollrct.xmin, 21, 0, 0, 0, 0, 0, "Move to the parent directory (PKEY)");
|
|
|
|
|
2003-07-05 10:50:42 +00:00
|
|
|
uiDrawBlock(block);
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
draw_filescroll(sfile);
|
|
|
|
draw_filetext(sfile);
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* others diskfree etc ? */
|
2005-01-11 12:14:45 +00:00
|
|
|
scrarea_queue_headredraw(sa);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2003-11-18 11:22:17 +00:00
|
|
|
myortho2(-0.375, (float)(sa->winx)-0.375, -0.375, (float)(sa->winy)-0.375);
|
2003-10-04 20:35:50 +00:00
|
|
|
draw_area_emboss(sa);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-01-11 12:14:45 +00:00
|
|
|
sa->win_swap= WIN_BACK_OK;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void do_filescroll(SpaceFile *sfile)
|
|
|
|
{
|
|
|
|
short mval[2], oldy, yo;
|
|
|
|
|
|
|
|
calc_file_rcts(sfile);
|
|
|
|
|
|
|
|
filescrollselect= 1;
|
2005-05-11 20:51:11 +00:00
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* for beauty */
|
2005-05-11 20:51:11 +00:00
|
|
|
scrarea_do_windraw(curarea);
|
|
|
|
screen_swapbuffers();
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
getmouseco_areawin(mval);
|
|
|
|
oldy= yo= mval[1];
|
|
|
|
|
|
|
|
while(get_mbut()&L_MOUSE) {
|
|
|
|
getmouseco_areawin(mval);
|
|
|
|
|
|
|
|
if(yo!=mval[1]) {
|
|
|
|
int dy= floor(0.5+((float)(oldy-mval[1]))*pixels_to_ofs);
|
|
|
|
|
|
|
|
if(dy) {
|
|
|
|
sfile->ofs+= dy;
|
|
|
|
if(sfile->ofs<0) {
|
|
|
|
sfile->ofs= 0;
|
|
|
|
oldy= mval[1];
|
|
|
|
}
|
|
|
|
else oldy= floor(0.5+ (float)oldy - (float)dy/pixels_to_ofs);
|
|
|
|
|
|
|
|
scrarea_do_windraw(curarea);
|
|
|
|
screen_swapbuffers();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
yo= mval[1];
|
|
|
|
}
|
|
|
|
else BIF_wait_for_statechange();
|
|
|
|
}
|
|
|
|
filescrollselect= 0;
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* for beauty */
|
2005-05-11 20:51:11 +00:00
|
|
|
scrarea_do_windraw(curarea);
|
|
|
|
screen_swapbuffers();
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2003-01-27 23:57:43 +00:00
|
|
|
static void do_filescrollwheel(SpaceFile *sfile, int move)
|
|
|
|
{
|
|
|
|
// by phase
|
|
|
|
int lines, rt;
|
|
|
|
|
|
|
|
calc_file_rcts(sfile);
|
|
|
|
|
|
|
|
lines = (int)(textrct.ymax-textrct.ymin)/FILESEL_DY;
|
|
|
|
rt = lines * sfile->collums;
|
|
|
|
|
|
|
|
if(sfile->totfile > rt) {
|
|
|
|
sfile->ofs+= move;
|
|
|
|
if( sfile->ofs + rt > sfile->totfile + 1)
|
|
|
|
sfile->ofs = sfile->totfile - rt + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(sfile->ofs<0) {
|
|
|
|
sfile->ofs= 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
void activate_fileselect(int type, char *title, char *file, void (*func)(char *))
|
|
|
|
{
|
|
|
|
SpaceFile *sfile;
|
|
|
|
char group[24], name[FILE_MAXDIR], temp[FILE_MAXDIR];
|
|
|
|
|
|
|
|
if(curarea==0) return;
|
|
|
|
if(curarea->win==0) return;
|
|
|
|
|
|
|
|
newspace(curarea, SPACE_FILE);
|
|
|
|
scrarea_queue_winredraw(curarea);
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* sometime double, when area already is SPACE_FILE with a different file name */
|
2005-07-13 13:30:51 +00:00
|
|
|
if(curarea->headwin) addqueue(curarea->headwin, CHANGED, 1);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
name[2]= 0;
|
|
|
|
strcpy(name, file);
|
|
|
|
|
|
|
|
sfile= curarea->spacedata.first;
|
|
|
|
/* sfile wants a (*)(short), but get (*)(char*) */
|
|
|
|
sfile->returnfunc= func;
|
|
|
|
sfile->type= type;
|
|
|
|
sfile->ofs= 0;
|
2003-04-30 13:22:26 +00:00
|
|
|
/* sfile->act is used for databrowse: double names of library objects */
|
2002-10-12 11:37:38 +00:00
|
|
|
sfile->act= -1;
|
|
|
|
|
|
|
|
if(BLI_convertstringcode(name, G.sce, G.scene->r.cfra)) sfile->flag |= FILE_STRINGCODE;
|
|
|
|
else sfile->flag &= ~FILE_STRINGCODE;
|
|
|
|
|
2005-07-11 23:49:06 +00:00
|
|
|
if (U.uiflag & USER_HIDE_DOT)
|
|
|
|
sfile->flag |= FILE_HIDE_DOT;
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(type==FILE_MAIN) {
|
|
|
|
char *groupname;
|
|
|
|
|
|
|
|
strcpy(sfile->file, name+2);
|
|
|
|
|
|
|
|
groupname = BLO_idcode_to_name( GS(name) );
|
|
|
|
if (groupname) {
|
|
|
|
strcpy(sfile->dir, groupname);
|
|
|
|
strcat(sfile->dir, "/");
|
|
|
|
}
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* free all */
|
2002-10-12 11:37:38 +00:00
|
|
|
if(sfile->libfiledata) BLO_blendhandle_close(sfile->libfiledata);
|
|
|
|
sfile->libfiledata= 0;
|
|
|
|
|
|
|
|
freefilelist(sfile);
|
|
|
|
}
|
|
|
|
else if(type==FILE_LOADLIB) {
|
|
|
|
strcpy(sfile->dir, name);
|
|
|
|
if( is_a_library(sfile, temp, group) ) {
|
2004-07-23 10:49:04 +00:00
|
|
|
/* force a reload of the library-filelist */
|
|
|
|
freefilelist(sfile);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
split_sfile(sfile, name);
|
|
|
|
if(sfile->libfiledata) BLO_blendhandle_close(sfile->libfiledata);
|
2004-07-23 10:49:04 +00:00
|
|
|
sfile->libfiledata= NULL;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else { /* FILE_BLENDER */
|
2003-04-30 13:22:26 +00:00
|
|
|
split_sfile(sfile, name); /* test filelist too */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* free: filelist and libfiledata became incorrect */
|
2002-10-12 11:37:38 +00:00
|
|
|
if(sfile->libfiledata) BLO_blendhandle_close(sfile->libfiledata);
|
|
|
|
sfile->libfiledata= 0;
|
|
|
|
}
|
|
|
|
BLI_strncpy(sfile->title, title, sizeof(sfile->title));
|
|
|
|
filetoname= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void activate_imageselect(int type, char *title, char *file, void (*func)(char *))
|
|
|
|
{
|
|
|
|
SpaceImaSel *simasel;
|
|
|
|
char dir[FILE_MAXDIR], name[FILE_MAXFILE];
|
|
|
|
|
|
|
|
if(curarea==0) return;
|
|
|
|
if(curarea->win==0) return;
|
|
|
|
|
|
|
|
newspace(curarea, SPACE_IMASEL);
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* sometimes double, when area is already SPACE_FILE with a different file name */
|
2002-10-12 11:37:38 +00:00
|
|
|
addqueue(curarea->headwin, CHANGED, 1);
|
|
|
|
addqueue(curarea->win, CHANGED, 1);
|
|
|
|
|
|
|
|
name[2]= 0;
|
|
|
|
strcpy(name, file);
|
|
|
|
|
|
|
|
simasel= curarea->spacedata.first;
|
|
|
|
simasel->returnfunc= func;
|
|
|
|
|
|
|
|
if(BLI_convertstringcode(name, G.sce, G.scene->r.cfra)) simasel->mode |= IMS_STRINGCODE;
|
|
|
|
else simasel->mode &= ~IMS_STRINGCODE;
|
|
|
|
|
|
|
|
BLI_split_dirfile(name, dir, simasel->file);
|
|
|
|
if(strcmp(dir, simasel->dir)!=0) simasel->fase= 0;
|
|
|
|
strcpy(simasel->dir, dir);
|
|
|
|
|
|
|
|
BLI_strncpy(simasel->title, title, sizeof(simasel->title));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* filetoname= 1; */
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void activate_databrowse(ID *id, int idcode, int fromcode, int retval, short *menup, void (*func)(unsigned short))
|
|
|
|
{
|
|
|
|
ListBase *lb;
|
|
|
|
SpaceFile *sfile;
|
|
|
|
char str[32];
|
|
|
|
|
|
|
|
if(id==0) {
|
|
|
|
lb= wich_libbase(G.main, idcode);
|
2003-06-27 15:26:23 +00:00
|
|
|
id= lb->last;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(id) strcpy(str, id->name);
|
|
|
|
else return;
|
|
|
|
|
|
|
|
activate_fileselect(FILE_MAIN, "SELECT DATABLOCK", str, (void (*) (char*))func);
|
|
|
|
|
|
|
|
sfile= curarea->spacedata.first;
|
|
|
|
sfile->retval= retval;
|
|
|
|
sfile->ipotype= fromcode;
|
|
|
|
sfile->menup= menup;
|
|
|
|
}
|
|
|
|
|
|
|
|
void filesel_prevspace()
|
|
|
|
{
|
|
|
|
SpaceFile *sfile;
|
|
|
|
|
|
|
|
sfile= curarea->spacedata.first;
|
|
|
|
if(sfile->next) {
|
|
|
|
|
|
|
|
BLI_remlink(&curarea->spacedata, sfile);
|
|
|
|
BLI_addtail(&curarea->spacedata, sfile);
|
|
|
|
|
|
|
|
sfile= curarea->spacedata.first;
|
2003-12-14 01:18:09 +00:00
|
|
|
|
|
|
|
if (sfile->spacetype == SPACE_SCRIPT) {
|
|
|
|
SpaceScript *sc = (SpaceScript *)sfile;
|
|
|
|
if (sc->script) sc->script->flags &=~SCRIPT_FILESEL;
|
|
|
|
}
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
newspace(curarea, sfile->spacetype);
|
|
|
|
}
|
|
|
|
else newspace(curarea, SPACE_INFO);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int countselect(SpaceFile *sfile)
|
|
|
|
{
|
|
|
|
int a, count=0;
|
|
|
|
|
|
|
|
for(a=0; a<sfile->totfile; a++) {
|
|
|
|
if(sfile->filelist[a].flags & ACTIVE) {
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int getotherdir(void)
|
|
|
|
{
|
|
|
|
ScrArea *sa;
|
|
|
|
SpaceFile *sfile=0;
|
|
|
|
|
|
|
|
sa= G.curscreen->areabase.first;
|
|
|
|
while(sa) {
|
|
|
|
if(sa!=curarea) {
|
|
|
|
if(sa->spacetype==SPACE_FILE) {
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* already found one */
|
2002-10-12 11:37:38 +00:00
|
|
|
if(sfile) return 0;
|
|
|
|
|
|
|
|
sfile= sa->spacedata.first;
|
|
|
|
|
|
|
|
if(sfile->type & FILE_UNIX) {
|
|
|
|
otherarea= sa;
|
|
|
|
BLI_make_file_string(G.sce, otherdir, sfile->dir, "");
|
|
|
|
}
|
|
|
|
else sfile= 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sa= sa->next;
|
|
|
|
}
|
|
|
|
if(sfile) return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void reread_other_fs(void)
|
|
|
|
{
|
|
|
|
SpaceFile *sfile;
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* watch it: only call when getotherdir returned OK */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
sfile= otherarea->spacedata.first;
|
|
|
|
freefilelist(sfile);
|
|
|
|
scrarea_queue_winredraw(otherarea);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void free_filesel_spec(char *dir)
|
|
|
|
{
|
2003-04-30 13:22:26 +00:00
|
|
|
/* all filesels with 'dir' are freed */
|
2002-10-12 11:37:38 +00:00
|
|
|
bScreen *sc;
|
|
|
|
|
|
|
|
sc= G.main->screen.first;
|
|
|
|
while(sc) {
|
|
|
|
ScrArea *sa= sc->areabase.first;
|
|
|
|
while(sa) {
|
|
|
|
SpaceLink *sl= sa->spacedata.first;
|
|
|
|
while(sl) {
|
|
|
|
if(sl->spacetype==SPACE_FILE) {
|
|
|
|
SpaceFile *sfile= (SpaceFile*) sl;
|
|
|
|
if (BLI_streq(sfile->dir, dir)) {
|
|
|
|
freefilelist(sfile);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sl= sl->next;
|
|
|
|
}
|
|
|
|
sa= sa->next;
|
|
|
|
}
|
|
|
|
sc= sc->id.next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void filesel_execute(SpaceFile *sfile)
|
|
|
|
{
|
|
|
|
struct direntry *files;
|
|
|
|
char name[FILE_MAXDIR];
|
|
|
|
int a;
|
|
|
|
|
|
|
|
filesel_prevspace();
|
|
|
|
|
|
|
|
if(sfile->type==FILE_LOADLIB) {
|
|
|
|
do_library_append(sfile);
|
2004-10-31 21:11:03 +00:00
|
|
|
BIF_undo_push("Append from file");
|
2002-10-12 11:37:38 +00:00
|
|
|
allqueue(REDRAWALL, 1);
|
|
|
|
}
|
|
|
|
else if(sfile->returnfunc) {
|
|
|
|
fsmenu_insert_entry(sfile->dir, 1);
|
|
|
|
|
2005-07-14 06:25:02 +00:00
|
|
|
if(sfile->type==FILE_MAIN) { /* DATABROWSE */
|
|
|
|
if (sfile->menup) { /* with value pointing to ID block index */
|
|
|
|
int notfound = 1;
|
|
|
|
|
|
|
|
/* Need special handling since hiding .* datablocks means that
|
|
|
|
sfile->act is no longer the same as files->nr.
|
|
|
|
|
|
|
|
Also, toggle HIDE_DOT on and off can make sfile->act not longer
|
|
|
|
correct (meaning it doesn't point to the correct item in the filelist.
|
|
|
|
|
|
|
|
sfile->file is always correct, so first with check if, for the item
|
|
|
|
corresponding to sfile->act, the name is the same.
|
|
|
|
|
|
|
|
If it isn't (or if sfile->act is not good), go over filelist and take
|
|
|
|
the correct one.
|
|
|
|
|
|
|
|
This means that selecting a datablock than hiding it makes it
|
|
|
|
unselectable. Not really a problem.
|
|
|
|
|
|
|
|
- theeth
|
|
|
|
*/
|
|
|
|
|
|
|
|
*sfile->menup= -1;
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(sfile->act>=0) {
|
|
|
|
if(sfile->filelist) {
|
|
|
|
files= sfile->filelist+sfile->act;
|
2005-07-14 06:25:02 +00:00
|
|
|
if ( strcmp(files->relname, sfile->file)==0) {
|
|
|
|
notfound = 0;
|
|
|
|
*sfile->menup= files->nr;
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
2005-07-14 06:25:02 +00:00
|
|
|
if (notfound) {
|
2002-10-12 11:37:38 +00:00
|
|
|
for(a=0; a<sfile->totfile; a++) {
|
|
|
|
if( strcmp(sfile->filelist[a].relname, sfile->file)==0) {
|
2005-07-14 06:25:02 +00:00
|
|
|
*sfile->menup= sfile->filelist[a].nr;
|
2002-10-12 11:37:38 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-10-07 18:24:02 +00:00
|
|
|
sfile->returnfunc((char*) (long)sfile->retval);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
else {
|
2004-07-23 10:49:04 +00:00
|
|
|
if(strncmp(sfile->title, "Save", 4)==0) free_filesel_spec(sfile->dir);
|
2004-11-24 18:02:07 +00:00
|
|
|
if(strncmp(sfile->title, "Export", 6)==0) free_filesel_spec(sfile->dir);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
strcpy(name, sfile->dir);
|
|
|
|
strcat(name, sfile->file);
|
|
|
|
|
|
|
|
if(sfile->flag & FILE_STRINGCODE) BLI_makestringcode(G.sce, name);
|
|
|
|
|
|
|
|
sfile->returnfunc(name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void do_filesel_buttons(short event, SpaceFile *sfile)
|
|
|
|
{
|
|
|
|
char butname[FILE_MAXDIR];
|
|
|
|
|
|
|
|
if (event == 1) {
|
|
|
|
if (strchr(sfile->file, '*') || strchr(sfile->file, '?') || strchr(sfile->file, '[')) {
|
|
|
|
int i, match = FALSE;
|
|
|
|
|
|
|
|
for (i = 2; i < sfile->totfile; i++) {
|
|
|
|
if (fnmatch(sfile->file, sfile->filelist[i].relname, 0) == 0) {
|
|
|
|
sfile->filelist[i].flags |= ACTIVE;
|
|
|
|
match = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (match) strcpy(sfile->file, "");
|
|
|
|
if(sfile->type==FILE_MAIN) filesel_select_objects(sfile);
|
|
|
|
scrarea_queue_winredraw(curarea);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(event== 2) {
|
|
|
|
/* reuse the butname variable */
|
|
|
|
checkdir(sfile->dir);
|
|
|
|
|
|
|
|
BLI_make_file_string(G.sce, butname, sfile->dir, "");
|
|
|
|
/* strip the trailing slash if its a real dir */
|
|
|
|
if (strlen(butname)!=1)
|
|
|
|
butname[strlen(butname)-1]=0;
|
|
|
|
|
|
|
|
if(sfile->type & FILE_UNIX) {
|
|
|
|
if (!BLI_exists(butname)) {
|
|
|
|
if (okee("Makedir")) {
|
|
|
|
BLI_recurdir_fileops(butname);
|
|
|
|
if (!BLI_exists(butname)) parent(sfile);
|
|
|
|
} else parent(sfile);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
freefilelist(sfile);
|
|
|
|
sfile->ofs= 0;
|
|
|
|
scrarea_queue_winredraw(curarea);
|
|
|
|
}
|
|
|
|
else if(event== 3) {
|
|
|
|
char *selected= fsmenu_get_entry(sfile->menu-1);
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* which string */
|
2002-10-12 11:37:38 +00:00
|
|
|
if (selected) {
|
|
|
|
strcpy(sfile->dir, selected);
|
|
|
|
BLI_make_exist(sfile->dir);
|
|
|
|
checkdir(sfile->dir);
|
|
|
|
freefilelist(sfile);
|
|
|
|
sfile->ofs= 0;
|
|
|
|
scrarea_queue_winredraw(curarea);
|
|
|
|
}
|
|
|
|
|
|
|
|
sfile->act= -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
else if(event== 4) parent(sfile);
|
|
|
|
else if(event== 5) {
|
|
|
|
if(sfile->type) filesel_execute(sfile);
|
|
|
|
}
|
|
|
|
else if(event== 6) filesel_prevspace();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/****/
|
|
|
|
|
|
|
|
typedef void (*ReplaceFP)(ID *oldblock, ID *newblock);
|
|
|
|
|
|
|
|
static void change_id_link(void *linkpv, void *newlinkv) {
|
|
|
|
ID **linkp= (ID**) linkpv;
|
|
|
|
ID *newlink= newlinkv;
|
|
|
|
|
|
|
|
if (*linkp) {
|
|
|
|
(*linkp)->us--;
|
|
|
|
}
|
|
|
|
(*linkp)= newlink;
|
|
|
|
if (newlink) {
|
|
|
|
id_us_plus(newlink);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void replace_image(ID *oldblock, ID *newblock) {
|
|
|
|
Image *oldima= (Image*) oldblock;
|
|
|
|
Image *newima= (Image*) newblock;
|
|
|
|
bScreen *sc;
|
|
|
|
Scene *sce;
|
|
|
|
Tex *tex;
|
|
|
|
Mesh *me;
|
|
|
|
|
|
|
|
for (tex= G.main->tex.first; tex; tex= tex->id.next) {
|
|
|
|
if (tex->env && tex->env->type == ENV_LOAD && tex->env->ima == oldima)
|
|
|
|
change_id_link(&tex->env->ima, newima);
|
|
|
|
if (tex->ima == oldima)
|
|
|
|
change_id_link(&tex->ima, newima);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (sce= G.main->scene.first; sce; sce= sce->id.next) {
|
|
|
|
if (sce->ima == oldima)
|
|
|
|
change_id_link(&sce->ima, newima);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (sc= G.main->screen.first; sc; sc= sc->id.next) {
|
|
|
|
ScrArea *sa;
|
|
|
|
|
|
|
|
for (sa= sc->areabase.first; sa; sa= sa->next) {
|
|
|
|
SpaceLink *sl;
|
|
|
|
|
|
|
|
for (sl= sa->spacedata.first; sl; sl= sl->next) {
|
|
|
|
if (sl->spacetype == SPACE_VIEW3D) {
|
|
|
|
View3D *v3d= (View3D*) sl;
|
|
|
|
BGpic *bgp= v3d->bgpic;
|
|
|
|
|
|
|
|
if (bgp && bgp->ima == oldima)
|
|
|
|
change_id_link(&bgp->ima, newima);
|
|
|
|
} else if (sl->spacetype == SPACE_IMAGE) {
|
|
|
|
SpaceImage *sima= (SpaceImage*) sl;
|
|
|
|
|
|
|
|
if (sima->image == oldima)
|
|
|
|
change_id_link(&sima->image, newima);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (me= G.main->mesh.first; me; me= me->id.next) {
|
|
|
|
TFace *tfaces= me->tface;
|
|
|
|
|
|
|
|
if (tfaces) {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i=0; i<me->totface; i++) {
|
|
|
|
TFace *tf= &tfaces[i];
|
|
|
|
|
|
|
|
if (tf->tpage == oldima) {
|
|
|
|
/* not change_id_link, tpage's aren't owners :(
|
|
|
|
* see hack below.
|
|
|
|
*/
|
|
|
|
tf->tpage= newima;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Nasty hack, necessary because tpages don't act
|
|
|
|
* as a user, so there lots of image user count
|
|
|
|
* munging occurs... this will ensure the image
|
|
|
|
* really dies.
|
|
|
|
*/
|
|
|
|
oldima->id.us= 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void replace_material(ID *oldblock, ID *newblock)
|
|
|
|
{
|
|
|
|
Material *old= (Material*) oldblock;
|
|
|
|
Material *new= (Material*) newblock;
|
|
|
|
Material ***matarar;
|
|
|
|
ID *id;
|
|
|
|
Object *ob;
|
|
|
|
int a;
|
|
|
|
|
|
|
|
ob= G.main->object.first;
|
|
|
|
while(ob) {
|
|
|
|
if(ob->totcol && ob->id.lib==0) {
|
|
|
|
matarar= give_matarar(ob);
|
|
|
|
for(a=1; a<=ob->totcol; a++) {
|
|
|
|
if(ob->mat[a-1] == old) {
|
|
|
|
if(old) old->id.us--;
|
|
|
|
id_us_plus((ID *)new);
|
|
|
|
ob->mat[a-1]= new;
|
|
|
|
}
|
|
|
|
id= ob->data;
|
|
|
|
if( (*matarar)[a-1] == old && id->lib==0) {
|
|
|
|
if(old) old->id.us--;
|
|
|
|
id_us_plus((ID *)new);
|
|
|
|
(*matarar)[a-1]= new;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ob= ob->id.next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static ReplaceFP get_id_replace_function(int idcode) {
|
|
|
|
switch (idcode) {
|
|
|
|
case ID_MA:
|
|
|
|
return &replace_material;
|
|
|
|
case ID_IM:
|
|
|
|
return &replace_image;
|
|
|
|
default:
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void databrowse_replace(SpaceFile *sfile, int idcode)
|
|
|
|
{
|
|
|
|
ReplaceFP replace_func= get_id_replace_function(idcode);
|
|
|
|
|
|
|
|
if (!replace_func) {
|
|
|
|
error("Replacing %s blocks is unsupported", BLO_idcode_to_name(idcode));
|
|
|
|
} else if (sfile->act==-1) {
|
|
|
|
error("Select target with leftmouse");
|
|
|
|
} else {
|
|
|
|
ID *target= (ID*) sfile->filelist[sfile->act].poin;
|
|
|
|
|
|
|
|
if (target) {
|
|
|
|
char buf[128];
|
|
|
|
|
|
|
|
sprintf(buf, "Replace with %s: %s", BLO_idcode_to_name(idcode), target->name+2);
|
|
|
|
|
|
|
|
if (okee(buf)) {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i <sfile->totfile; i++)
|
|
|
|
if ((sfile->filelist[i].flags&ACTIVE) && sfile->filelist[i].poin!=target)
|
|
|
|
replace_func(sfile->filelist[i].poin, target);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
freefilelist(sfile);
|
|
|
|
scrarea_queue_winredraw(curarea);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void fs_fake_users(SpaceFile *sfile)
|
|
|
|
{
|
|
|
|
ID *id;
|
|
|
|
int a;
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* only for F4 DATABROWSE */
|
2002-10-12 11:37:38 +00:00
|
|
|
if(sfile->returnfunc) return;
|
|
|
|
|
|
|
|
for(a=0; a<sfile->totfile; a++) {
|
|
|
|
if(sfile->filelist[a].flags & ACTIVE) {
|
|
|
|
id= (ID *)sfile->filelist[a].poin;
|
|
|
|
if(id) {
|
|
|
|
if( id->flag & LIB_FAKEUSER) {
|
|
|
|
id->flag -= LIB_FAKEUSER;
|
|
|
|
id->us--;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
id->flag |= LIB_FAKEUSER;
|
|
|
|
id->us++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
freefilelist(sfile);
|
|
|
|
scrarea_queue_winredraw(curarea);
|
|
|
|
}
|
|
|
|
|
2003-04-28 11:17:21 +00:00
|
|
|
|
|
|
|
static int get_hilited_entry(SpaceFile *sfile)
|
|
|
|
{
|
2003-08-14 15:18:45 +00:00
|
|
|
int a;
|
2003-04-28 11:17:21 +00:00
|
|
|
|
|
|
|
for(a=0; a<sfile->totfile; a++) {
|
|
|
|
if(sfile->filelist[a].flags & HILITE) {
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-03-24 01:46:05 +00:00
|
|
|
void winqreadfilespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2003-03-24 01:46:05 +00:00
|
|
|
unsigned short event= evt->event;
|
|
|
|
short val= evt->val;
|
2002-10-12 11:37:38 +00:00
|
|
|
static int acto=0;
|
|
|
|
SpaceFile *sfile;
|
|
|
|
int act, do_draw= 0, i, test, ret = 0;
|
|
|
|
short qual, mval[2];
|
|
|
|
char str[FILE_MAXDIR+FILE_MAXFILE+12];
|
|
|
|
|
|
|
|
sfile= curarea->spacedata.first;
|
|
|
|
if(sfile==0) return;
|
|
|
|
if(sfile->filelist==0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(curarea->win==0) return;
|
|
|
|
calc_file_rcts(sfile);
|
|
|
|
getmouseco_areawin(mval);
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* prevent looping */
|
2002-10-12 11:37:38 +00:00
|
|
|
if(selecting && !(get_mbut() & R_MOUSE)) selecting= 0;
|
|
|
|
|
|
|
|
if(val) {
|
|
|
|
|
|
|
|
if( event!=RETKEY && event!=PADENTER)
|
|
|
|
if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0;
|
|
|
|
|
|
|
|
switch(event) {
|
|
|
|
|
|
|
|
case UI_BUT_EVENT:
|
|
|
|
do_filesel_buttons(val, sfile);
|
|
|
|
break;
|
|
|
|
|
2003-01-27 23:57:43 +00:00
|
|
|
case WHEELDOWNMOUSE:
|
2003-01-28 11:14:38 +00:00
|
|
|
do_filescrollwheel(sfile, U.wheellinescroll);
|
2003-01-27 23:57:43 +00:00
|
|
|
act= find_active_file(sfile, mval[0], mval[1]);
|
|
|
|
set_active_file(sfile, act);
|
|
|
|
do_draw= 1;
|
|
|
|
break;
|
|
|
|
case WHEELUPMOUSE:
|
2003-01-28 11:14:38 +00:00
|
|
|
do_filescrollwheel(sfile, -U.wheellinescroll);
|
2003-01-27 23:57:43 +00:00
|
|
|
act= find_active_file(sfile, mval[0], mval[1]);
|
|
|
|
set_active_file(sfile, act);
|
|
|
|
do_draw= 1;
|
|
|
|
break;
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
case LEFTMOUSE:
|
|
|
|
case MIDDLEMOUSE:
|
|
|
|
if(mval[0]>scrollrct.xmin && mval[0]<scrollrct.xmax && mval[1]>scrollrct.ymin && mval[1]<scrollrct.ymax) {
|
|
|
|
do_filescroll(sfile);
|
|
|
|
}
|
|
|
|
else if(mval[0]>textrct.xmin && mval[0]<textrct.xmax && mval[1]>textrct.ymin && mval[1]<textrct.ymax) {
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* sfile->act is used in databrowse: double names of library objects */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
sfile->act= act= find_active_file(sfile, mval[0], mval[1]);
|
|
|
|
|
|
|
|
if(act>=0 && act<sfile->totfile) {
|
|
|
|
if(S_ISDIR(sfile->filelist[act].type)) {
|
|
|
|
strcat(sfile->dir, sfile->filelist[act].relname);
|
|
|
|
strcat(sfile->dir,"/");
|
|
|
|
checkdir(sfile->dir);
|
|
|
|
freefilelist(sfile);
|
|
|
|
sfile->ofs= 0;
|
|
|
|
do_draw= 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if( strcmp(sfile->file, sfile->filelist[act].relname)) {
|
|
|
|
do_draw= 1;
|
|
|
|
strcpy(sfile->file, sfile->filelist[act].relname);
|
|
|
|
}
|
|
|
|
if(event==MIDDLEMOUSE && sfile->type) filesel_execute(sfile);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RIGHTMOUSE:
|
|
|
|
act= find_active_file(sfile, mval[0], mval[1]);
|
|
|
|
acto= act;
|
|
|
|
if(act>=0 && act<sfile->totfile) {
|
|
|
|
|
|
|
|
if (sfile->filelist[act].flags & ACTIVE) {
|
|
|
|
sfile->filelist[act].flags &= ~ACTIVE;
|
|
|
|
selecting = INACTIVATE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
test= sfile->filelist[act].relname[0];
|
|
|
|
if (act>=2 || test!='.') sfile->filelist[act].flags |= ACTIVE;
|
|
|
|
|
|
|
|
selecting = ACTIVATE;
|
|
|
|
}
|
|
|
|
do_draw= 1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MOUSEY:
|
|
|
|
act= find_active_file(sfile, mval[0], mval[1]);
|
|
|
|
if (act!=acto) {
|
|
|
|
set_active_file(sfile, act);
|
|
|
|
}
|
|
|
|
if(selecting && act!=acto) {
|
|
|
|
|
|
|
|
while(1) {
|
|
|
|
if (acto >= 2 && acto < sfile->totfile) {
|
|
|
|
if (selecting == ACTIVATE) sfile->filelist[acto].flags |= ACTIVE;
|
|
|
|
else if (selecting == INACTIVATE) sfile->filelist[acto].flags &= ~ACTIVE;
|
|
|
|
}
|
|
|
|
if (acto < act) acto++;
|
|
|
|
else if (acto > act) acto--;
|
|
|
|
else break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
acto= act;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PAGEUPKEY:
|
|
|
|
sfile->ofs-= page_ofs;
|
|
|
|
do_draw= 1;
|
|
|
|
break;
|
|
|
|
case PAGEDOWNKEY:
|
|
|
|
sfile->ofs+= page_ofs;
|
|
|
|
do_draw= 1;
|
|
|
|
break;
|
|
|
|
case HOMEKEY:
|
|
|
|
sfile->ofs= 0;
|
|
|
|
do_draw= 1;
|
|
|
|
break;
|
|
|
|
case ENDKEY:
|
|
|
|
sfile->ofs= sfile->totfile;
|
|
|
|
do_draw= 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case AKEY:
|
|
|
|
swapselect_file(sfile);
|
|
|
|
if(sfile->type==FILE_MAIN) filesel_select_objects(sfile);
|
|
|
|
do_draw= 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BKEY:
|
|
|
|
case CKEY:
|
|
|
|
case LKEY:
|
|
|
|
if(event==LKEY && sfile->type==FILE_MAIN && (G.qual & LR_CTRLKEY)) {
|
|
|
|
databrowse_replace(sfile, groupname_to_code(sfile->dir));
|
|
|
|
break;
|
|
|
|
}
|
2003-04-30 13:22:26 +00:00
|
|
|
/* pass */
|
2002-10-12 11:37:38 +00:00
|
|
|
case MKEY:
|
|
|
|
if(sfile->type==FILE_MAIN) break;
|
|
|
|
|
|
|
|
if(!countselect(sfile)) {
|
|
|
|
error("No files selected");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!getotherdir()) {
|
|
|
|
error("No second fileselect");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!strcmp(sfile->dir, otherdir)) {
|
|
|
|
error("Same directories");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(event==BKEY) sprintf(str, "Backup to %s", otherdir);
|
|
|
|
else if(event==CKEY) sprintf(str, "Copy to %s", otherdir);
|
|
|
|
else if(event==LKEY) sprintf(str, "Linked copy to %s", otherdir);
|
|
|
|
else if(event==MKEY) sprintf(str, "Move to %s", otherdir);
|
|
|
|
|
|
|
|
if (!okee(str)) break;
|
|
|
|
|
|
|
|
for (i = 0; i<sfile->totfile; i++){
|
|
|
|
if (sfile->filelist[i].flags & ACTIVE) {
|
|
|
|
BLI_make_file_string(G.sce, str, sfile->dir, sfile->filelist[i].relname);
|
|
|
|
|
|
|
|
if(event==BKEY) ret= BLI_backup(sfile->filelist[i].relname, sfile->dir, otherdir);
|
|
|
|
else if(event==CKEY) ret= BLI_copy_fileops(str, otherdir);
|
|
|
|
else if(event==LKEY) ret= BLI_link(str, otherdir);
|
|
|
|
else if(event==MKEY) ret= BLI_move(str, otherdir);
|
|
|
|
|
|
|
|
if (ret) {error("Command failed, see console"); break;}
|
|
|
|
else sfile->filelist[i].flags &= ~ACTIVE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
do_draw= 1;
|
|
|
|
if(event==BKEY || event==MKEY)
|
|
|
|
freefilelist(sfile);
|
|
|
|
|
|
|
|
reread_other_fs();
|
|
|
|
|
|
|
|
break;
|
2003-04-28 11:17:21 +00:00
|
|
|
|
|
|
|
case XKEY:
|
|
|
|
test = get_hilited_entry(sfile);
|
|
|
|
|
|
|
|
if (test != -1 && !(S_ISDIR(sfile->filelist[test].type))){
|
|
|
|
BLI_make_file_string(G.sce, str, sfile->dir, sfile->filelist[test].relname);
|
|
|
|
|
|
|
|
if( okee("Remove %s", str) ) {
|
|
|
|
ret = BLI_delete(str, 0, 0);
|
|
|
|
if (ret) {
|
|
|
|
error("Command failed, see console");
|
|
|
|
} else {
|
|
|
|
freefilelist(sfile);
|
|
|
|
do_draw= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
case RKEY:
|
|
|
|
if(sfile->type==FILE_MAIN) {
|
|
|
|
databrowse_replace(sfile, groupname_to_code(sfile->dir));
|
|
|
|
break;
|
|
|
|
}
|
2003-04-30 13:22:26 +00:00
|
|
|
/* pass to TKEY! */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
case TKEY:
|
|
|
|
if(sfile->type==FILE_MAIN) break;
|
|
|
|
|
|
|
|
if(!countselect(sfile)) {
|
|
|
|
error("No files selected");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(event==TKEY) sprintf(str, "Touch");
|
|
|
|
else if(event==RKEY) sprintf(str, "Remove from %s", sfile->dir);
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
qual= G.qual; /* because after okee() you released the SHIFT */
|
2002-10-12 11:37:38 +00:00
|
|
|
if (!okee(str)) break;
|
|
|
|
|
|
|
|
for (i = 0; i <sfile->totfile; i++) {
|
|
|
|
if (sfile->filelist[i].flags & ACTIVE) {
|
|
|
|
BLI_make_file_string(G.sce, str, sfile->dir, sfile->filelist[i].relname);
|
|
|
|
|
|
|
|
if(event==TKEY) ret= BLI_touch(str);
|
|
|
|
else if(event==RKEY) {
|
|
|
|
if(qual & LR_SHIFTKEY) ret= BLI_delete(str, 0, 1);
|
|
|
|
else if(S_ISDIR(sfile->filelist[i].type)) ret= BLI_delete(str, 1, 0);
|
|
|
|
else ret= BLI_delete(str, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ret) {error("Command failed, see console"); break;}
|
|
|
|
else sfile->filelist[i].flags &= ~ACTIVE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
do_draw= 1;
|
|
|
|
freefilelist(sfile);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PKEY:
|
|
|
|
if(G.qual & LR_SHIFTKEY) {
|
|
|
|
extern char bprogname[]; /* usiblender.c */
|
|
|
|
|
|
|
|
sprintf(str, "%s -a \"%s%s\"", bprogname, sfile->dir, sfile->file);
|
|
|
|
system(str);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
parent(sfile);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IKEY:
|
|
|
|
if(sfile->type==FILE_MAIN) break;
|
|
|
|
|
|
|
|
sprintf(str, "$IMAGEEDITOR %s%s", sfile->dir, sfile->file);
|
|
|
|
system(str);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EKEY:
|
|
|
|
if(sfile->type==FILE_MAIN) break;
|
|
|
|
|
|
|
|
sprintf(str, "$WINEDITOR %s%s", sfile->dir, sfile->file);
|
|
|
|
system(str);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FKEY:
|
|
|
|
if(sfile->type==FILE_MAIN) {
|
|
|
|
fs_fake_users(sfile);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PADPLUSKEY:
|
|
|
|
case EQUALKEY:
|
|
|
|
if (G.qual & LR_CTRLKEY) BLI_newname(sfile->file, +100);
|
|
|
|
else if (G.qual & LR_SHIFTKEY) BLI_newname(sfile->file, +10);
|
|
|
|
else BLI_newname(sfile->file, +1);
|
|
|
|
|
|
|
|
do_draw= 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PADMINUS:
|
|
|
|
case MINUSKEY:
|
|
|
|
if (G.qual & LR_CTRLKEY) BLI_newname(sfile->file, -100);
|
|
|
|
else if (G.qual & LR_SHIFTKEY) BLI_newname(sfile->file, -10);
|
|
|
|
else BLI_newname(sfile->file, -1);
|
|
|
|
|
|
|
|
do_draw= 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BACKSLASHKEY:
|
|
|
|
case SLASHKEY:
|
|
|
|
if(sfile->type==FILE_MAIN) break;
|
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
strcpy(sfile->dir, "\\");
|
|
|
|
#else
|
|
|
|
strcpy(sfile->dir, "/");
|
|
|
|
#endif
|
|
|
|
freefilelist(sfile);
|
|
|
|
sfile->ofs= 0;
|
|
|
|
do_draw= 1;
|
|
|
|
break;
|
|
|
|
case PERIODKEY:
|
|
|
|
freefilelist(sfile);
|
|
|
|
do_draw= 1;
|
|
|
|
break;
|
|
|
|
case ESCKEY:
|
|
|
|
filesel_prevspace();
|
|
|
|
break;
|
|
|
|
case PADENTER:
|
|
|
|
case RETKEY:
|
|
|
|
if(sfile->type) filesel_execute(sfile);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(event==RIGHTMOUSE) {
|
|
|
|
selecting = NOTACTIVE;
|
|
|
|
if(sfile->type==FILE_MAIN) filesel_select_objects(sfile);
|
|
|
|
}
|
|
|
|
else if(event==LEFTMOUSE) {
|
|
|
|
if(sfile->type==FILE_MAIN) active_file_object(sfile);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* XXX, stupid patch, curarea can become undone
|
|
|
|
* because of file loading... fixme zr
|
|
|
|
*/
|
|
|
|
if(do_draw && curarea) scrarea_queue_winredraw(curarea);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ************* LIBRARY FILESEL ******************* */
|
|
|
|
|
|
|
|
static int groupname_to_code(char *group)
|
|
|
|
{
|
|
|
|
char buf[32];
|
|
|
|
char *lslash;
|
|
|
|
|
2005-03-10 20:29:28 +00:00
|
|
|
BLI_strncpy(buf, group, 31);
|
2002-10-12 11:37:38 +00:00
|
|
|
lslash= BLI_last_slash(buf);
|
|
|
|
if (lslash)
|
|
|
|
lslash[0]= '\0';
|
|
|
|
|
|
|
|
return BLO_idcode_from_name(buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int is_a_library(SpaceFile *sfile, char *dir, char *group)
|
|
|
|
{
|
2003-04-30 13:22:26 +00:00
|
|
|
/* return ok when a blenderfile, in dir is the filename,
|
|
|
|
* in group the type of libdata
|
2002-10-12 11:37:38 +00:00
|
|
|
*/
|
|
|
|
int len;
|
|
|
|
char *fd;
|
|
|
|
|
|
|
|
strcpy(dir, sfile->dir);
|
|
|
|
len= strlen(dir);
|
|
|
|
if(len<7) return 0;
|
|
|
|
if( dir[len-1] != '/' && dir[len-1] != '\\') return 0;
|
2004-04-05 11:25:25 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
group[0]= 0;
|
|
|
|
dir[len-1]= 0;
|
|
|
|
|
|
|
|
/* Find the last slash */
|
|
|
|
fd= (strrchr(dir, '/')>strrchr(dir, '\\'))?strrchr(dir, '/'):strrchr(dir, '\\');
|
|
|
|
|
|
|
|
if(fd==0) return 0;
|
|
|
|
*fd= 0;
|
|
|
|
if(BLO_has_bfile_extension(fd+1)) {
|
|
|
|
*fd= '/';
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
strcpy(group, fd+1);
|
|
|
|
|
|
|
|
/* Find the last slash */
|
|
|
|
fd= (strrchr(dir, '/')>strrchr(dir, '\\'))?strrchr(dir, '/'):strrchr(dir, '\\');
|
|
|
|
if (!fd || !BLO_has_bfile_extension(fd+1)) return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void do_library_append(SpaceFile *sfile)
|
|
|
|
{
|
2004-04-22 19:58:54 +00:00
|
|
|
Library *lib;
|
2002-10-12 11:37:38 +00:00
|
|
|
char dir[FILE_MAXDIR], group[32];
|
|
|
|
|
|
|
|
if ( is_a_library(sfile, dir, group)==0 ) {
|
|
|
|
error("Not a library");
|
|
|
|
} else if (!sfile->libfiledata) {
|
|
|
|
error("Library not loaded");
|
|
|
|
} else if (group[0]==0) {
|
|
|
|
error("Nothing indicated");
|
|
|
|
} else if (BLI_streq(G.main->name, dir)) {
|
|
|
|
error("Cannot use current file as library");
|
|
|
|
} else {
|
|
|
|
Object *ob;
|
|
|
|
int idcode = groupname_to_code(group);
|
|
|
|
|
|
|
|
BLO_library_append(sfile, dir, idcode);
|
|
|
|
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
/* DISPLISTS? */
|
2002-10-12 11:37:38 +00:00
|
|
|
ob= G.main->object.first;
|
|
|
|
while(ob) {
|
|
|
|
if(ob->id.lib) {
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
ob->recalc |= OB_RECALC;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
ob= ob->id.next;
|
|
|
|
}
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* in sfile->dir is the whole lib name */
|
2002-10-12 11:37:38 +00:00
|
|
|
strcpy(G.lib, sfile->dir);
|
|
|
|
|
2004-04-22 19:58:54 +00:00
|
|
|
/* and now find the latest append lib file */
|
|
|
|
lib= G.main->library.first;
|
|
|
|
while(lib) {
|
|
|
|
if (BLI_streq(dir, lib->name)) break;
|
|
|
|
lib= lib->id.next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((sfile->flag & FILE_LINK)==0) all_local(lib);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void library_to_filelist(SpaceFile *sfile)
|
|
|
|
{
|
|
|
|
LinkNode *l, *names;
|
2005-06-02 17:38:42 +00:00
|
|
|
int ok, i, nnames, idcode;
|
|
|
|
char filename[FILE_MAXDIR+FILE_MAXFILE];
|
|
|
|
char dir[FILE_MAXDIR], group[24];
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* name test */
|
2002-10-12 11:37:38 +00:00
|
|
|
ok= is_a_library(sfile, dir, group);
|
|
|
|
if (!ok) {
|
2003-04-30 13:22:26 +00:00
|
|
|
/* free */
|
2002-10-12 11:37:38 +00:00
|
|
|
if(sfile->libfiledata) BLO_blendhandle_close(sfile->libfiledata);
|
|
|
|
sfile->libfiledata= 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-06-02 17:38:42 +00:00
|
|
|
BLI_strncpy(filename, G.sce, sizeof(filename)); // G.sce = last file loaded, for UI
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* there we go */
|
|
|
|
/* for the time being only read filedata when libfiledata==0 */
|
2002-10-12 11:37:38 +00:00
|
|
|
if (sfile->libfiledata==0) {
|
2005-06-02 17:38:42 +00:00
|
|
|
sfile->libfiledata= BLO_blendhandle_from_file(dir); // this sets G.sce, we dont want it
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(sfile->libfiledata==0) return;
|
|
|
|
}
|
|
|
|
|
2003-10-07 18:24:02 +00:00
|
|
|
idcode= groupname_to_code(group);
|
2004-04-25 15:12:45 +00:00
|
|
|
|
|
|
|
// memory for strings is passed into filelist[i].relname
|
|
|
|
// and free'd in freefilelist
|
2003-10-07 18:24:02 +00:00
|
|
|
if (idcode) {
|
2002-10-12 11:37:38 +00:00
|
|
|
names= BLO_blendhandle_get_datablock_names(sfile->libfiledata, idcode);
|
|
|
|
} else {
|
|
|
|
names= BLO_blendhandle_get_linkable_groups(sfile->libfiledata);
|
|
|
|
}
|
|
|
|
|
|
|
|
nnames= BLI_linklist_length(names);
|
|
|
|
|
|
|
|
sfile->totfile= nnames + 2;
|
|
|
|
sfile->filelist= malloc(sfile->totfile * sizeof(*sfile->filelist));
|
|
|
|
memset(sfile->filelist, 0, sfile->totfile * sizeof(*sfile->filelist));
|
|
|
|
|
2005-04-28 19:29:54 +00:00
|
|
|
sfile->filelist[0].relname= BLI_strdup(".");
|
2002-10-12 11:37:38 +00:00
|
|
|
sfile->filelist[0].type |= S_IFDIR;
|
2005-04-28 19:29:54 +00:00
|
|
|
sfile->filelist[1].relname= BLI_strdup("..");
|
2002-10-12 11:37:38 +00:00
|
|
|
sfile->filelist[1].type |= S_IFDIR;
|
|
|
|
|
|
|
|
for (i=0, l= names; i<nnames; i++, l= l->next) {
|
2005-04-28 19:29:54 +00:00
|
|
|
char *blockname= BLI_strdup(l->link);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
sfile->filelist[i + 2].relname= blockname;
|
|
|
|
if (!idcode)
|
|
|
|
sfile->filelist[i + 2].type |= S_IFDIR;
|
|
|
|
}
|
|
|
|
|
2005-04-28 19:29:54 +00:00
|
|
|
BLI_linklist_free(names, free);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
qsort(sfile->filelist, sfile->totfile, sizeof(struct direntry), compare_name);
|
|
|
|
|
|
|
|
sfile->maxnamelen= 0;
|
|
|
|
for(i=0; i<sfile->totfile; i++) {
|
|
|
|
int len = BMF_GetStringWidth(G.font, sfile->filelist[i].relname);
|
|
|
|
if (len > sfile->maxnamelen)
|
|
|
|
sfile->maxnamelen = len;
|
|
|
|
}
|
2005-06-02 17:38:42 +00:00
|
|
|
|
|
|
|
BLI_strncpy(G.sce, filename, sizeof(filename)); // prevent G.sce to change
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ******************* DATA SELECT ********************* */
|
|
|
|
|
|
|
|
static void filesel_select_objects(SpaceFile *sfile)
|
|
|
|
{
|
|
|
|
Object *ob;
|
|
|
|
Base *base;
|
|
|
|
Scene *sce;
|
|
|
|
int a;
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* only when F4 DATABROWSE */
|
2002-10-12 11:37:38 +00:00
|
|
|
if(sfile->returnfunc) return;
|
|
|
|
|
|
|
|
if( strcmp(sfile->dir, "Object/")==0 ) {
|
|
|
|
for(a=0; a<sfile->totfile; a++) {
|
|
|
|
|
|
|
|
ob= (Object *)sfile->filelist[a].poin;
|
|
|
|
|
|
|
|
if(ob) {
|
|
|
|
if(sfile->filelist[a].flags & ACTIVE) ob->flag |= SELECT;
|
|
|
|
else ob->flag &= ~SELECT;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
base= FIRSTBASE;
|
|
|
|
while(base) {
|
|
|
|
base->flag= base->object->flag;
|
|
|
|
base= base->next;
|
|
|
|
}
|
2005-03-01 16:19:19 +00:00
|
|
|
countall();
|
2002-10-12 11:37:38 +00:00
|
|
|
allqueue(REDRAWVIEW3D, 0);
|
|
|
|
}
|
|
|
|
else if( strcmp(sfile->dir, "Scene/")==0 ) {
|
|
|
|
|
|
|
|
for(a=0; a<sfile->totfile; a++) {
|
|
|
|
|
|
|
|
sce= (Scene *)sfile->filelist[a].poin;
|
|
|
|
if(sce) {
|
|
|
|
if(sfile->filelist[a].flags & ACTIVE) sce->r.scemode |= R_BG_RENDER;
|
|
|
|
else sce->r.scemode &= ~R_BG_RENDER;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2003-10-07 18:24:02 +00:00
|
|
|
allqueue(REDRAWBUTSSCENE, 0);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void active_file_object(SpaceFile *sfile)
|
|
|
|
{
|
|
|
|
Object *ob;
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* only when F4 DATABROWSE */
|
2002-10-12 11:37:38 +00:00
|
|
|
if(sfile->returnfunc) return;
|
|
|
|
|
|
|
|
if( strcmp(sfile->dir, "Object/")==0 ) {
|
|
|
|
if(sfile->act >= 0) {
|
|
|
|
|
|
|
|
ob= (Object *)sfile->filelist[sfile->act].poin;
|
|
|
|
|
|
|
|
if(ob) {
|
|
|
|
set_active_object(ob);
|
|
|
|
if(BASACT && BASACT->object==ob) {
|
|
|
|
BASACT->flag |= SELECT;
|
|
|
|
sfile->filelist[sfile->act].flags |= ACTIVE;
|
|
|
|
allqueue(REDRAWVIEW3D, 0);
|
|
|
|
scrarea_queue_winredraw(curarea);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void main_to_filelist(SpaceFile *sfile)
|
|
|
|
{
|
|
|
|
ID *id;
|
|
|
|
struct direntry *files, *firstlib = NULL;
|
|
|
|
ListBase *lb;
|
|
|
|
int a, fake, idcode, len, ok, totlib, totbl;
|
2005-07-11 23:49:06 +00:00
|
|
|
short hide = 0;
|
|
|
|
|
|
|
|
if (sfile->flag & FILE_HIDE_DOT)
|
|
|
|
hide = 1;
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
if(sfile->dir[0]=='/') sfile->dir[0]= 0;
|
|
|
|
|
|
|
|
if(sfile->dir[0]) {
|
|
|
|
idcode= groupname_to_code(sfile->dir);
|
|
|
|
if(idcode==0) sfile->dir[0]= 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( sfile->dir[0]==0) {
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* make directories */
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
sfile->totfile= 21;
|
2002-10-12 11:37:38 +00:00
|
|
|
sfile->filelist= (struct direntry *)malloc(sfile->totfile * sizeof(struct direntry));
|
|
|
|
|
|
|
|
for(a=0; a<sfile->totfile; a++) {
|
|
|
|
memset( &(sfile->filelist[a]), 0 , sizeof(struct direntry));
|
|
|
|
sfile->filelist[a].type |= S_IFDIR;
|
|
|
|
}
|
|
|
|
|
2005-04-28 19:29:54 +00:00
|
|
|
sfile->filelist[0].relname= BLI_strdup("..");
|
|
|
|
sfile->filelist[1].relname= BLI_strdup(".");
|
|
|
|
sfile->filelist[2].relname= BLI_strdup("Scene");
|
|
|
|
sfile->filelist[3].relname= BLI_strdup("Object");
|
|
|
|
sfile->filelist[4].relname= BLI_strdup("Mesh");
|
|
|
|
sfile->filelist[5].relname= BLI_strdup("Curve");
|
|
|
|
sfile->filelist[6].relname= BLI_strdup("Metaball");
|
|
|
|
sfile->filelist[7].relname= BLI_strdup("Material");
|
|
|
|
sfile->filelist[8].relname= BLI_strdup("Texture");
|
|
|
|
sfile->filelist[9].relname= BLI_strdup("Image");
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
sfile->filelist[10].relname= BLI_strdup("Wave");
|
|
|
|
sfile->filelist[11].relname= BLI_strdup("Lattice");
|
|
|
|
sfile->filelist[12].relname= BLI_strdup("Lamp");
|
|
|
|
sfile->filelist[13].relname= BLI_strdup("Camera");
|
|
|
|
sfile->filelist[14].relname= BLI_strdup("Ipo");
|
|
|
|
sfile->filelist[15].relname= BLI_strdup("World");
|
|
|
|
sfile->filelist[16].relname= BLI_strdup("Screen");
|
|
|
|
sfile->filelist[17].relname= BLI_strdup("VFont");
|
|
|
|
sfile->filelist[18].relname= BLI_strdup("Text");
|
|
|
|
sfile->filelist[19].relname= BLI_strdup("Armature");
|
|
|
|
sfile->filelist[20].relname= BLI_strdup("Action");
|
2002-10-12 11:37:38 +00:00
|
|
|
qsort(sfile->filelist, sfile->totfile, sizeof(struct direntry), compare_name);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* make files */
|
2002-10-12 11:37:38 +00:00
|
|
|
idcode= groupname_to_code(sfile->dir);
|
|
|
|
|
|
|
|
lb= wich_libbase(G.main, idcode );
|
|
|
|
if(lb==0) return;
|
|
|
|
|
|
|
|
id= lb->first;
|
|
|
|
sfile->totfile= 0;
|
|
|
|
while(id) {
|
|
|
|
if(sfile->returnfunc && idcode==ID_IP) {
|
|
|
|
if(sfile->ipotype== ((Ipo *)id)->blocktype) sfile->totfile++;
|
|
|
|
}
|
2005-07-11 23:49:06 +00:00
|
|
|
else if (hide==0 || id->name[2] != '.')
|
|
|
|
sfile->totfile++;
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
id= id->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(sfile->returnfunc==0) sfile->totfile+= 2;
|
|
|
|
sfile->filelist= (struct direntry *)malloc(sfile->totfile * sizeof(struct direntry));
|
|
|
|
|
|
|
|
files= sfile->filelist;
|
|
|
|
|
|
|
|
if(sfile->returnfunc==0) {
|
|
|
|
memset( &(sfile->filelist[0]), 0 , sizeof(struct direntry));
|
2005-04-28 19:29:54 +00:00
|
|
|
sfile->filelist[0].relname= BLI_strdup(".");
|
2002-10-12 11:37:38 +00:00
|
|
|
sfile->filelist[0].type |= S_IFDIR;
|
|
|
|
memset( &(sfile->filelist[1]), 0 , sizeof(struct direntry));
|
2005-04-28 19:29:54 +00:00
|
|
|
sfile->filelist[1].relname= BLI_strdup("..");
|
2002-10-12 11:37:38 +00:00
|
|
|
sfile->filelist[1].type |= S_IFDIR;
|
|
|
|
|
|
|
|
files+= 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
id= lb->first;
|
|
|
|
totlib= totbl= 0;
|
|
|
|
|
|
|
|
while(id) {
|
|
|
|
|
|
|
|
ok= 0;
|
|
|
|
if(sfile->returnfunc && idcode==ID_IP) {
|
|
|
|
if(sfile->ipotype== ((Ipo *)id)->blocktype) ok= 1;
|
|
|
|
}
|
|
|
|
else ok= 1;
|
|
|
|
|
|
|
|
if(ok) {
|
|
|
|
|
2005-07-11 23:49:06 +00:00
|
|
|
if (hide==0 || id->name[2] != '.') {
|
|
|
|
memset( files, 0 , sizeof(struct direntry));
|
|
|
|
files->relname= BLI_strdup(id->name+2);
|
|
|
|
|
|
|
|
if(sfile->returnfunc==0) { /* F4 DATA BROWSE */
|
|
|
|
if(idcode==ID_OB) {
|
|
|
|
if( ((Object *)id)->flag & SELECT) files->flags |= ACTIVE;
|
|
|
|
}
|
|
|
|
else if(idcode==ID_SCE) {
|
|
|
|
if( ((Scene *)id)->r.scemode & R_BG_RENDER) files->flags |= ACTIVE;
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2005-07-11 23:49:06 +00:00
|
|
|
files->nr= totbl+1;
|
|
|
|
files->poin= id;
|
|
|
|
fake= id->flag & LIB_FAKEUSER;
|
|
|
|
|
|
|
|
if(id->lib && fake) sprintf(files->extra, "LF %d", id->us);
|
|
|
|
else if(id->lib) sprintf(files->extra, "L %d", id->us);
|
|
|
|
else if(fake) sprintf(files->extra, "F %d", id->us);
|
|
|
|
else sprintf(files->extra, " %d", id->us);
|
|
|
|
|
|
|
|
if(id->lib) {
|
|
|
|
if(totlib==0) firstlib= files;
|
|
|
|
totlib++;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2005-07-11 23:49:06 +00:00
|
|
|
|
|
|
|
files++;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2005-07-12 03:37:16 +00:00
|
|
|
totbl++;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
id= id->next;
|
|
|
|
}
|
|
|
|
|
2003-04-30 13:22:26 +00:00
|
|
|
/* only qsort of libraryblokken */
|
2002-10-12 11:37:38 +00:00
|
|
|
if(totlib>1) {
|
|
|
|
qsort(firstlib, totlib, sizeof(struct direntry), compare_name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sfile->maxnamelen= 0;
|
|
|
|
for(a=0; a<sfile->totfile; a++) {
|
|
|
|
len = BMF_GetStringWidth(G.font, sfile->filelist[a].relname);
|
|
|
|
if (len > sfile->maxnamelen) sfile->maxnamelen = len;
|
|
|
|
|
|
|
|
if(filetoname) {
|
|
|
|
if( strcmp(sfile->file, sfile->filelist[a].relname)==0) {
|
|
|
|
sfile->ofs= a-( sfile->collums*(curarea->winy-FILESELHEAD-10)/(2*FILESEL_DY));
|
|
|
|
filetoname= 0;
|
|
|
|
if(sfile->returnfunc) sfile->filelist[a].flags |= ACTIVE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-04-28 11:17:21 +00:00
|
|
|
void clever_numbuts_filesel()
|
|
|
|
{
|
|
|
|
SpaceFile *sfile;
|
|
|
|
char orgname[FILE_MAXDIR+FILE_MAXFILE+12];
|
|
|
|
char filename[FILE_MAXDIR+FILE_MAXFILE+12];
|
|
|
|
char newname[FILE_MAXDIR+FILE_MAXFILE+12];
|
|
|
|
int test;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
sfile= curarea->spacedata.first;
|
|
|
|
|
|
|
|
if(sfile->type==FILE_MAIN) return;
|
|
|
|
|
|
|
|
len = 110;
|
|
|
|
test = get_hilited_entry(sfile);
|
|
|
|
|
|
|
|
if (test != -1 && !(S_ISDIR(sfile->filelist[test].type))){
|
|
|
|
BLI_make_file_string(G.sce, orgname, sfile->dir, sfile->filelist[test].relname);
|
|
|
|
strcpy(filename, sfile->filelist[test].relname);
|
|
|
|
|
|
|
|
add_numbut(0, TEX, "", 0, len, filename, "Rename File");
|
|
|
|
|
|
|
|
if( do_clever_numbuts("Rename File", 1, REDRAW) ) {
|
|
|
|
BLI_make_file_string(G.sce, newname, sfile->dir, filename);
|
|
|
|
|
|
|
|
if( strcmp(orgname, newname) != 0 ) {
|
|
|
|
BLI_rename(orgname, newname);
|
|
|
|
freefilelist(sfile);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
scrarea_queue_winredraw(curarea);
|
|
|
|
}
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|