diff options
author | Kristian Høgsberg <krh@redhat.com> | 2006-07-07 03:27:45 -0400 |
---|---|---|
committer | Kristian Høgsberg <krh@redhat.com> | 2006-07-07 03:27:45 -0400 |
commit | f7258dd26ef90de18bfc1b36ea4559342bb600eb (patch) | |
tree | 5414c28d8193f2c6dc3830ea993ebb5ebfe58dc7 | |
parent | aaa214d0b0e3f00a3d6a6a305b0525a0b91e8191 (diff) |
Make akamaru anchor and polygon lists dynamic.
-rw-r--r-- | akamaru.c | 80 | ||||
-rw-r--r-- | akamaru.h | 11 | ||||
-rw-r--r-- | dock.c | 138 |
3 files changed, 140 insertions, 89 deletions
@@ -157,17 +157,30 @@ anchor_init (Anchor *anchor, Object *object, double x, double y) anchor->y = y; } +Anchor * +model_add_anchor (Model *model, Object *object, double x, double y) +{ + Anchor *anchor; + + anchor = g_new (Anchor, 1); + anchor->object = object; + anchor->x = x; + anchor->y = y; + list_append (&model->anchor_list, anchor); + + return anchor; +} + void -polygon_init (Polygon *p, int enclosing, int num_points, ...) +polygon_init_from_va_list (Polygon *p, int enclosing, + int num_points, va_list ap) { double dx, dy, length; int i, j; - va_list ap; /* Polygons are defined counter-clock-wise in a coordinate system * with the y-axis pointing down. */ - va_start (ap, num_points); p->num_points = num_points; p->points = g_new (Point, num_points); p->enclosing = enclosing; @@ -176,8 +189,7 @@ polygon_init (Polygon *p, int enclosing, int num_points, ...) p->points[i].x = va_arg (ap, double); p->points[i].y = va_arg (ap, double); } - va_end (ap); - + p->normals = g_new (Vector, p->num_points); /* Compute outward pointing normals. p->normals[i] is the normal * for the edged between p->points[i] and p->points[i + 1]. */ @@ -192,6 +204,31 @@ polygon_init (Polygon *p, int enclosing, int num_points, ...) } void +polygon_init (Polygon *polygon, int enclosing, int num_points, ...) +{ + va_list ap; + + va_start (ap, num_points); + polygon_init_from_va_list (polygon, enclosing, num_points, ap); + va_end (ap); +} + +Polygon * +model_add_polygon (Model *model, int enclosing, int num_points, ...) +{ + Polygon *polygon; + va_list ap; + + polygon = g_new0 (Polygon, 1); + va_start (ap, num_points); + polygon_init_from_va_list (polygon, enclosing, num_points, ap); + va_end (ap); + list_append (&model->polygon_list, polygon); + + return polygon; +} + +void polygon_init_diamond (Polygon *polygon, double x, double y) { return polygon_init (polygon, FALSE, 5, @@ -216,6 +253,13 @@ polygon_init_enclosing_rectangle (Polygon *polygon, double x0, double y0, return polygon_init (polygon, TRUE, 4, x0, y0, x0, y1, x1, y1, x1, y0); } +Polygon * +model_add_enclosing_rectangle (Model *model, double x0, double y0, + double x1, double y1) +{ + return model_add_polygon (model, TRUE, 4, x0, y0, x0, y1, x1, y1, x1, y0); +} + void model_init (Model *model) { @@ -223,6 +267,8 @@ 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->anchor_list, G_STRUCT_OFFSET (Anchor, link)); + list_init (&model->polygon_list, G_STRUCT_OFFSET (Polygon, link)); } Object * @@ -443,19 +489,23 @@ object_constrain_polygon (Object *object, void *data) } static void -model_constrain_polygon (Model *model, Polygon *polygon) +model_constrain_polygon (void *element, void *data) { ObjectConstrainPolygonClosure closure; + closure.polygon = element; + closure.model = data; - closure.model = model; - closure.polygon = polygon; - - model_for_each_object (model, object_constrain_polygon, &closure); + model_for_each_object (closure.model, object_constrain_polygon, &closure); } static void -model_constrain_anchor (Model *model, Anchor *anchor) +model_constrain_anchor (void *element, void *data) { + Anchor *anchor = element; + + if (anchor->object == NULL) + return; + anchor->object->position.x = anchor->x; anchor->object->position.y = anchor->y; anchor->object->previous_position.x = anchor->x; @@ -513,10 +563,7 @@ model_constrain (Model *model) double dx, dy, x, y, distance, fraction; int i; - if (model->mouse_anchor.object != NULL) - model_constrain_anchor (model, &model->mouse_anchor); - for (i = 0; i < model->num_anchors; i++) - model_constrain_anchor (model, &model->anchors[i]); + list_for_each (&model->anchor_list, model_constrain_anchor, model); /* String constraints. */ for (i = 0; i < model->num_strings; i++) { @@ -556,8 +603,7 @@ model_constrain (Model *model) model_constrain_offset (model, &model->offsets[i]); /* Polygon constraints. */ - for (i = 0; i < model->num_polygons; i++) - model_constrain_polygon (model, &model->polygons[i]); + list_for_each (&model->polygon_list, model_constrain_polygon, model); } void @@ -1,3 +1,6 @@ +/* -*- mode: c; c-basic-offset: 2 -*- + */ + #ifndef __AKAMARU_H__ #define __AKAMARU_H__ @@ -83,6 +86,7 @@ struct _Spacer { struct _Anchor { Object *object; double x, y; + Link link; }; struct _Polygon { @@ -90,12 +94,15 @@ struct _Polygon { Point *points; Vector *normals; int enclosing; + Link link; }; struct _Model { List object_list; List spacer_list; List spring_list; + List anchor_list; + List polygon_list; int num_objects; Object *objects; @@ -153,6 +160,10 @@ 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); +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, + double x1, double y1); void model_step (Model *model, double delta_t); @@ -41,6 +41,9 @@ struct _KibaDock GtkWidget widget; Model model; + Anchor *anchor; + Anchor *mouse_anchor; + int width; int height; int spacing; @@ -51,7 +54,7 @@ struct _KibaDock int drag_distance; KibaLauncher *dragging_launcher; - GConfClient *gconf_client; + GConfClient *gconf_client; Object *object; }; @@ -104,10 +107,9 @@ static void kiba_dock_drag_data_received (GtkWidget *widget, guint info, guint time); -static void kiba_dock_init_model (Model *model, - int num_items, - int width, int height, - int spacing); +static void kiba_dock_init_model (KibaDock *dock, + int width, + int height); static KibaLauncher *kiba_launcher_new (KibaDock *dock, Object *object, const char *gconf_path); @@ -140,7 +142,6 @@ static void kiba_dock_init (KibaDock *dock) { GSList *launchers, *l; - int num_launchers; GError *error = NULL; GdkScreen *screen; int width, height, i; @@ -162,38 +163,37 @@ kiba_dock_init (KibaDock *dock) launchers = gconf_client_all_dirs (dock->gconf_client, KIBA_GCONF_PATH "/launchers", &error); - if (error != NULL) { - printf ("error getting launchers: %s\n", error->message); - g_free (error->message); - } - - num_launchers = g_slist_length (launchers); + if (error != NULL) + { + printf ("error getting launchers: %s\n", error->message); + g_free (error->message); + } screen = gdk_screen_get_default (); width = gdk_screen_get_width (screen); height = gdk_screen_get_height (screen); dock->spacing = 50; - dock->num_launchers = num_launchers; - - kiba_dock_init_model (&dock->model, num_launchers, - width, height, dock->spacing); - for (l = launchers, i = 0; l != NULL; l = l->next, i++) { - char *path = l->data; - launcher = kiba_launcher_new (dock, &dock->model.objects[i + 1], path); - if (launcher == NULL) - continue; + kiba_dock_init_model (dock, width, height); - kiba_dock_add_launcher (dock, launcher, - g_random_int_range (0, width), - g_random_int_range (0, height)); - } + dock->num_launchers = g_slist_length (launchers); + for (l = launchers, i = 0; l != NULL; l = l->next, i++) + { + char *path = l->data; + launcher = kiba_launcher_new (dock, &dock->model.objects[i + 1], path); + if (launcher == NULL) + continue; + + kiba_dock_add_launcher (dock, launcher, + g_random_int_range (0, width), + g_random_int_range (0, height)); + } - gtk_drag_dest_set(GTK_WIDGET (dock), - GTK_DEST_DEFAULT_ALL, - targets, G_N_ELEMENTS (targets), - GDK_ACTION_MOVE | GDK_ACTION_COPY); + gtk_drag_dest_set (GTK_WIDGET (dock), + GTK_DEST_DEFAULT_ALL, + targets, G_N_ELEMENTS (targets), + GDK_ACTION_MOVE | GDK_ACTION_COPY); gtk_drag_dest_add_uri_targets (GTK_WIDGET (dock)); g_timeout_add (20, timeout_callback, dock); @@ -411,7 +411,7 @@ add_spacer (Object *object, void *data) KibaDock *dock = data; /* Skip the anchor object. */ - if (object->data == NULL && object != dock->object) + if (object != dock->anchor->object && object != dock->object) model_add_spacer (&dock->model, dock->object, object, dock->spacing); } @@ -421,7 +421,7 @@ kiba_dock_add_launcher (KibaDock *dock, KibaLauncher *launcher, int x, int y) Object *object; object = model_add_object (&dock->model, x, y, 12, NULL); - model_add_spring (&dock->model, dock->model.anchors[0].object, object, 0); + model_add_spring (&dock->model, dock->anchor->object, object, 0); dock->object = object; model_for_each_object (&dock->model, add_spacer, dock); dock->launchers = g_list_prepend (dock->launchers, launcher); @@ -431,38 +431,26 @@ kiba_dock_add_launcher (KibaDock *dock, KibaLauncher *launcher, int x, int y) } static void -kiba_dock_init_model (Model *model, int num_items, - int width, int height, int spacing) +kiba_dock_init_model (KibaDock *dock, int width, int height) { - int left_edge; - - model_init (model); - model->anchors = g_new (Anchor, 1); - model->num_anchors = 1; - - model->elasticity = 0.9; - model->friction = 150; - model->gravity = 50; - model->k = 0.8; - model->constrain_iterations = 1; - - model->polygons = g_new (Polygon, 3); - model->num_polygons = 3; - left_edge = (width - (num_items - 1) * spacing) / 2; - polygon_init_enclosing_rectangle (&model->polygons[0], - 0, 0, width - 50, height - 50); - polygon_init_rectangle (&model->polygons[1], - 0, height - 70, left_edge, height); - polygon_init_rectangle (&model->polygons[2], - width - left_edge + 2, height - 70, - width, height); - - model->anchors[0].x = width / 2; - model->anchors[0].y = height - 50; - /* Set object data to something non-NULL so we can recognize the anchor. */ - model->anchors[0].object = model_add_object (model, - width / 2, height - 50, 0, - model); + Object *object; + + model_init (&dock->model); + + dock->model.elasticity = 0.9; + dock->model.friction = 150; + dock->model.gravity = 50; + dock->model.k = 0.8; + dock->model.constrain_iterations = 1; + + model_add_enclosing_rectangle (&dock->model, 0, 0, width - 50, height - 50); + + object = model_add_object (&dock->model, width / 2, height - 50, 0, NULL); + + dock->anchor = + model_add_anchor (&dock->model, object, width / 2, height - 50); + + dock->mouse_anchor = model_add_anchor (&dock->model, NULL, 0, 0); } static gboolean @@ -480,10 +468,10 @@ kiba_dock_button_press_event (GtkWidget *widget, if (launcher == NULL) return FALSE; - dock->dragging_launcher = launcher; - dock->model.mouse_anchor.x = launcher->object->position.x; - dock->model.mouse_anchor.y = launcher->object->position.y; - dock->model.mouse_anchor.object = launcher->object; + dock->dragging_launcher = launcher; + dock->mouse_anchor->x = launcher->object->position.x; + dock->mouse_anchor->y = launcher->object->position.y; + dock->mouse_anchor->object = launcher->object; return TRUE; } @@ -499,6 +487,7 @@ kiba_launcher_exec (gpointer data) launcher->object->previous_position.y += g_random_double_range (5, 10); /* FIXME: Support drag and drop on launchers with %U and %F */ + /* FIXME: Use g_shell_quote or split or whatever it was... */ argv = g_strsplit (launcher->exec, " ", 0); g_spawn_async (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error); @@ -531,8 +520,8 @@ kiba_dock_button_release_event (GtkWidget *widget, if (dock->dragging_launcher && dock->drag_distance <= 1) g_idle_add (kiba_launcher_exec, dock->dragging_launcher); - dock->dragging_launcher = NULL; - dock->model.mouse_anchor.object = NULL; + dock->dragging_launcher = NULL; + dock->mouse_anchor->object = NULL; return TRUE; } @@ -544,15 +533,20 @@ kiba_dock_motion_notify_event (GtkWidget *widget, KibaDock *dock = KIBA_DOCK (widget); GdkModifierType state; int x, y, new_x, new_y, dx, dy; + GdkScreen *screen; + int screen_height; + + screen = gdk_screen_get_default (); + screen_height = gdk_screen_get_height (screen); gdk_window_get_pointer (gdk_get_default_root_window(), &x, &y, &state); new_x = x - dock->drag_offset_x; new_y = y - dock->drag_offset_y; - dx = new_x - dock->model.mouse_anchor.x; - dy = new_y - dock->model.mouse_anchor.y; + dx = new_x - dock->mouse_anchor->x; + dy = new_y - dock->mouse_anchor->y; - dock->model.mouse_anchor.x = new_x; - dock->model.mouse_anchor.y = new_y; + dock->mouse_anchor->x = new_x; + dock->mouse_anchor->y = MIN (new_y, screen_height - 50); dock->drag_distance += sqrt (dx * dx + dy * dy); return TRUE; |