Ejemplo n.º 1
0
GRECT  calculate_box( int reference, short x, short y,
				int attributes, FONTINFO* font_ptr, int parent_number )
{
	GRECT box ;
	BOOLEAN size_changed = FALSE ;
	
	box = get_box_size( reference, x, y, attributes, font_ptr, parent_number ) ;

	if( box.g_x - 1 < custom_tree.org_x )
	{
		size_changed = TRUE ;
		if( custom_display.x_start <= custom_tree.org_x )
			custom_display.x_start = box.g_x - 1 ;
		custom_tree.org_x = box.g_x - 1 ;
		send_redraw_message( &custom_display.custom_box, custom_form.fm_handle ) ;
	}
	if( rect_end( &box ) > custom_tree.lim_x )
	{
		size_changed = TRUE ;
		custom_tree.lim_x = rect_end( &box ) + 1 ;
	}
	
	if( box.g_y - 1 < custom_tree.org_y )
	{
		size_changed = TRUE ;
		if( custom_display.y_start <= custom_tree.org_y )
			custom_display.y_start = box.g_y - 1 ;
		custom_tree.org_y = box.g_y - 1 ;
		send_redraw_message( &custom_display.custom_box, custom_form.fm_handle ) ;
	}
	if( rect_bottom( &box ) + 1 > custom_tree.lim_y )
	{
		size_changed = TRUE ;
		custom_tree.lim_y = rect_bottom( &box ) + 1 ;
	}
	if( size_changed )  set_cust_sliders() ;
	
	return box ;
}
Ejemplo n.º 2
0
// For debugging
static void DrawRedBoxAroundRect(gl_context_t* context, rect2d_t rect)
{
    float const l = rect_left(rect);
    float const r = rect_right(rect);
    float const t = rect_top(rect);
    float const b = rect_bottom(rect);

    // Draw a yellow 1 pixel box around the entire thing.
    GLfloat boxLines[] = {
        l, b, 0,
        l, t, 0,
        r, t, 0,
        r, b, 0
    };

    // Use the program object
    glUseProgram(context->mainProgram);

    glVertexAttribPointer(context->a_position, 3, GL_FLOAT, GL_FALSE, 0, boxLines);
    glEnableVertexAttribArray(context->a_position);
    glUniform4f(context->u_fragColor, 1,0,0,1);
    glDrawArrays(GL_LINE_LOOP, 0, 4);
    check_gl();
}
Ejemplo n.º 3
0
Archivo: proj.c Proyecto: juddy/edcde
static void
project_rband(
    Widget	widget,
    XEvent	*event,
    XRectangle	*rb_rect,
    XtPointer	client_data
)
{
    Vwr		v = NULL;
    VNode	*selected_nodes = NULL;
    VMethods	m;
    ABSelectedRec	old_sel, 
			new_sel;
    XRectangle	tmp_rect;
    int		num_selected = 0,
		num_cur_selected = 0,
		i;

    XtVaGetValues(widget, XmNuserData, &v, NULL); 

    if (!v)
	return;

    if (!(m = v->methods))
	return;
    
    /* If rubberband was drawn from lower-right to upper-left,
     * translate rect so that x,y is upper-left point in rectangle.
     */
    if (rect_right(rb_rect) < rb_rect->x ||
	rect_bottom(rb_rect) < rb_rect->y)
    {
	tmp_rect.x = rect_right(rb_rect);
	tmp_rect.y = rect_bottom(rb_rect);
	tmp_rect.width = rb_rect->x - tmp_rect.x;
	tmp_rect.height = rb_rect->y - tmp_rect.y;
	rb_rect = &tmp_rect;
    }

    /*
     * Important: set rband_rect so that
     * the function 'project_select_rband' can see it.
     */
    rband_rect = rb_rect;

    /*
     * Get list of currently selected modules in project
     * organizer
     */
    vwr_get_cond(v->current_tree, &selected_nodes, 
			&num_selected, select_fn);

    if (mselect_adjust)
	/*
	 * If select adjust, remember how many modules are currently
	 * selected
	 */
	num_cur_selected = num_selected;
    else
    {
	/*
	 * If not select adjust, the current select count is reset
	 */
	num_cur_selected = 0;

	/*
	 * Deselect all currently selected nodes
	 */
        for (i=0; i < num_selected; ++i)
	{
	    ABObj	obj;

	    /*
	     * Get ABObj
	     */
	    obj = (ABObj)selected_nodes[i]->obj_data;

	    if (!obj)
	        continue;

	    proj_deselect(obj);
	}
    }

    /*
     * Free up node list if it contained anything
     */
    if (selected_nodes)
        util_free(selected_nodes);

    /*
     * Get nodes in browser that are within the
     * rubber band rectangle.
     */
    vwr_get_cond(v->current_tree, &selected_nodes, 
			&num_selected, project_select_rband);
    
    /*
     * Update (activate/deactivate) project organizer menu items
     */
    update_menu_items(0, num_cur_selected + num_selected);

    /*
     * Return if no selected nodes
     */
    if (num_selected == 0)
	return;

    /*
     * For each object enclosed in rubber band rectangle
     */
    for (i=0; i < num_selected; ++i)
    {
	ABObj	obj;
	int	j;

	/*
	 * Get ABObj
	 */
	obj = (ABObj)selected_nodes[i]->obj_data;

	if (!obj)
	    continue;

	proj_select(obj);
    }

    /*
     * Unset rband_rect
     */
    rband_rect = NULL;

    /*
     * Free up node list if it contained anything
     */
    if (selected_nodes)
	util_free(selected_nodes);
}
Ejemplo n.º 4
0
/*
 *    Resize object according to info in last resize rubberbanding    
 */
