diff options
author | Kristian Høgsberg <krh@redhat.com> | 2006-07-08 05:16:11 -0400 |
---|---|---|
committer | Kristian Høgsberg <krh@redhat.com> | 2006-07-08 05:16:11 -0400 |
commit | cde68c08fa0a7cc76900f6218eb972a6cbc660a5 (patch) | |
tree | e93d7948f49f84bf7ff9cc99a020bd0fd83540ed | |
parent | f7258dd26ef90de18bfc1b36ea4559342bb600eb (diff) |
Make more of the model dynamic, start porting over main.c.
-rw-r--r-- | akamaru.c | 159 | ||||
-rw-r--r-- | akamaru.h | 10 | ||||
-rw-r--r-- | main.c | 58 |
3 files changed, 136 insertions, 91 deletions
@@ -109,6 +109,20 @@ stick_init (Stick *stick, Object *a, Object *b, double length) stick->length = length; } +Stick * +model_add_stick (Model *model, Object *a, Object *b, double length) +{ + Stick *stick; + + stick = g_new (Stick, 1); + stick->a = a; + stick->b = b; + stick->length = length; + list_append (&model->stick_list, stick); + + return stick; +} + void string_init (String *string, Object *a, Object *b, double length) { @@ -117,6 +131,20 @@ string_init (String *string, Object *a, Object *b, double length) string->length = length; } +String * +model_add_string (Model *model, Object *a, Object *b, double length) +{ + String *string; + + string = g_new (String, 1); + string->a = a; + string->b = b; + string->length = length; + list_append (&model->string_list, string); + + return string; +} + void offset_spring_init (OffsetSpring *spring, Object *a, Object *b, double dx, double dy) @@ -267,8 +295,11 @@ model_init (Model *model) list_init (&model->object_list, G_STRUCT_OFFSET (Object, link)); list_init (&model->spacer_list, G_STRUCT_OFFSET (Spacer, link)); list_init (&model->spring_list, G_STRUCT_OFFSET (Spring, link)); + list_init (&model->stick_list, G_STRUCT_OFFSET (Stick, link)); + list_init (&model->string_list, G_STRUCT_OFFSET (String, link)); list_init (&model->anchor_list, G_STRUCT_OFFSET (Anchor, link)); list_init (&model->polygon_list, G_STRUCT_OFFSET (Polygon, link)); + list_init (&model->offset_list, G_STRUCT_OFFSET (Offset, link)); } Object * @@ -508,13 +539,12 @@ model_constrain_anchor (void *element, void *data) anchor->object->position.x = anchor->x; anchor->object->position.y = anchor->y; - anchor->object->previous_position.x = anchor->x; - anchor->object->previous_position.y = anchor->y; } static void -model_constrain_offset (Model *model, Offset *offset) +model_constrain_offset (void *element, void *data) { + Offset *offset = element; double x, y; int i; @@ -535,6 +565,29 @@ model_constrain_offset (Model *model, Offset *offset) } static void +model_constrain_string (void *element, void *data) +{ + String *string = element; + double x, y, dx, dy, distance, fraction; + + x = string->a->position.x; + y = string->a->position.y; + dx = string->b->position.x - x; + dy = string->b->position.y - y; + distance = estimate_distance (dx, dy, string->length); + + if (distance < string->length) + return; + + fraction = (distance - string->length) / distance / 2; + string->a->position.x = x + dx * fraction; + string->a->position.y = y + dy * fraction; + string->b->position.x = x + dx * (1 - fraction); + string->b->position.y = y + dy * (1 - fraction); +} + + +static void model_constrain_spacer (void *element, void *data) { Spacer *spacer = element; @@ -556,53 +609,34 @@ model_constrain_spacer (void *element, void *data) spacer->b->position.y = y + dy * (1 - fraction); } - static void -model_constrain (Model *model) +model_constrain_stick (void *element, void *data) { - double dx, dy, x, y, distance, fraction; - int i; - - list_for_each (&model->anchor_list, model_constrain_anchor, model); - - /* String constraints. */ - for (i = 0; i < model->num_strings; i++) { - x = model->strings[i].a->position.x; - y = model->strings[i].a->position.y; - dx = model->strings[i].b->position.x - x; - dy = model->strings[i].b->position.y - y; - distance = estimate_distance (dx, dy, model->strings[i].length); - if (distance < model->strings[i].length) - continue; - fraction = (distance - model->strings[i].length) / distance / 2; - model->strings[i].a->position.x = x + dx * fraction; - model->strings[i].a->position.y = y + dy * fraction; - model->strings[i].b->position.x = x + dx * (1 - fraction); - model->strings[i].b->position.y = y + dy * (1 - fraction); - } + Stick *stick = element; + double x, y, dx, dy, distance, fraction; - /* Spacer constraints. */ - list_for_each (&model->spacer_list, model_constrain_spacer, model); + x = stick->a->position.x; + y = stick->a->position.y; + dx = stick->b->position.x - x; + dy = stick->b->position.y - y; - /* Stick constraints. */ - for (i = 0; i < model->num_sticks; i++) { - x = model->sticks[i].a->position.x; - y = model->sticks[i].a->position.y; - dx = model->sticks[i].b->position.x - x; - dy = model->sticks[i].b->position.y - y; - distance = estimate_distance (dx, dy, model->sticks[i].length); - fraction = (distance - model->sticks[i].length) / distance / 2; - model->sticks[i].a->position.x = x + dx * fraction; - model->sticks[i].a->position.y = y + dy * fraction; - model->sticks[i].b->position.x = x + dx * (1 - fraction); - model->sticks[i].b->position.y = y + dy * (1 - fraction); - } + distance = estimate_distance (dx, dy, stick->length); - /* Offset constraints. */ - for (i = 0; i < model->num_offsets; i++) - model_constrain_offset (model, &model->offsets[i]); + fraction = (distance - stick->length) / distance / 2; + stick->a->position.x = x + dx * fraction; + stick->a->position.y = y + dy * fraction; + stick->b->position.x = x + dx * (1 - fraction); + stick->b->position.y = y + dy * (1 - fraction); +} - /* Polygon constraints. */ +static void +model_constrain (Model *model) +{ + list_for_each (&model->anchor_list, model_constrain_anchor, model); + list_for_each (&model->string_list, model_constrain_string, model); + list_for_each (&model->spacer_list, model_constrain_spacer, model); + list_for_each (&model->stick_list, model_constrain_stick, model); + list_for_each (&model->offset_list, model_constrain_offset, model); list_for_each (&model->polygon_list, model_constrain_polygon, model); } @@ -630,20 +664,35 @@ object_distance (Object *object, double x, double y) return sqrt (dx*dx + dy*dy); } +typedef struct { + double x; + double y; + double distance; + Object *object; +} FindNearestClosure; + +static void +model_update_closest (Object *object, void *data) +{ + FindNearestClosure *closure = data; + double distance; + + distance = object_distance (object, closure->x, closure->y); + if (closure->object == NULL || distance < closure->distance) { + closure->distance = distance; + closure->object = object; + } +} + Object * model_find_nearest (Model *model, double x, double y) { - Object *object; - double distance, min_distance; - int i; + FindNearestClosure closure; - for (i = 0; i < model->num_objects; i++) { - distance = object_distance (&model->objects[i], x, y); - if (i == 0 || distance < min_distance) { - min_distance = distance; - object = &model->objects[i]; - } - } + closure.x = x; + closure.y = y; + closure.object = NULL; + model_for_each_object (model, model_update_closest, &closure); - return object; + return closure.object; } @@ -53,17 +53,20 @@ struct _Object { struct _Stick { Object *a, *b; int length; + Link link; }; struct _String { Object *a, *b; int length; + Link link; }; struct _Offset { int num_objects; Object **objects; int dx, dy; + Link link; }; struct _Spring { @@ -100,9 +103,12 @@ struct _Polygon { struct _Model { List object_list; List spacer_list; + List string_list; + List stick_list; List spring_list; List anchor_list; List polygon_list; + List offset_list; int num_objects; Object *objects; @@ -129,8 +135,6 @@ struct _Model { double gravity; int constrain_iterations; - Anchor mouse_anchor; - double theta; }; @@ -160,6 +164,8 @@ void model_for_each_object (Model *model, ObjectFunc func, void *data); Spacer *model_add_spacer (Model *model, Object *a, Object *b, double length); Spring *model_add_spring (Model *model, Object *a, Object *b, double length); +Stick *model_add_stick (Model *model, Object *a, Object *b, double length); +String *model_add_string (Model *model, Object *a, Object *b, double length); Anchor *model_add_anchor (Model *model, Object *object, double x, double y); Polygon *model_add_polygon (Model *model, int enclosing, int num_points, ...); Polygon *model_add_enclosing_rectangle (Model *model, double x0, double y0, @@ -81,27 +81,18 @@ static void model_init_rope (Model *model) { const int num_objects = 20; - const int num_sticks = num_objects - 1; const int stick_length = 10; + Object *object, *prev; int i; - memset (model, 0, sizeof *model); - model->objects = g_new (Object, num_objects); - model->num_objects = num_objects; - model->sticks = g_new (Stick, num_sticks); - model->num_sticks = num_sticks; - + model_init (model); model_init_constants (model); model_init_polygons (model); - for (i = 0; i < num_objects; i++) { - object_init (&model->objects[i], 200, 40 + i * stick_length, 1); - - if (i + 1 < num_objects) { - model->sticks[i].a = &model->objects[i]; - model->sticks[i].b = &model->objects[i + 1]; - model->sticks[i].length = stick_length; - } + for (i = 0, prev = NULL; i < num_objects; i++, prev = object) { + object = model_add_object (model, 200, 40 + i * stick_length, 1, NULL); + if (prev != NULL) + model_add_stick (model, object, prev, stick_length); } } @@ -117,7 +108,7 @@ model_init_curtain (Model *model) double x, y; int i, j, index, stick_index; - memset (model, 0, sizeof *model); + model_init (model); model->objects = g_new (Object, num_objects); model->num_objects = num_objects; model->sticks = g_new (Stick, num_sticks); @@ -483,17 +474,12 @@ draw_polygons (cairo_t *cr, Model *model, Color *color) } static void -draw_objects (cairo_t *cr, Model *model, Color *color) +draw_object (Object *object, void *data) { - int i; + cairo_t *cr = data; - cairo_set_source_rgba (cr, color->red, color->green, color->blue, 0.4); - for (i = 0; i < model->num_objects; i++) { - cairo_arc (cr, model->objects[i].position.x, - model->objects[i].position.y, - 3, 0, 2*M_PI); - cairo_fill (cr); - } + cairo_arc (cr, object->position.x, object->position.y, 3, 0, 2 * M_PI); + cairo_fill (cr); } static Color blue = { 0, 0, 1 }; @@ -506,6 +492,7 @@ struct _Closure { GtkWidget *drawing_area; GtkWidget *fps_label; Model *model; + Anchor *mouse_anchor; int frame_count; int i; struct timeval start; @@ -527,7 +514,9 @@ draw_model (GtkWidget *widget, Model *model) draw_springs (cr, model, &black); draw_offsets (cr, model, &blue); draw_offset_springs (cr, model, &blue); - draw_objects (cr, model, &red); + + cairo_set_source_rgba (cr, 1, 0, 0, 0.4); + model_for_each_object (model, draw_object, cr); cairo_destroy (cr); } @@ -554,9 +543,9 @@ button_press_event (GtkWidget *widget, if (event->button != 1) return TRUE; - closure->model->mouse_anchor.x = event->x; - closure->model->mouse_anchor.y = event->y; - closure->model->mouse_anchor.object = + closure->mouse_anchor->x = event->x; + closure->mouse_anchor->y = event->y; + closure->mouse_anchor->object = model_find_nearest (closure->model, event->x, event->y); return TRUE; @@ -572,7 +561,7 @@ button_release_event (GtkWidget *widget, if ((event->state & GDK_BUTTON1_MASK) == 0) return TRUE; - closure->model->mouse_anchor.object = NULL; + closure->mouse_anchor->object = NULL; return TRUE; } @@ -587,9 +576,9 @@ motion_notify_event (GtkWidget *widget, GdkModifierType state; gdk_window_get_pointer (event->window, &x, &y, &state); - - closure->model->mouse_anchor.x = x + 0.5; - closure->model->mouse_anchor.y = y + 0.5; + + closure->mouse_anchor->x = x + 0.5; + closure->mouse_anchor->y = y + 0.5; return TRUE; } @@ -800,11 +789,12 @@ main (int argc, char *argv[]) model_init_rope (&model); create_window (&closure); closure.i = 0; - gtk_widget_show_all (gtk_widget_get_toplevel (closure.drawing_area)); closure.model = &model; + closure.mouse_anchor = model_add_anchor (&model, NULL, 0, 0); closure.frame_count = 0; gettimeofday (&closure.start, NULL); g_timeout_add (40, timeout_callback, &closure); + gtk_widget_show_all (gtk_widget_get_toplevel (closure.drawing_area)); gtk_main (); return 0; |