summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2006-07-07 03:27:45 -0400
committerKristian Høgsberg <krh@redhat.com>2006-07-07 03:27:45 -0400
commitf7258dd26ef90de18bfc1b36ea4559342bb600eb (patch)
tree5414c28d8193f2c6dc3830ea993ebb5ebfe58dc7
parentaaa214d0b0e3f00a3d6a6a305b0525a0b91e8191 (diff)
Make akamaru anchor and polygon lists dynamic.
-rw-r--r--akamaru.c80
-rw-r--r--akamaru.h11
-rw-r--r--dock.c138
3 files changed, 140 insertions, 89 deletions
diff --git a/akamaru.c b/akamaru.c
index c75a110..836e2d9 100644
--- a/akamaru.c
+++ b/akamaru.c
@@ -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
diff --git a/akamaru.h b/akamaru.h
index 1e29f5e..af3f772 100644
--- a/akamaru.h
+++ b/akamaru.h
@@ -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);
diff --git a/dock.c b/dock.c
index e554c89..5182bc4 100644
--- a/dock.c
+++ b/dock.c
@@ -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;