From e28d05b0ad36242fac4512e29047e3dd8912de3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Tue, 20 Sep 2011 21:43:54 -0400 Subject: [PATCH] window.c: Move window items to window.c --- clients/desktop-shell.c | 163 +++++++++++----------------------------- clients/window.c | 124 +++++++++++++++++++++++++++++- clients/window.h | 34 ++++++++- 3 files changed, 197 insertions(+), 124 deletions(-) diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c index d7833e55..496d0d18 100644 --- a/clients/desktop-shell.c +++ b/clients/desktop-shell.c @@ -46,14 +46,12 @@ struct desktop { struct panel { struct window *window; - struct wl_list item_list; - struct panel_item *focus; }; struct panel_item { - struct wl_list link; + struct item *item; + struct panel *panel; cairo_surface_t *icon; - int x, y, width, height; int pressed; const char *path; }; @@ -88,41 +86,38 @@ panel_activate_item(struct panel *panel, struct panel_item *item) } } -static struct panel_item * -panel_find_item(struct panel *panel, int32_t x, int32_t y) -{ - struct panel_item *item; - - wl_list_for_each(item, &panel->item_list, link) { - if (item->x <= x && x < item->x + item->width && - item->y <= y && y < item->y + item->height) { - return item; - } - } - - return NULL; -} - static void -panel_draw_item(struct panel *panel, cairo_t *cr, struct panel_item *item) +panel_draw_item(struct item *item, void *data) { - int x, y; - - if (item->pressed) { - x = item->x + 1; - y = item->y + 1; - } else { - x = item->x; - y = item->y; + cairo_t *cr = data; + struct panel_item *pi; + int x, y, width, height; + double dx, dy; + + pi = item_get_user_data(item); + width = cairo_image_surface_get_width(pi->icon); + height = cairo_image_surface_get_height(pi->icon); + x = 0; + y = -height / 2; + if (pi->pressed) { + x++; + y++; } - cairo_set_source_surface(cr, item->icon, x, y); + dx = x; + dy = y; + cairo_user_to_device(cr, &dx, &dy); + item_set_allocation(item, dx, dy, width, height); + + cairo_set_source_surface(cr, pi->icon, x, y); cairo_paint(cr); - if (panel->focus == item) { + if (window_get_focus_item(pi->panel->window) == item) { cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.4); - cairo_mask_surface(cr, item->icon, x, y); + cairo_mask_surface(cr, pi->icon, x, y); } + + cairo_translate(cr, width + 10, 0); } static void @@ -130,8 +125,6 @@ panel_redraw_handler(struct window *window, void *data) { cairo_surface_t *surface; cairo_t *cr; - struct panel *panel = window_get_user_data(window); - struct panel_item *item; window_draw(window); surface = window_get_surface(window); @@ -141,8 +134,8 @@ panel_redraw_handler(struct window *window, void *data) cairo_paint(cr); cairo_set_operator(cr, CAIRO_OPERATOR_OVER); - wl_list_for_each(item, &panel->item_list, link) - panel_draw_item(panel, cr, item); + cairo_translate(cr, 10, 32 / 2); + window_for_each_item(window, panel_draw_item, cr); cairo_destroy(cr); cairo_surface_destroy(surface); @@ -150,54 +143,10 @@ panel_redraw_handler(struct window *window, void *data) } static void -panel_set_focus(struct panel *panel, struct panel_item *focus) +panel_item_focus_handler(struct window *window, + struct item *focus, void *data) { - if (focus == panel->focus) - return; - - panel->focus = focus; - window_schedule_redraw(panel->window); -} - -static int -panel_enter_handler(struct window *window, - struct input *input, uint32_t time, - int32_t x, int32_t y, void *data) -{ - struct panel *panel = data; - struct panel_item *item; - - item = panel_find_item(panel, x, y); - panel_set_focus(panel, item); - - return POINTER_LEFT_PTR; -} - -static void -panel_leave_handler(struct window *window, - struct input *input, uint32_t time, void *data) -{ - struct panel *panel = data; - - panel_set_focus(panel, NULL); -} - -static int -panel_motion_handler(struct window *window, - struct input *input, uint32_t time, - int32_t x, int32_t y, - int32_t sx, int32_t sy, void *data) -{ - struct panel *panel = data; - struct panel_item *item; - - if (panel->focus && panel->focus->pressed) - return POINTER_LEFT_PTR; - - item = panel_find_item(panel, sx, sy); - panel_set_focus(panel, item); - - return POINTER_LEFT_PTR; + window_schedule_redraw(window); } static void @@ -206,20 +155,15 @@ panel_button_handler(struct window *window, int button, int state, void *data) { struct panel *panel = data; - struct panel_item *item; - int32_t x, y; + struct panel_item *pi; + struct item *focus; - if (panel->focus && button == BTN_LEFT) { - panel->focus->pressed = state; + focus = window_get_focus_item(panel->window); + if (focus && button == BTN_LEFT) { + pi = item_get_user_data(focus); window_schedule_redraw(panel->window); - - if (state == 0) { - panel_activate_item(panel, panel->focus); - - input_get_position(input, &x, &y); - item = panel_find_item(panel, x, y); - panel_set_focus(panel, item); - } + if (state == 0) + panel_activate_item(panel, pi); } } @@ -230,7 +174,6 @@ panel_create(struct display *display) panel = malloc(sizeof *panel); memset(panel, 0, sizeof *panel); - wl_list_init(&panel->item_list); panel->window = window_create(display, 0, 0); @@ -239,10 +182,8 @@ panel_create(struct display *display) window_set_redraw_handler(panel->window, panel_redraw_handler); window_set_custom(panel->window); window_set_user_data(panel->window, panel); - window_set_enter_handler(panel->window, panel_enter_handler); - window_set_leave_handler(panel->window, panel_leave_handler); - window_set_motion_handler(panel->window, panel_motion_handler); window_set_button_handler(panel->window, panel_button_handler); + window_set_item_focus_handler(panel->window, panel_item_focus_handler); return panel; } @@ -256,27 +197,8 @@ panel_add_item(struct panel *panel, const char *icon, const char *path) memset(item, 0, sizeof *item); item->icon = cairo_image_surface_create_from_png(icon); item->path = strdup(path); - wl_list_insert(panel->item_list.prev, &item->link); - - item->width = cairo_image_surface_get_width(item->icon); - item->height = cairo_image_surface_get_height(item->icon); -} - -static void -panel_allocate(struct panel *panel, int width, int height) -{ - struct panel_item *item; - int x; - - window_set_child_size(panel->window, width, height); - window_schedule_redraw(panel->window); - - x = 10; - wl_list_for_each(item, &panel->item_list, link) { - item->x = x; - item->y = (height - item->height) / 2; - x += item->width + 10; - } + item->panel = panel; + window_add_item(panel->window, item); } static void @@ -324,7 +246,8 @@ desktop_shell_configure(void *data, struct desktop *desktop = data; if (surface == window_get_wl_surface(desktop->panel->window)) { - panel_allocate(desktop->panel, width, 32); + window_set_child_size(desktop->panel->window, width, 32); + window_schedule_redraw(desktop->panel->window); } else if (surface == window_get_wl_surface(desktop->background)) { background_draw(desktop->background, width, height, desktop->background_path); diff --git a/clients/window.c b/clients/window.c index e7a61ef9..9e92adb9 100644 --- a/clients/window.c +++ b/clients/window.c @@ -125,11 +125,22 @@ struct window { window_motion_handler_t motion_handler; window_enter_handler_t enter_handler; window_leave_handler_t leave_handler; + window_item_focus_handler_t item_focus_handler; + + struct wl_list item_list; + struct item *focus_item; + uint32_t item_grab_button; void *user_data; struct wl_list link; }; +struct item { + struct wl_list link; + struct rectangle allocation; + void *user_data; +}; + struct input { struct display *display; struct wl_input_device *input_device; @@ -949,6 +960,73 @@ window_destroy(struct window *window) free(window); } +static struct item * +window_find_item(struct window *window, int32_t x, int32_t y) +{ + struct item *item; + + wl_list_for_each(item, &window->item_list, link) { + if (item->allocation.x <= x && + x < item->allocation.x + item->allocation.width && + item->allocation.y <= y && + y < item->allocation.y + item->allocation.height) { + return item; + } + } + + return NULL; +} + +struct item * +window_add_item(struct window *window, void *data) +{ + struct item *item; + + item = malloc(sizeof *item); + memset(item, 0, sizeof *item); + item->user_data = data; + wl_list_insert(window->item_list.prev, &item->link); + + return item; +} + +void +window_for_each_item(struct window *window, item_func_t func, void *data) +{ + struct item *item; + + wl_list_for_each(item, &window->item_list, link) + func(item, data); +} + +struct item * +window_get_focus_item(struct window *window) +{ + return window->focus_item; +} + +void +item_get_allocation(struct item *item, struct rectangle *allocation) +{ + *allocation = item->allocation; +} + +void +item_set_allocation(struct item *item, + int32_t x, int32_t y, int32_t width, int32_t height) +{ + item->allocation.x = x; + item->allocation.y = y; + item->allocation.width = width; + item->allocation.height = height; +} + +void * +item_get_user_data(struct item *item) +{ + return item->user_data; +} + void display_flush_cairo_device(struct display *display) { @@ -1078,6 +1156,20 @@ set_pointer_image(struct input *input, uint32_t time, int pointer) pointer_images[pointer].hotspot_y); } +static void +window_set_focus_item(struct window *window, struct item *focus) +{ + void *data; + + if (focus == window->focus_item) + return; + + window->focus_item = focus; + data = focus ? focus->user_data : NULL; + if (window->item_focus_handler) + window->item_focus_handler(window, focus, data); +} + static void window_handle_motion(void *data, struct wl_input_device *input_device, uint32_t time, @@ -1085,6 +1177,7 @@ window_handle_motion(void *data, struct wl_input_device *input_device, { struct input *input = data; struct window *window = input->pointer_focus; + struct item *item; int pointer = POINTER_LEFT_PTR; input->x = x; @@ -1092,6 +1185,11 @@ window_handle_motion(void *data, struct wl_input_device *input_device, input->sx = sx; input->sy = sy; + if (!window->focus_item || !window->item_grab_button) { + item = window_find_item(window, sx, sy); + window_set_focus_item(window, item); + } + if (window->motion_handler) pointer = (*window->motion_handler)(window, input, time, x, y, sx, sy, @@ -1107,8 +1205,12 @@ window_handle_button(void *data, { struct input *input = data; struct window *window = input->pointer_focus; + struct item *item; int location; + if (window->focus_item && window->item_grab_button == 0 && state) + window->item_grab_button = button; + location = get_pointer_location(window, input->sx, input->sy); if (button == BTN_LEFT && state == 1) { @@ -1144,6 +1246,13 @@ window_handle_button(void *data, button, state, window->user_data); } + + if (window->focus_item && + window->item_grab_button == button && !state) { + window->item_grab_button = 0; + item = window_find_item(window, input->sx, input->sy); + window_set_focus_item(window, item); + } } static void @@ -1184,10 +1293,13 @@ window_handle_pointer_focus(void *data, { struct input *input = data; struct window *window; + struct item *item; int pointer; window = input->pointer_focus; if (window && window->surface != surface) { + window_set_focus_item(window, NULL); + if (window->leave_handler) window->leave_handler(window, input, time, window->user_data); @@ -1210,8 +1322,10 @@ window_handle_pointer_focus(void *data, time, sx, sy, window->user_data); - set_pointer_image(input, time, pointer); + item = window_find_item(window, x, y); + window_set_focus_item(window, item); + set_pointer_image(input, time, pointer); } } @@ -1503,6 +1617,13 @@ window_set_keyboard_focus_handler(struct window *window, window->keyboard_focus_handler = handler; } +void +window_set_item_focus_handler(struct window *window, + window_item_focus_handler_t handler) +{ + window->item_focus_handler = handler; +} + void window_set_transparent(struct window *window, int transparent) { @@ -1562,6 +1683,7 @@ window_create_internal(struct display *display, struct window *parent, window->margin = 16; window->decoration = 1; window->transparent = 1; + wl_list_init(&window->item_list); if (display->dpy) #ifdef HAVE_CAIRO_EGL diff --git a/clients/window.h b/clients/window.h index df819bf5..24091975 100644 --- a/clients/window.h +++ b/clients/window.h @@ -29,6 +29,9 @@ #include struct window; +struct item; +struct display; +struct input; struct task { void (*run)(struct task *task, uint32_t events); @@ -42,9 +45,6 @@ struct rectangle { int32_t height; }; -struct display; -struct input; - struct display * display_create(int *argc, char **argv[], const GOptionEntry *option_entries); @@ -156,6 +156,9 @@ typedef int (*window_motion_handler_t)(struct window *window, int32_t x, int32_t y, int32_t sx, int32_t sy, void *data); +typedef void (*window_item_focus_handler_t)(struct window *window, + struct item *focus, void *data); + struct window * window_create(struct display *display, int32_t width, int32_t height); struct window * @@ -165,6 +168,17 @@ window_create_transient(struct display *display, struct window *parent, void window_destroy(struct window *window); +struct item * +window_add_item(struct window *window, void *data); + +typedef void (*item_func_t)(struct item *item, void *data); + +void +window_for_each_item(struct window *window, item_func_t func, void *data); + +struct item * +window_get_focus_item(struct window *window); + void window_move(struct window *window, struct input *input, uint32_t time); @@ -264,6 +278,10 @@ void window_set_keyboard_focus_handler(struct window *window, window_keyboard_focus_handler_t handler); +void +window_set_item_focus_handler(struct window *window, + window_item_focus_handler_t handler); + void window_set_title(struct window *window, const char *title); @@ -277,6 +295,16 @@ void window_activate_drag(struct wl_drag *drag, struct window *window, struct input *input, uint32_t time); +void +item_get_allocation(struct item *item, struct rectangle *allocation); + +void +item_set_allocation(struct item *item, + int32_t x, int32_t y, int32_t width, int32_t height); + +void * +item_get_user_data(struct item *item); + void input_get_position(struct input *input, int32_t *x, int32_t *y);