[Date Prev] [Date Next] [Thread Prev] [Thread Next] Date Index Thread Index Search archive:
Date:Mon Dec 14 18:17:51 1996 
Subject:Drawing trees with RC_GRAPHIC 
From:Riccardo Poli 
Volume-ID:961214.01 

Hi,

I've written a  simple program  to extend LIB  SHOWTREE to  be able to
draw trees (represented as lists of lists) in  an RC_GRAPHIC window. I
append it to this message.

The code seems to  work, but I haven't experimented  with it for  long
enough to guaratee that it is bug-free.

Riccardo
----------------------------------------------------------------------
/* --- Copyright University of Birmingham 1996. All rights reserved. ------
 > File:            $poplocal/local/auto/rc_showtree.p
 > Purpose:         Version of LIB SHOWTREE using rc_graphic
 > Author:          Riccardo Poli, Dec 14 1996
 > Documentation:	HELP SHOWTREE and below
 > Related Files:   LIB SHOWTREE
 */

;;;
;;; Program:        rc_showtree.p
;;;
;;; Author:         Riccardo Poli
;;;
;;; Creation date:  Dec 1996
;;;
;;; Description:    A graphical version of showtree based on RC_GRAPHIC
;;;

/*
;;; A couple of examples on how to use rc_showtree

rc_start();
rc_showtree([+ [* 1 x][/ [+ 3 y] 10]],0,-200);

;;; Changing fonts
rc_start();
XpwSetFont(rc_window,'9x15') ->;
rc_showtree([OR [NAND x2 x1] [NOR x1 x1]],-200,-230);
true -> showtree_ortho_links;
XpwSetFont(rc_window,'fixed') ->;
rc_showtree([OR [NAND x2 x1] [NOR x1 x1]],0,-230);
false -> showtree_oblong_nodes;
XpwSetFont(rc_window,'10x20') ->;
rc_showtree([OR [NAND x2 x1] [NOR x1 x1]],-100,0);

;;; A bigger tree
rc_destroy();
1000 -> rc_window_xsize;
false -> rc_clipping;
rc_start();
false -> showtree_ortho_links;
true -> showtree_oblong_nodes;
XpwSetFont(rc_window,'5x7') ->;
rc_showtree([University
	   [Science
	    [Psychology Glyn Cristina '...']
	    [ComputerScience Aaron Riccardo Manfred '...']
	    '...']
	   [Engineering
	    MechEng
	    ElecEng
	    '...']
	   '...'],-300,-200);


;;; A parse tree
rc_start();
XpwSetFont(rc_window,'8x13') ->;
rc_showtree([s [np [pn he]]
      [vp [vnplocnp put]
          [ppnplocnp [np [snp [det a]
                              [qn [adj big] [qn [noun dog]]]]]
                     [locprep into]
                     [np [snp [det each] [qn [noun car]]]]]]],-300,-200);
*/


uses showtree;
uses rc_graphic;

section;

vars showtree_oblong_nodes = true;
vars showtree_ortho_links = false;
vars showtree_scale = 10;

define showtree_box(r1,c1,r2,c2);
    rc_jumpto(r1,c1);
    if showtree_oblong_nodes then
    	rc_draw_oblong(r2-r1,c2-c1,1);
    else
    	rc_draw_rectangle(r2-r1,c2-c1);
    endif;
enddefine;

define vars showtree_width(node, name);
	lvars node, name, size;
    	unless name.isstring then
            name><'' -> name
    	endunless;
    	XpwTextWidth(rc_window, name)  / rc_xscale + 1 -> size;
	if showtree_node_daughters()(node) then
		size + 2
	else
		size
	endif;
enddefine;

define vars showtree_height(node,val);
    if XpwFontHeight(rc_window) < 10 then
	2;
    else
    	XpwFontHeight(rc_window) / 10 * 2;
    endif;
enddefine;

define vars showtree_draw_node(node, val);
    lvars node, val, name, r1, c1, r2, c2, size, h;

    dl(val) -> c2 -> c1 -> r2 -> r1;
    hd(showtree_node_draw_data()(node)) -> name;
    unless name.isstring then
        name><'' -> name
    endunless;
    if showtree_node_daughters()(node) then
	showtree_box(c1, r1, c2-2, r2);
 	c1 + 1 -> c1
    endif;
    XpwTextWidth(rc_window, name)  / rc_xscale -> size;
    XpwFontHeight(rc_window) / 10 -> h;
    rc_print_at(c1, r1 +  h, name);
enddefine;

define  connectup();
    define vars join(node, unode);
	lvars node, unode, loc1, loc2, elem;
	if islist(unode) then
	    for elem in unode do join(node,elem) endfor;
	else
	    showtree_node_location()(node) -> loc1;
	    showtree_node_location()(unode) -> loc2;
	    drawline(showtree_mid(loc1(4),loc1(3)),
		     loc1(2),
		     showtree_mid(loc2(4),loc2(3)),
		     loc2(1))
	endif;
    enddefine;

    appproperty(showtree_node_daughters(),
		procedure(node, val);
		    lvars val, node, unode, subnodes;
		    if listlength(val) > 0 then
			dest(val) -> subnodes -> unode;
			if subnodes == [] then
			    join(node, unode)
			else
			    join(node, unode);
			    last(subnodes) -> unode;
			    allbutlast(1, subnodes) -> subnodes;
			    join(node, unode);
			    join(node, subnodes)
			endif
		    endif
		endprocedure);
enddefine;


define vars rc_showtree(tree,x,y);
    dlocal drawline = rc_drawline,
           rc_xscale = showtree_scale * rc_xscale,
	   rc_yscale = -showtree_scale * rc_yscale,
	   rc_xorigin = rc_xorigin + x,
	   rc_yorigin = rc_yorigin + y;

    showtree_init();
    newproperty([], 59, false, true) -> showtree_node_location();
    newproperty([], 59, false, true) -> showtree_node_daughters();
    newproperty([], 59, false, true) -> showtree_node_draw_data();
    newproperty([], 59, false, true) -> showtree_subtree_rootnode_name();
    $-showtree$-shapetree($-showtree$-transformtree(tree,1));
    appproperty(showtree_node_location(), showtree_draw_node);
    if showtree_ortho_links then
    	$-showtree$-connectup();
    else
	connectup();
    endif;
enddefine;

vars procedure rc_drawtree = rc_showtree;

endsection;
----------------------------------------------------------------------

-- 
Dr. Riccardo Poli                    E-mail: R.Poli@cs.bham.ac.uk 
School of Computer Science           Telephone: +44-121-414-3739
The University of Birmingham         Fax: +44-121-414-4281
Edgbaston, Birmingham B15 2TT, UK