summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2011-12-19 15:40:10 -0500
committerKristian Høgsberg <krh@bitplanet.net>2011-12-19 15:40:10 -0500
commitbbedd7e9d2e7409d3ca99a85eaf4bcc98957c425 (patch)
treefca45489f8afb0d06ef35f70bfc762c6a4db8cc8
parent8da0fbde12e2c1ce07ece6f8b2b9a5a9a9ca3ff4 (diff)
clients: Implement a toy-menu for testing the menu surface type
-rw-r--r--clients/resizor.c16
-rw-r--r--clients/window.c169
-rw-r--r--clients/window.h3
3 files changed, 155 insertions, 33 deletions
diff --git a/clients/resizor.c b/clients/resizor.c
index 87c7af3..a31e0d7 100644
--- a/clients/resizor.c
+++ b/clients/resizor.c
@@ -157,15 +157,17 @@ key_handler(struct window *window, struct input *input, uint32_t time,
static void
show_menu(struct resizor *resizor, struct input *input)
{
- int32_t x, y, width = 200, height = 200;
+ int32_t x, y;
+ static const char *entries[] = {
+ "Roy", "Pris", "Leon", "Zhora"
+ };
input_get_position(input, &x, &y);
- resizor->menu = window_create_transient(resizor->display,
- resizor->window,
- x - 10, y - 10, width, height);
+ resizor->menu = window_create_menu(resizor->display,
+ resizor->window,
+ x - 10, y - 10, entries, 4);
- window_draw(resizor->menu);
- window_flush(resizor->menu);
+ window_schedule_redraw(resizor->menu);
}
static void
@@ -179,8 +181,6 @@ button_handler(struct window *window,
case BTN_RIGHT:
if (state)
show_menu(resizor, input);
- else
- window_destroy(resizor->menu);
break;
}
}
diff --git a/clients/window.c b/clients/window.c
index d06d4aa..09e9b70 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -100,6 +100,7 @@ enum {
TYPE_TOPLEVEL,
TYPE_FULLSCREEN,
TYPE_TRANSIENT,
+ TYPE_MENU,
TYPE_CUSTOM
};
@@ -772,6 +773,8 @@ window_set_type(struct window *window)
window->parent->shell_surface,
window->x, window->y, 0);
break;
+ case TYPE_MENU:
+ break;
case TYPE_CUSTOM:
break;
}
@@ -930,28 +933,6 @@ window_create_surface(struct window *window)
}
static void
-window_draw_menu(struct window *window)
-{
- cairo_t *cr;
- int width, height, r = 5;
-
- window_create_surface(window);
-
- cr = cairo_create(window->cairo_surface);
- cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
- cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0);
- cairo_paint(cr);
-
- width = window->allocation.width;
- height = window->allocation.height;
- rounded_rect(cr, r, r, width - r, height - r, r);
- cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
- cairo_set_source_rgba(cr, 1.0, 1.0, 0.0, 0.5);
- cairo_fill(cr);
- cairo_destroy(cr);
-}
-
-static void
window_draw_decorations(struct window *window)
{
cairo_t *cr;
@@ -1090,9 +1071,7 @@ item_get_user_data(struct item *item)
void
window_draw(struct window *window)
{
- if (window->parent)
- window_draw_menu(window);
- else if (!window->decoration)
+ if (!window->decoration)
window_create_surface(window);
else
window_draw_decorations(window);
@@ -2041,6 +2020,146 @@ window_create_transient(struct display *display, struct window *parent,
return window;
}
+struct menu {
+ struct window *window;
+ const char **entries;
+ int current;
+ int count;
+};
+
+static int
+menu_set_item(struct window *window, struct menu *menu, int sy)
+{
+ int next;
+
+ next = (sy - 8) / 20;
+ if (menu->current != next) {
+ menu->current = next;
+ window_schedule_redraw(window);
+ }
+
+ return POINTER_LEFT_PTR;
+}
+
+static int
+menu_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)
+{
+ return menu_set_item(window, data, sy);
+}
+
+static int
+menu_enter_handler(struct window *window,
+ struct input *input, uint32_t time,
+ int32_t x, int32_t y, void *data)
+{
+ return menu_set_item(window, data, y);
+}
+
+static void
+menu_leave_handler(struct window *window,
+ struct input *input, uint32_t time, void *data)
+{
+ menu_set_item(window, data, -200);
+}
+
+static void
+menu_button_handler(struct window *window,
+ struct input *input, uint32_t time,
+ int button, int state, void *data)
+
+{
+ struct menu *menu = data;
+
+ /* Either relase after press-drag-release or click-motion-click. */
+ if (state == 0 && 0 <= menu->current && menu->current < menu->count)
+ window_destroy(window);
+}
+
+static void
+menu_redraw_handler(struct window *window, void *data)
+{
+ cairo_t *cr;
+ const int32_t r = 3, margin = 3;
+ struct menu *menu = data;
+ int32_t width, height, i;
+
+ width = 200;
+ height = menu->count * 20 + margin * 2;
+ window_set_child_size(window, width, height);
+ window_create_surface(window);
+
+ cr = cairo_create(window->cairo_surface);
+ cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0);
+ cairo_paint(cr);
+
+ width = window->allocation.width;
+ height = window->allocation.height;
+ rounded_rect(cr, 0, 0, width, height, r);
+ cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgba(cr, 0.0, 0.0, 0.4, 0.8);
+ cairo_fill(cr);
+
+ for (i = 0; i < menu->count; i++) {
+ if (i == menu->current) {
+ cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
+ cairo_rectangle(cr, margin, i * 20 + margin,
+ width - 2 * margin, 20);
+ cairo_fill(cr);
+ cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
+ cairo_move_to(cr, 10, i * 20 + 16);
+ cairo_show_text(cr, menu->entries[i]);
+ } else {
+ cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
+ cairo_move_to(cr, 10, i * 20 + 16);
+ cairo_show_text(cr, menu->entries[i]);
+ }
+ }
+
+ cairo_destroy(cr);
+ window_flush(window);
+}
+
+struct window *
+window_create_menu(struct display *display, struct window *parent,
+ int32_t x, int32_t y, const char **entries, int count)
+{
+ struct window *window;
+ struct menu *menu;
+
+ menu = malloc(sizeof *menu);
+ if (!menu)
+ return NULL;
+
+ window = window_create_internal(parent->display, parent, 0, 0);
+ if (!window)
+ return NULL;
+
+ menu->window = window;
+ menu->entries = entries;
+ menu->count = count;
+ window->decoration = 0;
+ window->type = TYPE_MENU;
+ window->x = x;
+ window->y = y;
+
+ wl_shell_surface_set_transient(window->shell_surface,
+ window->parent->shell_surface,
+ window->x, window->y, 0);
+
+ window_set_motion_handler(window, menu_motion_handler);
+ window_set_enter_handler(window, menu_enter_handler);
+ window_set_leave_handler(window, menu_leave_handler);
+ window_set_button_handler(window, menu_button_handler);
+ window_set_redraw_handler(window, menu_redraw_handler);
+ window_set_user_data(window, menu);
+
+ return window;
+}
+
void
window_set_buffer_type(struct window *window, enum window_buffer_type type)
{
diff --git a/clients/window.h b/clients/window.h
index e5dc008..59397f0 100644
--- a/clients/window.h
+++ b/clients/window.h
@@ -196,6 +196,9 @@ window_create(struct display *display, int32_t width, int32_t height);
struct window *
window_create_transient(struct display *display, struct window *parent,
int32_t x, int32_t y, int32_t width, int32_t height);
+struct window *
+window_create_menu(struct display *display, struct window *parent,
+ int32_t x, int32_t y, const char **entries, int count);
void
window_destroy(struct window *window);