Also find terminals on ends of connections.
This commit is contained in:
		
							parent
							
								
									8aef3fc772
								
							
						
					
					
						commit
						f074bc6742
					
				| @ -181,6 +181,18 @@ typedef struct | |||||||
| } | } | ||||||
| DrawData; | DrawData; | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * CheckTerminalsData: | ||||||
|  |  */ | ||||||
|  | typedef struct | ||||||
|  | { | ||||||
|  | 	gboolean found; | ||||||
|  | 	gdouble distance; | ||||||
|  | 	LdPoint point; | ||||||
|  | 	LdPoint terminal; | ||||||
|  | } | ||||||
|  | CheckTerminalsData; | ||||||
|  | 
 | ||||||
| enum | enum | ||||||
| { | { | ||||||
| 	PROP_0, | 	PROP_0, | ||||||
| @ -240,9 +252,15 @@ static gboolean is_object_selected (LdDiagramView *self, | |||||||
| static void queue_draw (LdDiagramView *self, LdRectangle *rect); | static void queue_draw (LdDiagramView *self, LdRectangle *rect); | ||||||
| static void queue_object_draw (LdDiagramView *self, LdDiagramObject *object); | static void queue_object_draw (LdDiagramView *self, LdDiagramObject *object); | ||||||
| 
 | 
 | ||||||
| /* Symbol terminals. */ | /* Terminals. */ | ||||||
| static void check_terminals (LdDiagramView *self, const LdPoint *point); | static void check_terminals (LdDiagramView *self, const LdPoint *point); | ||||||
| static void rotate_terminal (LdPoint *terminal, gint symbol_rotation); | static void check_terminals_point (LdDiagramView *self, const LdPoint *point, | ||||||
|  | 	CheckTerminalsData *data); | ||||||
|  | void check_connection_terminals (LdDiagramView *self, | ||||||
|  | 	LdDiagramConnection *connection, CheckTerminalsData *data); | ||||||
|  | void check_symbol_terminals (LdDiagramView *self, | ||||||
|  | 	LdDiagramSymbol *diagram_symbol, CheckTerminalsData *data); | ||||||
|  | static void rotate_symbol_terminal (LdPoint *terminal, gint symbol_rotation); | ||||||
| static void hide_terminals (LdDiagramView *self); | static void hide_terminals (LdDiagramView *self); | ||||||
| static void queue_terminal_draw (LdDiagramView *self, LdPoint *terminal); | static void queue_terminal_draw (LdDiagramView *self, LdPoint *terminal); | ||||||
| 
 | 
 | ||||||
| @ -1248,72 +1266,118 @@ queue_object_draw (LdDiagramView *self, LdDiagramObject *object) | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /* ===== Symbol terminals ================================================== */ | /* ===== Terminals ========================================================= */ | ||||||
| 
 | 
 | ||||||
| static void | static void | ||||||
| check_terminals (LdDiagramView *self, const LdPoint *point) | check_terminals (LdDiagramView *self, const LdPoint *point) | ||||||
| { | { | ||||||
| 	GList *objects, *iter; | 	GList *objects, *iter; | ||||||
| 	LdDiagramSymbol *closest_symbol = NULL; | 	CheckTerminalsData data; | ||||||
| 	gdouble closest_distance = TERMINAL_HOVER_TOLERANCE; | 
 | ||||||
| 	LdPoint closest_terminal; | 	data.found = FALSE; | ||||||
|  | 	data.point = *point; | ||||||
|  | 	data.distance = TERMINAL_HOVER_TOLERANCE; | ||||||
| 
 | 
 | ||||||
| 	objects = (GList *) ld_diagram_get_objects (self->priv->diagram); | 	objects = (GList *) ld_diagram_get_objects (self->priv->diagram); | ||||||
| 	for (iter = objects; iter; iter = g_list_next (iter)) | 	for (iter = objects; iter; iter = g_list_next (iter)) | ||||||
| 	{ | 	{ | ||||||
| 		gdouble object_x, object_y; | 		if (LD_IS_DIAGRAM_CONNECTION (iter->data)) | ||||||
| 		LdDiagramSymbol *diagram_symbol; | 			check_connection_terminals (self, iter->data, &data); | ||||||
| 		LdSymbol *symbol; | 		else if (LD_IS_DIAGRAM_SYMBOL (iter->data)) | ||||||
| 		const LdPointArray *terminals; | 			check_symbol_terminals (self, iter->data, &data); | ||||||
| 		guint i; |  | ||||||
| 		gint rotation; |  | ||||||
| 
 |  | ||||||
| 		if (!LD_IS_DIAGRAM_SYMBOL (iter->data)) |  | ||||||
| 			continue; |  | ||||||
| 
 |  | ||||||
| 		diagram_symbol = LD_DIAGRAM_SYMBOL (iter->data); |  | ||||||
| 		symbol = resolve_symbol (self, diagram_symbol); |  | ||||||
| 		if (!symbol) |  | ||||||
| 			continue; |  | ||||||
| 
 |  | ||||||
| 		g_object_get (diagram_symbol, "x", &object_x, "y", &object_y, |  | ||||||
| 			"rotation", &rotation, NULL); |  | ||||||
| 
 |  | ||||||
| 		terminals = ld_symbol_get_terminals (symbol); |  | ||||||
| 		for (i = 0; i < terminals->length; i++) |  | ||||||
| 		{ |  | ||||||
| 			LdPoint cur_term, widget_coords; |  | ||||||
| 			gdouble distance; |  | ||||||
| 
 |  | ||||||
| 			cur_term = terminals->points[i]; |  | ||||||
| 			rotate_terminal (&cur_term, rotation); |  | ||||||
| 			cur_term.x += object_x; |  | ||||||
| 			cur_term.y += object_y; |  | ||||||
| 
 |  | ||||||
| 			ld_diagram_view_diagram_to_widget_coords (self, |  | ||||||
| 				cur_term.x, cur_term.y, &widget_coords.x, &widget_coords.y); |  | ||||||
| 			distance = ld_point_distance (&widget_coords, point->x, point->y); |  | ||||||
| 			if (distance <= closest_distance) |  | ||||||
| 			{ |  | ||||||
| 				closest_symbol = diagram_symbol; |  | ||||||
| 				closest_distance = distance; |  | ||||||
| 				closest_terminal = cur_term; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	hide_terminals (self); | 	hide_terminals (self); | ||||||
| 
 | 
 | ||||||
| 	if (closest_symbol) | 	if (data.found) | ||||||
| 	{ | 	{ | ||||||
| 		self->priv->terminal_hovered = TRUE; | 		self->priv->terminal_hovered = TRUE; | ||||||
| 		self->priv->terminal = closest_terminal; | 		self->priv->terminal = data.terminal; | ||||||
| 		queue_terminal_draw (self, &closest_terminal); | 		queue_terminal_draw (self, &data.terminal); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void | static void | ||||||
| rotate_terminal (LdPoint *terminal, gint symbol_rotation) | check_terminals_point (LdDiagramView *self, const LdPoint *point, | ||||||
|  | 	CheckTerminalsData *data) | ||||||
|  | { | ||||||
|  | 	LdPoint widget_coords; | ||||||
|  | 	gdouble distance; | ||||||
|  | 
 | ||||||
|  | 	ld_diagram_view_diagram_to_widget_coords (self, | ||||||
|  | 		point->x, point->y, &widget_coords.x, &widget_coords.y); | ||||||
|  | 	distance = ld_point_distance (&widget_coords, | ||||||
|  | 		data->point.x, data->point.y); | ||||||
|  | 	if (distance <= data->distance) | ||||||
|  | 	{ | ||||||
|  | 		data->distance = distance; | ||||||
|  | 		data->terminal = *point; | ||||||
|  | 		data->found = TRUE; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | check_connection_terminals (LdDiagramView *self, | ||||||
|  | 	LdDiagramConnection *connection, CheckTerminalsData *data) | ||||||
|  | { | ||||||
|  | 	LdPointArray *points; | ||||||
|  | 	gdouble object_x, object_y; | ||||||
|  | 	guint last; | ||||||
|  | 
 | ||||||
|  | 	g_object_get (connection, "x", &object_x, "y", &object_y, NULL); | ||||||
|  | 
 | ||||||
|  | 	points = ld_diagram_connection_get_points (connection); | ||||||
|  | 	if (points->length < 2) | ||||||
|  | 	{ | ||||||
|  | 		ld_point_array_free (points); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	points->points[0].x += object_x; | ||||||
|  | 	points->points[0].y += object_y; | ||||||
|  | 	check_terminals_point (self, &points->points[0], data); | ||||||
|  | 
 | ||||||
|  | 	last = points->length - 1; | ||||||
|  | 	points->points[last].x += object_x; | ||||||
|  | 	points->points[last].y += object_y; | ||||||
|  | 	check_terminals_point (self, &points->points[last], data); | ||||||
|  | 
 | ||||||
|  | 	ld_point_array_free (points); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | check_symbol_terminals (LdDiagramView *self, | ||||||
|  | 	LdDiagramSymbol *diagram_symbol, CheckTerminalsData *data) | ||||||
|  | { | ||||||
|  | 	gdouble object_x, object_y; | ||||||
|  | 	LdSymbol *symbol; | ||||||
|  | 	const LdPointArray *terminals; | ||||||
|  | 	guint i; | ||||||
|  | 	gint rotation; | ||||||
|  | 
 | ||||||
|  | 	symbol = resolve_symbol (self, diagram_symbol); | ||||||
|  | 	if (!symbol) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	g_object_get (diagram_symbol, "x", &object_x, "y", &object_y, | ||||||
|  | 		"rotation", &rotation, NULL); | ||||||
|  | 
 | ||||||
|  | 	terminals = ld_symbol_get_terminals (symbol); | ||||||
|  | 	for (i = 0; i < terminals->length; i++) | ||||||
|  | 	{ | ||||||
|  | 		LdPoint cur_term; | ||||||
|  | 
 | ||||||
|  | 		cur_term = terminals->points[i]; | ||||||
|  | 		rotate_symbol_terminal (&cur_term, rotation); | ||||||
|  | 		cur_term.x += object_x; | ||||||
|  | 		cur_term.y += object_y; | ||||||
|  | 
 | ||||||
|  | 		check_terminals_point (self, &cur_term, data); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | rotate_symbol_terminal (LdPoint *terminal, gint symbol_rotation) | ||||||
| { | { | ||||||
| 	gdouble temp; | 	gdouble temp; | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user