X-Git-Url: https://git.cworth.org/git?p=akamaru;a=blobdiff_plain;f=dock.c;h=c90c3d9b10dba63bad951510028f148269e7ba83;hp=37707a98fcb243eb81014b40af25ab76ff4622a6;hb=HEAD;hpb=b70eba22906b666c8038c1d10bc0663489622fe0 diff --git a/dock.c b/dock.c index 37707a9..c90c3d9 100644 --- a/dock.c +++ b/dock.c @@ -1,4 +1,4 @@ -/* -*- mode: c; c-basic-offset: 2 -*- +/* -*- mode: c; c-basic-offset: 8 -*- */ #include @@ -16,212 +16,220 @@ typedef struct Closure Closure; struct Closure { - Model model; - int num_icons; - GdkWindow **windows; - int drag_offset_x, drag_offset_y; - int anchor_x, anchor_y; - int spacing; + Model model; + int num_icons; + GdkWindow **windows; + int drag_offset_x, drag_offset_y; + int spacing; + int height; }; static gint timeout_callback (gpointer data) { - Closure *closure = data; - int i; + Closure *closure = data; + int i; - for (i = 0; i < closure->num_icons; i++) { - gdk_window_move (closure->windows[i], - closure->model.objects[i + 1].position.x, - closure->model.objects[i + 1].position.y); - } + for (i = 0; i < closure->num_icons; i++) { + gdk_window_move (closure->windows[i], + closure->model.objects[i + 1].position.x + 0.5, + closure->model.objects[i + 1].position.y + 0.5); + } - model_step (&closure->model, 0.1); + for (i = 0; i < 4; i++) + model_step (&closure->model, 0.03); - return TRUE; + return TRUE; } static GdkWindow * create_window (GdkScreen *screen, int x, int y, int width, int height) { - GdkWindowAttr attributes; - gint attributes_mask; - - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gdk_screen_get_rgba_visual (screen); - attributes.colormap = gdk_screen_get_rgba_colormap (screen); - attributes.window_type = GDK_WINDOW_TEMP; - - attributes.x = x; - attributes.y = y; - attributes.width = width; - attributes.height = height; - attributes.event_mask = - GDK_EXPOSURE_MASK | - GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | - GDK_ENTER_NOTIFY_MASK | - GDK_LEAVE_NOTIFY_MASK | - GDK_POINTER_MOTION_MASK | - GDK_POINTER_MOTION_HINT_MASK; - - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; + GdkWindowAttr attributes; + gint attributes_mask; + + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.visual = gdk_screen_get_rgba_visual (screen); + attributes.colormap = gdk_screen_get_rgba_colormap (screen); + attributes.window_type = GDK_WINDOW_TEMP; + + attributes.x = x; + attributes.y = y; + attributes.width = width; + attributes.height = height; + attributes.event_mask = + GDK_EXPOSURE_MASK | + GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_ENTER_NOTIFY_MASK | + GDK_LEAVE_NOTIFY_MASK | + GDK_POINTER_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK; + + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; - return gdk_window_new (gdk_screen_get_root_window (screen), - &attributes, attributes_mask); + return gdk_window_new (gdk_screen_get_root_window (screen), + &attributes, attributes_mask); } static void -model_init_dock (Model *model, int num_items, int x, int y, int spacing) +model_init_dock (Model *model, int num_items, + int width, int height, int spacing) { - const int num_objects = num_items + 1; - const int num_spacers = (num_objects - 1) * (num_objects - 2) / 2; - const int num_springs = num_objects - 1; - int i, j; - Object *object; - Spring *spring; - Spacer *spacer; - - memset (model, 0, sizeof *model); - model->objects = g_new (Object, num_objects); - model->num_objects = num_objects; - model->springs = g_new (Spring, num_springs); - model->num_springs = num_springs; - model->spacers = g_new (Spacer, num_spacers); - model->num_spacers = num_spacers; - model->anchors = g_new (Anchor, 1); - model->num_anchors = 1; - model->k = 0.1; - - model->polygons = g_new (Polygon, 1); - model->num_polygons = 1; - polygon_init_enclosing_rectangle (&model->polygons[0], 0, 0, 1024 - 50, y); - - model->anchors[0].x = x; - model->anchors[0].y = y; - model->anchors[0].object = &model->objects[0]; - - object_init (&model->objects[0], x, y, 20); - - object = &model->objects[1]; - spring = model->springs; - spacer = model->spacers; - - for (i = 1; i < num_objects; i++, object++) { - object_init (&model->objects[i], 200 + i * spacing / 2, 300, 3); - spring_init (spring++, &model->objects[0], object, spacing); - for (j = 1; j < num_objects - i; j++) { - spacer_init (spacer++, object, object + j, spacing); - } - } + const int num_objects = num_items + 1; + const int num_spacers = (num_objects - 1) * (num_objects - 2) / 2; + const int num_springs = num_objects - 1; + const int spread = spacing + 20; + int i, j, left_edge; + Object *object; + Spring *spring; + Spacer *spacer; + + memset (model, 0, sizeof *model); + model->objects = g_new (Object, num_objects); + model->num_objects = num_objects; + model->springs = g_new (Spring, num_springs); + model->num_springs = num_springs; + model->spacers = g_new (Spacer, num_spacers); + model->num_spacers = num_spacers; + model->anchors = g_new (Anchor, 1); + model->num_anchors = 1; + model->k = 0.1; + + model->polygons = g_new (Polygon, 1); + model->num_polygons = 1; + polygon_init_enclosing_rectangle (&model->polygons[0], + 0, 0, width - 50, height - 50); + + model->anchors[0].x = width / 2; + model->anchors[0].y = height - 50; + model->anchors[0].object = &model->objects[0]; + + object_init (&model->objects[0], + model->anchors[0].x, model->anchors[0].y, 0); + + object = &model->objects[1]; + spring = model->springs; + spacer = model->spacers; + left_edge = (width - (num_items - 1) * spread) / 2; + + for (i = 1; i < num_objects; i++, object++) { + object_init (&model->objects[i], + left_edge + (i - 1) * spread, height - 100, 1); + spring_init (spring++, &model->objects[0], object, spacing); + for (j = 1; j < num_objects - i; j++) { + spacer_init (spacer++, object, object + j, spacing); + } + } } static GdkFilterReturn window_event (GdkXEvent *xevent, GdkEvent *event, gpointer data) { - Closure *closure = data; - GdkModifierType state; - XEvent *ev = (XEvent *) xevent; - int x, y, i; - Object *object; - - switch (ev->type) { - case ButtonPress: - closure->drag_offset_x = ev->xbutton.x; - closure->drag_offset_y = ev->xbutton.y; - for (i = 0; i < closure->num_icons; i++) { - if (closure->windows[i] == event->any.window) { - object = &closure->model.objects[i + 1]; - closure->model.mouse_anchor.x = object->position.x; - closure->model.mouse_anchor.y = object->position.y; - closure->model.mouse_anchor.object = object; - } - } - break; - - case ButtonRelease: - closure->model.mouse_anchor.object = NULL; - break; - - case MotionNotify: - gdk_window_get_pointer (gdk_get_default_root_window(), &x, &y, &state); - closure->model.mouse_anchor.x = x + 0.5 - closure->drag_offset_x; - closure->model.mouse_anchor.y = y + 0.5 - closure->drag_offset_y; - if (closure->model.mouse_anchor.y > closure->anchor_y) - closure->model.mouse_anchor.y = closure->anchor_y; - break; - - default: - break; - } - - return GDK_FILTER_CONTINUE; + Closure *closure = data; + GdkModifierType state; + XEvent *ev = (XEvent *) xevent; + int x, y, i; + Object *object; + + switch (ev->type) { + case ButtonPress: + closure->drag_offset_x = ev->xbutton.x; + closure->drag_offset_y = ev->xbutton.y; + for (i = 0; i < closure->num_icons; i++) { + if (closure->windows[i] == event->any.window) { + object = &closure->model.objects[i + 1]; + closure->model.mouse_anchor.x = object->position.x; + closure->model.mouse_anchor.y = object->position.y; + closure->model.mouse_anchor.object = object; + } + } + break; + + case ButtonRelease: + closure->model.mouse_anchor.object = NULL; + break; + + case MotionNotify: + gdk_window_get_pointer (gdk_get_default_root_window(), &x, &y, &state); + closure->model.mouse_anchor.x = x - closure->drag_offset_x; + closure->model.mouse_anchor.y = y - closure->drag_offset_y; + if (closure->model.mouse_anchor.y > closure->height) + closure->model.mouse_anchor.y = closure->height; + break; + + default: + break; + } + + return GDK_FILTER_CONTINUE; } static const char *icons[] = { - "svg/applications-office.svg", - "svg/camera-video.svg", - "svg/email.svg", - "svg/firefox-logo.svg", - "svg/gnome-dev-disc-dvdrom.svg", - "svg/gnome-terminal.svg", - "svg/help-browser.svg", - "svg/internet-group-chat.svg" + "svg/applications-office.svg", + "svg/camera-video.svg", + "svg/email.svg", + "svg/firefox-logo.svg", + "svg/gnome-dev-disc-dvdrom.svg", + "svg/gnome-terminal.svg", + "svg/help-browser.svg", + "svg/internet-group-chat.svg" }; int main (int argc, char *argv[]) { - Closure closure; - GdkScreen *screen; - const int num_icons = G_N_ELEMENTS (icons); - int x, y, width, height, i; - RsvgHandle *handle; - RsvgDimensionData dimension; - cairo_t *cr; - const int screen_width = 1024, screen_height = 768, spacing = 50; + Closure closure; + GdkScreen *screen; + const int num_icons = G_N_ELEMENTS (icons); + int x, y, width, height, i; + RsvgHandle *handle; + RsvgDimensionData dimension; + cairo_t *cr; + const int spacing = 50; - gtk_init (&argc, &argv); + gtk_init (&argc, &argv); - rsvg_init (); + rsvg_init (); - screen = gdk_screen_get_default (); + screen = gdk_screen_get_default (); + width = gdk_screen_get_width (screen); + height = gdk_screen_get_height (screen); - closure.anchor_x = screen_width / 2; - closure.anchor_y = screen_height - 50; - closure.spacing = spacing; - closure.num_icons = num_icons; - closure.windows = g_new (GdkWindow *, num_icons); - for (i = 0; i < num_icons; i++) { + closure.spacing = spacing; + closure.height = height - 50; + closure.num_icons = num_icons; + closure.windows = g_new (GdkWindow *, num_icons); - handle = rsvg_handle_new_from_file (icons[i], NULL); - rsvg_handle_get_dimensions (handle, &dimension); + model_init_dock (&closure.model, num_icons, width, height, spacing); - x = (screen_width - spacing * num_icons) / 2 + i * spacing; - y = closure.anchor_y; - width = dimension.width; - height = dimension.height; - closure.windows[i] = create_window (screen, x, y, width, height); + for (i = 0; i < num_icons; i++) { - gdk_window_show (closure.windows[i]); + handle = rsvg_handle_new_from_file (icons[i], NULL); + rsvg_handle_get_dimensions (handle, &dimension); - cr = gdk_cairo_create (closure.windows[i]); - cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); - cairo_paint (cr); - cairo_set_operator (cr, CAIRO_OPERATOR_OVER); - rsvg_handle_render_cairo (handle, cr); - rsvg_handle_free (handle); - cairo_destroy (cr); + x = closure.model.objects[i + 1].position.x; + y = closure.model.objects[i + 1].position.y; + closure.windows[i] = + create_window (screen, x, y, dimension.width, dimension.height); - gdk_window_add_filter (closure.windows[i], window_event, &closure); - } + gdk_window_show (closure.windows[i]); - model_init_dock (&closure.model, num_icons, - closure.anchor_x, closure.anchor_y, spacing); - g_timeout_add (20, timeout_callback, &closure); + cr = gdk_cairo_create (closure.windows[i]); + cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); + cairo_paint (cr); + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + rsvg_handle_render_cairo (handle, cr); + rsvg_handle_free (handle); + cairo_destroy (cr); - gtk_main (); + gdk_window_add_filter (closure.windows[i], window_event, &closure); + } - rsvg_term (); + g_timeout_add (20, timeout_callback, &closure); - return 0; + gtk_main (); + + rsvg_term (); + + return 0; }