int
abobj_resize(
    ABObj     obj, 
    XEvent     *event
)
{
    Widget       parent;
    Display      *dpy;
    XRectangle   p_rect;
    XRectangle	 adj_rect;
    Window       rootwin;
    int          orig_x, orig_y;
    int          trans_x, trans_y;
    ABObj	 moveobj;
    ABObj	 pobj;

    if (!first_move) /* resize occurred */
    {
        Window     win;

	if (obj_is_item(obj))
	    obj = obj_get_parent(obj);

	obj     = obj_get_root(obj);
        parent  = XtParent(xy_widget);
        dpy     = XtDisplay(xy_widget);

        orig_x = (int)resize_rect.x;
        orig_y = (int)resize_rect.y;

        first_move = TRUE;

        x_get_widget_rect(parent, &p_rect);

        rootwin = RootWindowOfScreen(XtScreen(xy_widget));

        /* erase last rect outline 
         */
        x_fullscreen_box(xy_widget, rootwin, 
        	resize_rect.x, resize_rect.y,
                rect_right(&resize_rect), 
                rect_bottom(&resize_rect));

        /* translate from root coordinates to parent's 
         */
        XTranslateCoordinates(dpy, rootwin, XtWindow(parent),
                        orig_x , orig_y, &trans_x, &trans_y, &win);

	resize_rect.width++;
	resize_rect.height++;

        /* Ensure new geometry fits within parent
         */
        if (trans_x < 0)
        {
            resize_rect.x = 0;
            resize_rect.width += trans_x;

	    if (obj_is_pane(obj) || obj_is_separator(obj)) /* If a pane, attach to parent's edge */
		obj_set_attachment(xy_obj, AB_CP_WEST, AB_ATTACH_OBJ, obj_get_parent(xy_obj), 0);
        }
        else    
	{
            resize_rect.x = trans_x;

            /* Break edge-attachment */
            if ((obj_is_pane(obj) || obj_is_separator(obj)) &&
                 (obj_get_attach_type(xy_obj, AB_CP_WEST) == AB_ATTACH_OBJ &&
                  obj_get_attach_value(xy_obj, AB_CP_WEST) == (void*)obj_get_parent(xy_obj)))
                obj_set_attachment(xy_obj, AB_CP_WEST, AB_ATTACH_POINT, (void*)0, trans_x);
        }

        if (trans_y < 0)
        {
            resize_rect.y = 0;
            resize_rect.height += trans_y;

            if (obj_is_pane(obj) || obj_is_separator(obj)) /* If a pane, attach to parent's edge */
                obj_set_attachment(xy_obj, AB_CP_NORTH, AB_ATTACH_OBJ, obj_get_parent(xy_obj), 0);
        }
        else
	{
            resize_rect.y = trans_y;

	    /* Break edge-attachment */
            if ((obj_is_pane(obj) || obj_is_separator(obj)) &&
		 (obj_get_attach_type(xy_obj, AB_CP_NORTH) == AB_ATTACH_OBJ &&
		  obj_get_attach_value(xy_obj, AB_CP_NORTH) == (void*)obj_get_parent(xy_obj))) 
                obj_set_attachment(xy_obj, AB_CP_NORTH, AB_ATTACH_POINT, (void*)0, trans_y);
	}

        if (resize_rect.x + (short)resize_rect.width >= (short)p_rect.width)
        {
            resize_rect.width = (short)p_rect.width - resize_rect.x - 1;

	    if (obj_is_pane(obj) || obj_is_separator(obj)) /* If a pane, attach to parent's edge */ 
		obj_set_attachment(xy_obj, AB_CP_EAST, AB_ATTACH_OBJ, obj_get_parent(xy_obj), 0);
	}
	else
	{
            /* Break edge-attachment */ 
	    if ((obj_is_pane(obj) || obj_is_separator(obj)) &&
                 (obj_get_attach_type(xy_obj, AB_CP_EAST) == AB_ATTACH_OBJ &&
                  obj_get_attach_value(xy_obj, AB_CP_EAST) == (void*)obj_get_parent(xy_obj))) 
                obj_set_attachment(xy_obj, AB_CP_EAST, AB_ATTACH_NONE, (void*)0, 0); 
        } 

        if (resize_rect.y + (short)resize_rect.height > (short)p_rect.height)
	{
            resize_rect.height = (short)p_rect.height - resize_rect.y - 1;

            if (obj_is_pane(obj) || obj_is_separator(obj)) /* If a pane, attach to parent's edge */
                obj_set_attachment(xy_obj, AB_CP_SOUTH, AB_ATTACH_OBJ, obj_get_parent(xy_obj), 0); 
	}
        else 
        {
            /* Break edge-attachment */ 
            if ((obj_is_pane(obj) || obj_is_separator(obj)) && 
                 (obj_get_attach_type(xy_obj, AB_CP_SOUTH) == AB_ATTACH_OBJ && 
                  obj_get_attach_value(xy_obj, AB_CP_SOUTH) == (void*)obj_get_parent(xy_obj)))  
                obj_set_attachment(xy_obj, AB_CP_SOUTH, AB_ATTACH_NONE, (void*)0, 0);  
        } 

	(void)abobj_set_undo(&obj, 1, undo_resize, AB_UNDO_RESIZE);

	pobj = obj_get_parent(obj);
 	if (obj_is_layers(pobj))
	    moveobj = pobj;
	else
	    moveobj = obj;

	adj_rect = resize_rect;
	if (abobj_has_attached_label(obj))
	    subtract_attached_label(obj, &adj_rect);

        if (obj_is_drawing_area(obj) && obj_has_scrollbar(obj))
        {
            int new_d_w = -1;
            int new_d_h = -1;
            int d_w = obj_get_drawarea_width(obj);
            int d_h = obj_get_drawarea_height(obj);
 
            /* If the overall DrawArea dimension is now larger than the internal
             * canvas dimension, resize the canvas dimension to be at least as large
             * as the overall DrawArea.
             */
            if ((int)resize_rect.width != obj_get_width(obj) &&
                (int)resize_rect.width > d_w)
                new_d_w = (int)resize_rect.width;
 
            if ((int)resize_rect.height != obj_get_height(obj) &&
                (int)resize_rect.height > d_h)
                new_d_h = (int)resize_rect.height;
 
            if (new_d_w != -1 || new_d_h != -1)
                abobj_set_drawarea_size(obj,
                        new_d_w != -1? new_d_w : d_w, new_d_h != -1? new_d_h : d_h);
        }

        /* 
 	 * Resize the object !
         */
	if (obj_is_layers(pobj))
	    abobj_layer_set_size(pobj, resize_rect.width, resize_rect.height);

        else if ((obj_is_text(obj) || obj_is_term_pane(obj)) &&
		  obj_get_num_columns(obj) != -1)
	    /* TextPane, TermPane, TextField with Character-based Sizing */
	    abobj_set_text_size(obj, (int)adj_rect.width, (int)adj_rect.height);

	else if (obj_is_list(obj) && obj_get_num_rows(obj) != -1)
	{
	    /* List with Character-based height */
	    abobj_set_text_size(obj, (int)adj_rect.width, (int)adj_rect.height);
	    abobj_set_pixel_width(obj, (int)adj_rect.width, border_w);
	}
	else /* else size is Pixel-based...*/
	    resize_in_pixels(obj, (int)adj_rect.width, (int)adj_rect.height, border_w);

        abobj_set_xy(moveobj, resize_rect.x, resize_rect.y);

	if (xy_obj->attachments)
	    abobj_calculate_new_layout(xy_obj, resize_rect.x, resize_rect.y,
		resize_rect.width, resize_rect.height);

	/* Change obj size BEFORE changing attachments...*/
	abobj_instantiate_changes(obj);
	abobj_tree_instantiate_changes(moveobj);

	/* WORKAROUND for Motif XmForm bug (it ignores child resize request 
	 * if x,y have not also changed). So, we have to force it.
	 */
	abobj_force_dang_form_resize(xy_obj);

	if (util_get_verbosity() > 3)
	    objxm_dump_widget_geometry(xy_widget);

        return OK;
    }
    return ERROR;

}
Ejemplo n.º 5
0
/*
 *    Draw rubberbanding outline for resizing action    
 */
