⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fv.tree.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
				{					*s_p = NULL;					s_p = second;					width = Fv_fontwidth[*n_p-' '];				}		*s_p++ = *n_p++;	}	*s_p = NULL;	pw_text(Fv_tree.pw, x, f_p->y+(TREE_GLYPH_HEIGHT>>1),		PIX_SRC | PIX_DST, Fv_font, first);	if (!shadow)		pw_text(Fv_tree.pw, x, 			f_p->y+TREE_GLYPH_HEIGHT-(TREE_GLYPH_HEIGHT>>2),			PIX_SRC | PIX_DST, Fv_font, second);}staticcalc_tree(f_p, y)			/* Calculate tree's coordinates */	register FV_TNODE *f_p;			/* Current node */	int y;					/* Current y level */{	register FV_TNODE *nf_p = NULL;		/* Previous sibling */	register int stack = 0;			/* Current stack level */	for (; f_p; f_p = f_p->sibling)	{		if (f_p->child && !(f_p->status & PRUNE))		{			calc_tree(f_p->child,y+(TREE_GLYPH_HEIGHT<<1));			nf_p = f_p->child;			for (; nf_p->sibling; nf_p = nf_p->sibling)				;			f_p->x = f_p->child->x+((nf_p->x-f_p->child->x)/2);			stack = 0;		}		else		{			if (stack>MAXSTACKDEPTH)			{				nf_p = NULL;				Xpos -= GLYPH_WIDTH;			}			if (nf_p && (nf_p->child == NULL||					nf_p->status == PRUNE))			{				Xpos += GLYPH_WIDTH>>2;				++stack;			}			else			{				stack = 0;				Xpos += GLYPH_WIDTH+(GLYPH_WIDTH>>2);			}			f_p->x = Xpos;		}		if (Xpos>Xmax)			Xmax = Xpos;		f_p->stack = stack;		f_p->y = y+(f_p->stack*((TREE_GLYPH_HEIGHT>>1)+			(TREE_GLYPH_HEIGHT>>3)));		if (f_p->y > Ymax)			Ymax = f_p->y;		nf_p = f_p;	}}staticdisplay_tree(f_p)			/* Display tree at folder */	register FV_TNODE *f_p;{	register int x;	for (; f_p; f_p = f_p->sibling)	{		pw_rop(Fv_tree.pw, f_p->x, f_p->y, GLYPH_WIDTH,			TREE_GLYPH_HEIGHT, PIX_SRC,			f_p==Fv_current?Fv_icon[FV_IOPENFOLDER]:				f_p->mtime && !(f_p->status&PRUNE)?					     Fv_icon[FV_IFOLDER] :					     Fv_icon[FV_IUNEXPLFOLDER],			0, TREE_GLYPH_TOP);		fv_put_text_on_folder(f_p);		/* Connect node with parent */		if (f_p != Fv_thead && f_p->stack == 0)		{			/* Straight up to tab height... */			x = f_p->x+(GLYPH_WIDTH>>1);			pw_vector(Fv_tree.pw, x,				f_p->y+(TREE_GLYPH_HEIGHT>>3),				x, f_p->y,				PIX_SRC, 1);			/* ...then arc to parent */			pw_vector(Fv_tree.pw, x, f_p->y,				f_p->parent->x+(GLYPH_WIDTH>>1),				f_p->y-TREE_GLYPH_HEIGHT, PIX_SRC, 1);		}		if (f_p->child && !(f_p->status & PRUNE))			display_tree(f_p->child);	}}fv_drawtree(calc)			/* Draw path pane */	BOOLEAN calc;			/* Recalculate tree positions */{	FV_TNODE *saved_sibling;	/* Lock and clear canvas... */#ifdef SV1	pw_lock(Fv_tree.pw, &Fv_tree.r);#endif	/* Clear background */	pw_writebackground(Fv_tree.pw, Fv_tree.r.r_left, 		Fv_tree.r.r_top, Fv_tree.r.r_width, 		Fv_tree.r.r_height, PIX_CLR);	if (Fv_treeview)	{		if (calc)		{			Xpos = MARGIN - (GLYPH_WIDTH+ (GLYPH_WIDTH>>2));			Xmax = Xpos;			Ymax = MARGIN;			calc_tree(Fv_thead, Ymax);						Fv_dont_paint = TRUE;			window_set(Fv_tree.canvas, 				CANVAS_WIDTH, Xmax+(GLYPH_WIDTH<<1),				CANVAS_HEIGHT, Ymax+GLYPH_HEIGHT, 				0);			Fv_dont_paint = FALSE;		}		/* If we've changed the tree's root, we don't want to		 * display any of it's possible siblings...		 */		saved_sibling = Fv_thead->sibling;		Fv_thead->sibling = NULL;		display_tree(Fv_thead);		Fv_thead->sibling = saved_sibling;		reverse(Fv_tselected);	}	else		draw_path();#ifdef SV1	pw_unlock(Fv_tree.pw);			/* Unlock canvas */#endif}fv_showopen()			/* Avoid repainting tree to show open folder */{	if (!Fv_treeview)	{		draw_path();		Fv_lastcurrent = Fv_current;		return;	}	/* We've seen this folder already.  Just 	 * exchange the open folder icons...	 */	if (Fv_lastcurrent)	{		register FV_TNODE *f_p;		pw_rop(Fv_tree.pw, Fv_lastcurrent->x, Fv_lastcurrent->y,			GLYPH_WIDTH, TREE_GLYPH_HEIGHT,			PIX_SRC, Fv_icon[FV_IFOLDER], 0, TREE_GLYPH_TOP);		fv_put_text_on_folder(Fv_lastcurrent);		f_p = Fv_lastcurrent->sibling;		if (!Fv_lastcurrent->child && f_p && f_p->stack)		{			/* Open folder was in stack--repaint rest of			 * stack...			 */			for (; f_p && f_p->stack; f_p = f_p->sibling)			{				pw_rop(Fv_tree.pw, f_p->x, f_p->y,					GLYPH_WIDTH,					TREE_GLYPH_HEIGHT,					PIX_SRC,					f_p->mtime ? Fv_icon[FV_IFOLDER]						: Fv_icon[FV_IUNEXPLFOLDER],					0, TREE_GLYPH_TOP);				fv_put_text_on_folder(f_p);			}		}					}	pw_rop(Fv_tree.pw, Fv_current->x, Fv_current->y,		GLYPH_WIDTH, TREE_GLYPH_HEIGHT,		PIX_SRC, Fv_icon[FV_IOPENFOLDER], 0, TREE_GLYPH_TOP);	fv_put_text_on_folder(Fv_current);	/* Ensure that this folder is visible... */	fv_visiblefolder(Fv_current);	Fv_lastcurrent = Fv_current;}staticdraw_path()					/* Draw folder path */{	FV_TNODE *level[32];			/* Nodes in path */	register int x;				/* X coordinate */	register int y;				/* Y coordinate */	register int levelno;			/* level array index */	register FV_TNODE *f_p;			/* Node pointer */	/* Get full path name; back up tree */	f_p = Fv_current;	for ( levelno = 0; f_p; f_p = f_p->parent, levelno++ )	{		if ( levelno > 32 )		{			fv_putmsg(TRUE, "> 32 levels deep", 0, 0);			return;		}		level[levelno] = f_p;	}	y = Fv_tree.r.r_top + MARGIN;	/* Do we have enough room to display full path?  If not then	 * display from current folder back with a line to indicate	 * the truncation.	 */	if ((levelno*GLYPH_WIDTH) +((levelno)*(GLYPH_WIDTH>>2))		> Fv_tree.r.r_width)	{		levelno = (Fv_tree.r.r_width-MARGIN)/(GLYPH_WIDTH+			(GLYPH_WIDTH>>2));		if (levelno<1)			levelno = 1;		/* MUST be one visible! */		pw_vector(Fv_tree.pw, 0, y+(TREE_GLYPH_HEIGHT>>1), GLYPH_WIDTH>>2,			y+(TREE_GLYPH_HEIGHT>>1), PIX_SRC, 1);	}	x = (GLYPH_WIDTH>>2)+Fv_tree.r.r_left;	/* Display path */	Npath = levelno;	levelno--;	while (levelno > -1)	{		f_p = level[levelno];		pw_rop(Fv_tree.pw, x, y, GLYPH_WIDTH, TREE_GLYPH_HEIGHT,			PIX_SRC, 			levelno ? Fv_icon[FV_IFOLDER]				: Fv_icon[FV_IOPENFOLDER],			0, TREE_GLYPH_TOP);		f_p->x = x;		f_p->y = y;		fv_put_text_on_folder(f_p);		x += GLYPH_WIDTH + (GLYPH_WIDTH>>2);		/* Connecting arc to next folder */		if (levelno)			pw_vector(Fv_tree.pw, x-(GLYPH_WIDTH>>2),				y+(TREE_GLYPH_HEIGHT>>1),				x,				y+(TREE_GLYPH_HEIGHT>>1), PIX_SRC, 1);		levelno--;	}	Fv_lastcurrent = Fv_current;	reverse(Fv_tselected);}static FV_TNODE *path_chosen(x, y)			/* What path was chosen? */	register int x, y;{	register int w, fno;	FV_TNODE *f_p;	/* Check reasonable boundaries */	w = GLYPH_WIDTH+(GLYPH_WIDTH>>2);	if (x<MARGIN || y<MARGIN || y>(MARGIN+TREE_GLYPH_HEIGHT) || x>(w*Npath))		return(NULL);	/* Get folder number chosen (ensure that we're not in folder gap) */	x -= GLYPH_WIDTH>>2;	fno = x / w;	if (fno>0)		x -= w*fno;	if (x>GLYPH_WIDTH)		return(NULL);	fno++;	f_p = Fv_current;	while (fno < Npath)	{		f_p = f_p->parent;		fno++;	}	return(f_p);}fv_visiblefolder(f_p)			/* Make folder visible in tree */	register FV_TNODE *f_p;{	int newpos;	/* Try and centre folder in window */	if (f_p->x < Fv_tree.r.r_left || 	    f_p->x+(GLYPH_WIDTH>>1) > Fv_tree.r.r_left+Fv_tree.r.r_width)	{		newpos = f_p->x - (Fv_tree.r.r_width>>1);		if (newpos<0)			newpos = 0;#ifndef SV1		newpos /= 10;#endif		scrollbar_scroll_to(Fv_tree.hsbar, newpos);	}	if (f_p->y < Fv_tree.r.r_top ||	    f_p->y+(TREE_GLYPH_HEIGHT>>1) > Fv_tree.r.r_top+Fv_tree.r.r_height)	{		newpos = f_p->y - (Fv_tree.r.r_height>>1);		if (newpos<0)			newpos = 0;#ifndef SV1		newpos /= 10;#endif		scrollbar_scroll_to(Fv_tree.vsbar, newpos);	}}voidfv_addparent_button()		/* Add tree root's parent */{	/* Restore current head */	if (Fv_sibling && Fv_sibling->parent == Fv_thead->parent)		Fv_thead->sibling = Fv_sibling;	add_parent(Fv_thead->parent);}staticadd_parent(f_p)			/* Add parent to folder */	FV_TNODE *f_p;{	Fv_thead = f_p;	fv_drawtree(TRUE);	if (Fv_tselected)		fv_visiblefolder(Fv_tselected);		/* Track selected */}fv_hide_node()			/* Don't show selected folder's descendents */{	BOOLEAN new;	if (Fv_tselected->mtime == 0)	{		fv_busy_cursor(TRUE);		fv_expand_node(Fv_tselected, &new);		fv_busy_cursor(FALSE);		if (!new)			return;	}	else if (Fv_tselected->status & PRUNE)		Fv_tselected->status &= ~PRUNE;	else		Fv_tselected->status |= PRUNE;	fv_drawtree(TRUE);	fv_visiblefolder(Fv_tselected);		/* Track selected */}fv_set_root()			/* Set tree root to current folder */{	if (Fv_tselected != Fv_thead)	{		Fv_sibling = Fv_tselected->sibling;		Fv_tselected->sibling = NULL;		add_parent(Fv_tselected);		Fv_lastcurrent = NULL;	}}fv_openfile(name, pattern, folder)	/* Open a file */	char *name;			/* File name (incl path) */	char *pattern;			/* Pattern it matched */	BOOLEAN folder;			/* Goto folder? */{	register char *n_p;		/* Name pointer */	char *fname;			/* File name (excl path) */	register FV_TNODE *f_p, *parent;/* Tree pointers */	register int more;		/* More of path name to come? */	BOOLEAN make_folder = FALSE;	/* Did we make a folder? */	FV_TNODE *child;		/* Temp folder child */	if (folder)		fname = NULL;	else	{		/* Remove last component of path */		n_p = name;		while (*n_p)			n_p++;		while (*n_p != '/' && n_p != name)			n_p--;		/* It's a filename, match it */		if (n_p == name)		{			fname = n_p;			goto match;		}		fname = n_p+1;		*n_p = NULL;	}	more = TRUE;	if (*name == '/')	{		/* Begin at root... */		name++;		if (*name == NULL)		{			more = FALSE;			f_p = Fv_troot;		}		else		{			f_p = Fv_troot->child;			parent = Fv_troot;		}		/* Make sure root is visible */		Fv_dont_paint = TRUE;		while (Fv_thead != Fv_troot)			fv_addparent_button();		Fv_dont_paint = FALSE;	}	else	{		/* Begin at selected or current folder... */		f_p = Fv_tselected ? Fv_tselected : Fv_current;		parent = f_p;		f_p = f_p->child;		f_p->status &= ~PRUNE;	}	while (more)	{		/* Get next folder name... */		while (*name == '/')		/* Skip extra /'s */			*name++;		n_p = name;		while (*n_p && *n_p != '/')			n_p++;		if (more = (*n_p=='/'))			*n_p = NULL;		else if (n_p==name)		/* / at end */			break;				for (; f_p; f_p = f_p->sibling)			if (strcmp(f_p->name, name)==0)				break;		if (f_p)			/* Found folder? */		{			if (more)			{				parent = f_p;				f_p = f_p->child;				if (f_p)					f_p->status &= ~PRUNE;			}			else				break;		/* Last folder in path */		}		else				/* We have to make folder */		{			make_folder = TRUE;			if (((f_p=(FV_TNODE *)fv_malloc(sizeof(FV_TNODE)))==NULL) ||			    ((f_p->name=fv_malloc((unsigned)strlen(name)+1))==NULL))				return;			if (parent && parent->mtime == 0 && parent->child)			{				/* Assign parent some bogus time so it thinks				 * we've seen this folder, (revisiting folder				 * will expand it, but preserve existing				 * children)				 */				 parent->mtime = 10;			}			(void)strcpy(f_p->name, name);			f_p->parent = parent;			f_p->sibling = parent->child;			f_p->child = NULL;			f_p->status = 0;			f_p->mtime = 0;			parent->child = f_p;			parent = f_p;		}		if (more)		{			*n_p = '/';			name = n_p+1;		}	}	/* We've arrived at the correct folder */	if (fname)		*(fname-1) = '/';		/* Restore name */	if (f_p != (Fv_tselected ? Fv_tselected : Fv_current))	{		/* File isn't in current directory... */		fv_getpath(f_p, (char *)0);		if (chdir(Fv_path)==-1)			return;		(void)strcpy(Fv_openfolder_path, Fv_path);		Fv_current = f_p;		/* Did folder repaint discover new folders? */		child = f_p->child;		fv_display_folder(FV_BUILD_FOLDER);		if (child != f_p->child)			make_folder = TRUE;		if (Fv_thead != Fv_troot && !fv_descendant(f_p, Fv_thead))		{			/* Folder not in current subtree; back to real root */			Fv_thead->sibling = Fv_sibling;			Fv_thead = Fv_troot;			make_folder = TRUE;		}		if (make_folder || !Fv_treeview)			fv_drawtree(make_folder);		else			fv_showopen();					if (Fv_treeview)		{			fv_visiblefolder(Fv_current);			reverse(Fv_current);			Lastselected = Fv_tselected = Fv_lastcurrent = Fv_current;		}		else			Lastselected = Fv_tselected = Fv_lastcurrent = NULL;	}	/* If we were passed a pattern, then try and edit it, otherwise	 * just match it.	 */	if (fname)	{match:		if (*fname == '.' && !Fv_see_dot)			fv_putmsg(TRUE, Fv_message[MEHIDDEN], 0, 0);		else if (pattern)			fv_gotofile(fname, pattern);		else			fv_match_files(fname);	}	else		scrollbar_scroll_to(Fv_foldr.vsbar, 0);}fv_treedeselect()		/* Deselect folder */{	reverse(Fv_tselected ? Fv_tselected : Lastselected);	Lastselected = NULL;	Fv_tselected = NULL;}fv_descendant(c_p, f_p)		/* Search folder tree for descendant of folder */	FV_TNODE *c_p;	FV_TNODE *f_p;{	if (c_p == f_p)		return(TRUE);	Child = c_p;	Found_child = FALSE;	descendant(f_p);	return(Found_child);}staticdescendant(f_p)	register FV_TNODE *f_p;{	if (Found_child)		return;	for ( ; f_p; f_p = f_p->sibling)		if (f_p == Child)		{			Found_child = TRUE;			break;		}		else if (f_p->child)			descendant(f_p->child);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -