/***********************************************************************
* link_draw_rules.c: Implementation of the list of rules for drawing
* the links.
***********************************************************************/
/***********************************************************************
* This file is part of SpaceChart.
* Copyright (C) 2000 Miguel Coca <e970095@zipi.fi.upm.es>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
***********************************************************************/
#include <stdlib.h>
#include <float.h>
#include <gdk/gdk.h>
#include "../include/starmap.h"
#include "../include/link.h"
#include "../include/link_selection.h"
#include "../include/link_draw_rules.h"
struct list_node
{
link_selection_t* selection;
int width;
GdkLineStyle style;
double rgb[3];
};
struct st_link_drawing_rules
{
GdkLineStyle default_style;
double default_color[3];
int default_width;
struct list_node** list;
};
/* Definition of local functions */
static int rule_list_add( struct list_node** list[],
link_selection_t* selection, int width,
GdkLineStyle style, double rgb[] );
static void rule_list_find( struct list_node* list[], link_t *link,
int* width, GdkLineStyle* style, double rgb[] );
static void rule_list_destroy( struct list_node* list[] );
static int rule_list_length( struct list_node* list[] );
static void rule_list_foreach( struct list_node* list[],
void (*function)( link_selection_t *selection,
int width,
GdkLineStyle style,
double rgb[],
void* data ),
void* data );
/* Public Functions */
link_drawing_rules_t* link_drawing_rules_new( int default_width,
GdkLineStyle default_style,
double default_rgb[] )
{
link_drawing_rules_t* rules;
if( ( rules = (link_drawing_rules_t*)
malloc( sizeof( link_drawing_rules_t ) ) ) &&
( rules->list = (struct list_node**)
malloc( sizeof(struct list_node*) ) ) )
{
rules->default_width = default_width;
rules->default_style = default_style;
rules->default_color[0] = default_rgb[0];
rules->default_color[1] = default_rgb[1];
rules->default_color[2] = default_rgb[2];
rules->list[0] = NULL;
}
return rules;
}
void link_drawing_rules_get_default( link_drawing_rules_t* rules, int *width,
GdkLineStyle *style, double rgb[] )
{
*width = rules->default_width;
*style = rules->default_style;
rgb[0] = rules->default_color[0];
rgb[1] = rules->default_color[1];
rgb[2] = rules->default_color[2];
}
void link_drawing_rules_find( link_drawing_rules_t* rules,
link_t *link, int* width,
GdkLineStyle* style, double rgb[] )
{
*width = rules->default_width;
*style = rules->default_style;
rgb[0] = rules->default_color[0];
rgb[1] = rules->default_color[1];
rgb[2] = rules->default_color[2];
rule_list_find( rules->list, link, width, style, rgb );
}
int link_drawing_rules_add( link_drawing_rules_t* rules,
link_selection_t* selection, int width,
GdkLineStyle style, double rgb[] )
{
return rule_list_add( &(rules->list), selection, width, style, rgb );
}
void link_drawing_rules_foreach( link_drawing_rules_t* rules,
void (*function)( link_selection_t* selection,
int width,
GdkLineStyle style,
double rgb[],
void* data ),
void* data )
{
rule_list_foreach( rules->list, function, data );
}
void link_drawing_rules_destroy( link_drawing_rules_t* rules )
{
rule_list_destroy( rules->list );
free( rules );
}
/* Local Functions */
int rule_list_add( struct list_node** list[], link_selection_t* selection,
int width, GdkLineStyle style, double rgb[] )
{
struct list_node** aux;
struct list_node* new_node;
int length;
if( ( new_node = (struct list_node*)
malloc( sizeof( struct list_node ) ) ) )
{
new_node->width = width;
new_node->style = style;
new_node->rgb[0] = rgb[0];
new_node->rgb[1] = rgb[1];
new_node->rgb[2] = rgb[2];
new_node->selection = selection;
length = rule_list_length( *list );
if( ( aux = realloc( *list,(length+2) *
sizeof( struct list_node* ) ) ) )
{
*list = aux;
(*list)[length] = new_node;
(*list)[length+1] = NULL;
}
else
{
free( new_node );
return 0;
}
return 1;
}
else
return 0;
}
void rule_list_find( struct list_node* list[], link_t *link,
int* width, GdkLineStyle* style, double rgb[] )
{
register int matches = 0;
register struct list_node** list_aux;
for( list_aux=list; *list_aux && !matches; list_aux++ )
{
matches = link_selection_match( (*list_aux)->selection, link );
if( matches )
{
if( width )
*width = (*list_aux)->width;
if( style )
*style = (*list_aux)->style;
if( rgb )
{
rgb[0] = (*list_aux)->rgb[0];
rgb[1] = (*list_aux)->rgb[1];
rgb[2] = (*list_aux)->rgb[2];
}
}
}
}
void rule_list_destroy( struct list_node* list[] )
{
int i;
for( i = 0; list[i]; i++ )
{
link_selection_destroy( list[i]->selection );
free( list[i] );
}
free( list );
}
int rule_list_length( struct list_node* list[] )
{
register int i;
for( i = 0; list[i]; i++ )
;
return i;
}
void rule_list_foreach( struct list_node* list[],
void (*function)( link_selection_t *selection,
int width,
GdkLineStyle style,
double rgb[],
void* data ),
void* data )
{
int i;
for( i = 0; list[i]; i++ )
{
function( list[i]->selection, list[i]->width,
list[i]->style, list[i]->rgb, data );
}
}
syntax highlighted by Code2HTML, v. 0.9.1