int
abobjP_resize_object_outline(
    ABObj        obj,
    XEvent       *event,
    RESIZE_DIR   dir
)
{
    ABObj	       s_obj;
    static Widget      parent;
    static Window      rootwin;
    static Display     *dpy;
    static XRectangle  orig_r, r;
    static int         last_x, last_y;
    int                x,y;
    char               buf[80];

    if (event->type == MotionNotify)
    {
    	x = ((XMotionEvent*)event)->x_root;
    	y = ((XMotionEvent*)event)->y_root;
    }
    else if (event->type == ButtonPress)
    {
        x = ((XButtonEvent*)event)->x_root;
        y = ((XButtonEvent*)event)->y_root;
    } 
    else
	return -1;

    if (first_move)
    {
        Window     win;
        int    orig_x, orig_y;
        int    trans_x, trans_y;

	if (obj_is_item(obj))
	    obj = obj_get_parent(obj);

	obj  = obj_get_root(obj);
	xy_obj = objxm_comp_get_subobj(obj, AB_CFG_POSITION_OBJ);
	xy_widget = (Widget)xy_obj->ui_handle;
 
        if (xy_widget == NULL)
        {
            if (util_get_verbosity() > 0)
                fprintf(stderr,"abobjP_resize_object_outline: %s :no SIZE widget\n",
			util_strsafe(obj_get_name(obj)));
            return ERROR;
        }
 
        parent  = XtParent(xy_widget);
        dpy     = XtDisplay(xy_widget);
        rootwin = RootWindowOfScreen(XtScreen(xy_widget));

        x_get_widget_rect(xy_widget, &orig_r);
	if (obj_has_border_frame(obj)) /* We have a border-frame to deal with */
	{
	    XRectangle pane_r;

            s_obj = objxm_comp_get_subobj(obj, AB_CFG_SIZE_OBJ);

	    /* Determine width of border */
	    x_get_widget_rect(objxm_get_widget(s_obj), &pane_r);
	    border_w = ((int)(orig_r.width - pane_r.width))/2;
	}
	else
	    border_w = 0;

	orig_r.width--;
	orig_r.height--;

        r = orig_r;

        orig_x = (int)orig_r.x;
        orig_y = (int)orig_r.y;

        XTranslateCoordinates(dpy, XtWindow(parent),
            rootwin, orig_x , orig_y, &trans_x, &trans_y,
            &win);

        r.x = (short)trans_x;
        r.y = (short)trans_y;

        first_move = FALSE;
    }
    else     /* erase previous outline */    
    {
        make_rect(&resize_rect, &r, last_x, last_y, dir);
        x_fullscreen_box(xy_widget, rootwin, 
                resize_rect.x, resize_rect.y,
                rect_right(&resize_rect), 
                rect_bottom(&resize_rect));

    }

    make_rect(&resize_rect, &r, x, y, dir);
    x_fullscreen_box(xy_widget, rootwin, 
                resize_rect.x, resize_rect.y,
                                rect_right(&resize_rect), 
                rect_bottom(&resize_rect));

    sprintf(buf, "%3.3dx%3.3d", resize_rect.width,
                                resize_rect.height);

    /* REMIND: aim, update status region on ab palette win */

    last_x = x;
    last_y = y;

    return OK;

}
Ejemplo n.º 6
0
Custom_couple*  add_custom_coupling( Custom_person* Cp_ptr, short side )
{
	Custom_couple* Cc_ptr ;
	Custom_couple* sCc_ptr ;
	Custom_person* sCp_ptr ;		/* spouse Cp pointer		*/
	Custom_person* cCp_ptr ;		/* child Cp pointer			*/
	Person* pptr ;
	Couple* cptr ;
	BOOLEAN male ;			/* sex of pre-existing partner		*/
	short block ;
	int couple_reference = 0 ;
	int* new_coupling_list ;
	int* couple_list_ptr ;
	int* new_list_ptr ;
	char* coup_ptr ;
	int couple_ref ;				/* Couple reference number	*/
	int spouse_reference ;
	GRECT spouse_box ;
	short spouse_x ;
	short child_y ;
	int* child_number_ptr ;
	char* child_ptr ;
	int progeny[MAX_CHILDREN+1] ;
	int* prog_list_ptr ;
	short number_of_children ;
	short nearest_x ;
	short furthest_x ;
	short highest_y ;
	short parent_box_bottom ;

	Cc_ptr = new_custom_couple() ;
	if( Cc_ptr == NULL )  return Cc_ptr ;

	pptr = get_pdata_ptr( Cp_ptr->reference, &block ) ;
	coup_ptr = pptr->couplings ;	

	new_coupling_list = (int *) checked_malloc( ( Cp_ptr->couplings_drawn + 2 ) * sizeof( int ) ) ;
	if( new_coupling_list == NULL )
	{
		remove_custom_coupling( Cc_ptr ) ;
		return NULL ;
	}
	
	new_list_ptr = new_coupling_list ;

										/* find couple to add				*/

	if( Cp_ptr->couplings_drawn != 0 )
	{
		assert( Cp_ptr->coupling_list != NULL ) ;
												/* find first undrawn coupling	*/
		while( couple_ref = form_ref( &coup_ptr ), couple_ref != 0 && couple_reference == 0 )
		{
			BOOLEAN used ;
			
			couple_list_ptr = Cp_ptr->coupling_list ;
			used = FALSE ;
			while( *couple_list_ptr != 0 && couple_reference == 0 )
			{
				sCc_ptr = get_Cc_ptr( *couple_list_ptr++) ;
				if( couple_ref == sCc_ptr->reference )  used = TRUE ;
			}
			if( !used )  couple_reference = couple_ref ;
			else  couple_list_ptr++ ;
		}
		couple_list_ptr = Cp_ptr->coupling_list ;	
		while( *couple_list_ptr )
			*new_list_ptr++ = *couple_list_ptr++ ;
		free( Cp_ptr->coupling_list ) ;
	}
	else  couple_reference = form_ref( &coup_ptr ) ;

										/* initialise some values			*/

	*new_list_ptr++ = Cc_ptr->list_number ;
	*new_list_ptr++ = 0 ;
	Cc_ptr->reference = couple_reference ;
	Cp_ptr->coupling_list = new_coupling_list ;
	Cp_ptr->couplings_drawn++ ;
	
	Cc_ptr->y = Cp_ptr->y ;

										/* ascertain sex of existing		*/
										/* partner and ref of spouse, if	*/
										/* any								*/
	if( couples[couple_reference].male_reference == Cp_ptr->reference )
	{
		male = TRUE ;
		Cc_ptr->male_number = Cp_ptr->list_number ;
		spouse_reference = couples[couple_reference].female_reference ;
	}
	else
	{
		male = FALSE ;
		Cc_ptr->female_number = Cp_ptr->list_number ;
		spouse_reference = couples[couple_reference].male_reference ;
	}

										/* if spouse, add them to tree and	*/
										/* calculate lowest point of couple	*/

	if( spouse_reference != 0 )
	{
		if( male && side == CUST_LEFT || !male && side == CUST_RIGHT )  Cc_ptr->status |= CUST_REVERSED ;
	
		spouse_box = get_box_size( spouse_reference, 0, 0, custom_tree.attributes, NULL, 0 ) ;
		if( side == RIGHT )  Cc_ptr->x = rect_end( &(Cp_ptr->box) ) + couple_gap ;
		else  Cc_ptr->x = Cp_ptr->box.g_x - couple_gap ;
	
		if( side == RIGHT )  spouse_x = Cc_ptr->x + spouse_box.g_w / 2 + couple_gap ;
		else  spouse_x = Cc_ptr->x - spouse_box.g_w / 2 - couple_gap ;
		sCp_ptr = add_custom_person( spouse_reference, spouse_x, Cc_ptr->y, NULL, 0 ) ;
		if( sCp_ptr != NULL )
		{
			sCp_ptr->couplings_drawn = 1 ;
			if( male )  Cc_ptr->female_number = sCp_ptr->list_number ;
			else  Cc_ptr->male_number = sCp_ptr->list_number ;

			sCp_ptr->coupling_list = (int *) checked_malloc( 2 * sizeof( int ) ) ;
			if( sCp_ptr->coupling_list != NULL )
			{
				*(sCp_ptr->coupling_list) = Cc_ptr->list_number ;
				*(sCp_ptr->coupling_list + 1) = 0 ;	/* terminate list	*/
			}
		}
		if( rect_bottom( &(sCp_ptr->box) ) > rect_bottom( &(Cp_ptr->box) ) )
			parent_box_bottom = rect_bottom( &(sCp_ptr->box) ) ;
		else  parent_box_bottom = rect_bottom( &(Cp_ptr->box) ) ;
	}

										/* else if no spouse set bottom of	*/
										/* couple to bottom of person and	*/
										/* set spouse number to 0			*/

	else
	{
		Cc_ptr->x = Cp_ptr->x ;
		parent_box_bottom = rect_bottom( &(Cp_ptr->box) ) ;
		if( male )  Cc_ptr->female_number = 0 ;
		else  Cc_ptr->male_number = 0 ;
	}
										/* set hline_y even if there are no	*/
										/* children yet, ready for updating	*/
	Cc_ptr->hline_y = parent_box_bottom + generation_gap / 2 ;
	Cc_ptr->hline_x0 = Cc_ptr->x ;
	Cc_ptr->hline_x1 = Cc_ptr->x ;

										/* if any children, add them to		*/
										/* tree and couple list				*/

	cptr = get_cdata_ptr( Cc_ptr->reference, &block ) ;
	if( child_ptr = cptr->children, child_ptr != NULL )
	{
		prog_list_ptr = progeny ;
		number_of_children = 0 ;
		while( *prog_list_ptr++ = form_ref( &child_ptr ) )
		{
			number_of_children++ ;
		}
		Cc_ptr->child_numbers = (int *) checked_malloc( ( number_of_children + 1 ) * sizeof( int ) ) ;
		if( Cc_ptr->child_numbers != NULL )
		{
			int previous_last_number ;
			
			previous_last_number = custom_tree.end_person->list_number ;
			child_y = Cc_ptr->y + generation_gap ;
									/* measure width of children and add them at an arbitrary x position (i.e. 0)	*/
			highest_y = child_y ;	/* initialise to too low value	*/
			add_children( progeny, 0, Cc_ptr, TRUE, 0, 0,
								child_y, &furthest_x, &highest_y) ;

			prog_list_ptr = progeny ;
			child_number_ptr = Cc_ptr->child_numbers ;
			while( *prog_list_ptr )
			{
				*child_number_ptr++ = get_cust_person_by_ref( *prog_list_ptr++, previous_last_number ) ;
			}
			*child_number_ptr = 0 ;

			child_number_ptr = Cc_ptr->child_numbers ;
			cCp_ptr = get_Cp_ptr( Cc_ptr->child_numbers[0] ) ;
			nearest_x = cCp_ptr->x ;

			while( *child_number_ptr )
			{
				cCp_ptr = get_Cp_ptr( *child_number_ptr++ ) ;
				cCp_ptr->x += Cc_ptr->x - ( nearest_x + furthest_x ) / 2 ;
				cCp_ptr->box.g_x += Cc_ptr->x - ( nearest_x + furthest_x ) / 2 ;
				cCp_ptr->y += Cc_ptr->hline_y + generation_gap / 2 - highest_y ;
				cCp_ptr->box.g_y += Cc_ptr->hline_y + generation_gap / 2 - highest_y ;
			}

			cCp_ptr = get_Cp_ptr( Cc_ptr->child_numbers[0] ) ;
			Cc_ptr->hline_x0 = cCp_ptr->x ;
			if( custom_display.x_start <= custom_tree.org_x )
			{
				if( Cc_ptr->x - 1 < custom_display.x_start )
					custom_display.x_start = Cc_ptr->x - 1 ;
			}
			cCp_ptr = get_Cp_ptr( Cc_ptr->child_numbers[number_of_children - 1] ) ;
			Cc_ptr->hline_x1 = cCp_ptr->x ; 
		}
	}

	return Cc_ptr ;
}
Ejemplo n.º 7
0
Custom_couple*  add_custom_parents( Custom_person* Cp_ptr )
{
	Custom_couple* Cc_ptr ;
	int siblings[MAX_CHILDREN] ;
	Custom_person* mCp_ptr = NULL ;		/* pointer to male parent		*/
	Custom_person* fCp_ptr = NULL ;		/* pointer to female parent		*/
	Person* pptr ;
	Couple* cptr ;
	int parents ;
	int father, mother ;
	int ref ;				/* temporary reference					*/
	short child ;			/* loop counter							*/
	short children ;		/* number of siblings, inc original		*/
	char* child_refs_ptr ;	/* pointer to references				*/
	short base_position_y ;		/* y position of original child		*/
	short upper_limit, lower_limit ;
	short leftest_sibling_x, rightest_sibling_x ;
	short highest_position_y ;
	short father_x, mother_x ;
	GRECT box_father, box_mother ;
	short parent_box_bottom ;
	short block ;			/* block number for get_[p/c]data_ptr	*/
	BOOLEAN fail = FALSE ;
	
	Cc_ptr = new_custom_couple() ;
	if( Cc_ptr == NULL )  return Cc_ptr ;
	pptr = get_pdata_ptr( Cp_ptr->reference, &block ) ;	
	assert( pptr != NULL ) ;
	parents = pptr->parents ;
	assert( parents != 0 ) ;
	Cc_ptr->reference = parents ;
	
	Cp_ptr->parent_number = Cc_ptr->list_number ;

	cptr = get_cdata_ptr( parents, &block ) ;
	child_refs_ptr = cptr->children ;
	assert( child_refs_ptr ) ;

					/* Force temporary father number in order that	*/
					/* auto_fname will work for add children.		*/
					/* Note that male_reference is wrongly used, it	*/
					/* will later be replaced with list number.		*/
	Cc_ptr->male_number = couples[parents].male_reference ;

				/* if person has auto fname, their size will change	*/
				/* with the addition of their father. Adjust their	*/
				/* position to allow for this if they are coupled.	*/
	if( cptr->male_reference != 0
		&& ( Cp_ptr->attributes & FNAME_AUTO_BIT
			|| ( (Cp_ptr->attributes & FNAME_BITS) == 0
				&& custom_tree.attributes & FNAME_AUTO_BIT ) ) )
	{
		Custom_couple* xCc_ptr ;
		short old_edge_x ;		/* active edge of person's box	*/
		short x_correction ;
		short reversed = FALSE ;
		short not_reversed = FALSE ;
		short coupling_index = 0 ;
		BOOLEAN left_partner = FALSE ;
		
		if( Cp_ptr->couplings_drawn != 0 )
		{
			while( *(Cp_ptr->coupling_list + coupling_index) )
			{
				xCc_ptr = get_Cc_ptr( *(Cp_ptr->coupling_list + coupling_index) ) ;
				assert( xCc_ptr ) ;
			
				if( xCc_ptr->status & CUST_REVERSED )  reversed = TRUE ;
				else  not_reversed = TRUE ;

				coupling_index++ ;
			}
				/* check if adjustment is possible, i.e. all	*/
				/* couplings on same side						*/
			if( reversed && !not_reversed || not_reversed && !reversed )
			{
				if( !reversed && xCc_ptr->male_number == Cp_ptr->list_number )
					left_partner = TRUE ;
				if( left_partner )
					old_edge_x = rect_end( &(Cp_ptr->box) ) ;
				else  old_edge_x = Cp_ptr->box.g_x ;
			}
		}
			
		Cp_ptr->box = calculate_box( Cp_ptr->reference, Cp_ptr->x, Cp_ptr->y,
				Cp_ptr->attributes, Cp_ptr->font_ptr, Cp_ptr->parent_number ) ;

		if( Cp_ptr->couplings_drawn != 0 )
		{
			if( left_partner )  x_correction = old_edge_x - rect_end( &(Cp_ptr->box) ) ;
			else  x_correction = old_edge_x - Cp_ptr->box.g_x ;
			Cp_ptr->x += x_correction ;
			Cp_ptr->box.g_x += x_correction ;
		}
	}

	child = 0 ;
	while( ( ref = form_ref( &child_refs_ptr ) ) && ( child < MAX_CHILDREN ) )
	{
		siblings[child] = ref ;
		child++ ;
	}
	siblings[child] = 0 ;
	children = child ;

				/* find current person in sibling array				*/
	child = 0 ;
	while( siblings[child] != Cp_ptr->reference )  child++ ;

	Cc_ptr->child_numbers = (int*) checked_malloc( (children + 1) * sizeof( int ) ) ;
	if( Cc_ptr->child_numbers == NULL )
	{
		Cp_ptr->parent_number = 0 ;
		remove_custom_coupling( Cc_ptr ) ;
		return NULL ;
	}
	
	Cc_ptr->child_numbers[child] = Cp_ptr->list_number ;
	Cc_ptr->child_numbers[children] = 0 ;						/* terminate list	*/

	upper_limit = Cp_ptr->box.g_x + Cp_ptr->box.g_w / 2 ;
	leftest_sibling_x = upper_limit ;	/* initialise limits to centre of original	*/
	rightest_sibling_x = upper_limit ;
	lower_limit = Cp_ptr->box.g_x ;
	base_position_y = Cp_ptr->box.g_y - Cp_ptr->box.g_h / 2 ;
	highest_position_y = Cp_ptr->box.g_y ;
	
												/* add any children to the left		*/
	if( child >= 1 )  fail = add_children( siblings, child-1, Cc_ptr, FALSE, upper_limit, lower_limit,
								base_position_y, &leftest_sibling_x, &highest_position_y) ;
	else  leftest_sibling_x = Cp_ptr->x ;
	
	if( fail )
	{
		Cp_ptr->parent_number = 0 ;
		remove_custom_coupling( Cc_ptr ) ;
		return NULL ;
	}
												/* add any children to the right	*/
	if( child+1 < children )  fail = add_children( siblings, child+1, Cc_ptr, TRUE, upper_limit, lower_limit,
								base_position_y, &rightest_sibling_x, &highest_position_y) ;
	else  rightest_sibling_x = Cp_ptr->x ;
	if( fail )
	{
		if( child >= 1 )
			while( --child >= 0 )
				remove_custom_person( get_Cp_ptr( Cc_ptr->child_numbers[child] ) ) ;
		Cp_ptr->parent_number = 0 ;
		remove_custom_coupling( Cc_ptr ) ;
		return NULL ;
	}

	if( father = couples[parents].male_reference )
		box_father = get_box_size( father, 0, 0, custom_tree.attributes, NULL, 0 ) ;
	if( mother = couples[parents].female_reference )
		box_mother = get_box_size( mother, 0, 0, custom_tree.attributes, NULL, 0 ) ;
	if( father )  Cc_ptr->y = highest_position_y - box_father.g_h - generation_gap ;
	else  Cc_ptr->y = highest_position_y - box_mother.g_h - generation_gap ;
	
	Cc_ptr->x = (leftest_sibling_x + rightest_sibling_x) / 2 ;
	if( father && mother )
	{
		father_x = Cc_ptr->x - box_father.g_w / 2 - couple_gap ;
		mother_x = Cc_ptr->x + box_mother.g_w / 2 + couple_gap ;
	}
	else
	{
		father_x = Cc_ptr->x ;
		mother_x = Cc_ptr->x ;
	}
	
	if( father )
	{
		mCp_ptr = add_custom_person( father, father_x, Cc_ptr->y, NULL, 0 ) ;
		if( mCp_ptr != NULL )
		{
			mCp_ptr->couplings_drawn = 1 ;
			Cc_ptr->male_number = mCp_ptr->list_number ;
			mCp_ptr->coupling_list = (int *) checked_malloc( 2 * sizeof( int ) ) ;
			if( mCp_ptr->coupling_list != NULL )
			{
				*(mCp_ptr->coupling_list) = Cc_ptr->list_number ;
				*(mCp_ptr->coupling_list + 1) = 0 ;	/* terminate list	*/
			}
			else  fail = TRUE ;
			parent_box_bottom = rect_bottom( &(mCp_ptr->box) ) ;
		}
		else  fail = TRUE ;
	}
	if( !fail && mother )
	{
		fCp_ptr = add_custom_person( mother, mother_x, Cc_ptr->y, NULL, 0 ) ;
		if( fCp_ptr != NULL )
		{
			fCp_ptr->couplings_drawn = 1 ;
			Cc_ptr->female_number = fCp_ptr->list_number ;
			fCp_ptr->coupling_list = (int *) checked_malloc( 2 * sizeof( int ) ) ;
			if( fCp_ptr->coupling_list != NULL )
			{
				*(fCp_ptr->coupling_list) = Cc_ptr->list_number ;
				*(fCp_ptr->coupling_list + 1) = 0 ;	/* terminate list	*/
			}
			else  fail = TRUE ;
		}
		else  fail = TRUE ;
		if( father )
		{
			if( rect_bottom( &(fCp_ptr->box) ) > parent_box_bottom )
				parent_box_bottom = rect_bottom( &(fCp_ptr->box) ) ;
		}
		else  parent_box_bottom = rect_bottom( &(fCp_ptr->box) ) ;
	}

	Cc_ptr->hline_x0 = leftest_sibling_x ;
	Cc_ptr->hline_x1 = rightest_sibling_x ;
	Cc_ptr->hline_y = parent_box_bottom + generation_gap / 2 ;

	if( fail )
	{
					/* remove children			*/
		child = 0 ;
		while( child < children )
		{
			if( Cc_ptr->child_numbers[child] != Cp_ptr->list_number )
				remove_custom_person( get_Cp_ptr( Cc_ptr->child_numbers[child] ) ) ;
			child++ ;
		}
		if( mCp_ptr )  remove_custom_person( mCp_ptr ) ;
		if( fCp_ptr )  remove_custom_person( fCp_ptr ) ;
		Cp_ptr->parent_number = 0 ;
		remove_custom_coupling( Cc_ptr ) ;
		Cc_ptr = NULL ;
	}
	return Cc_ptr ;
}