[PATCH] Weston: window.c: Frame buttons
Martin Minarik
minarik11 at student.fiit.stuba.sk
Fri May 4 05:34:24 PDT 2012
Thanks for all the feedback.
We are adding frame buttons to wl_list, as suggested by vignatti.
---
clients/window.c | 254
+++++++++++++++++++++++++++++++++++++++++++++++++++++-
data/Makefile.am | 4 +
2 files changed, 255 insertions(+), 3 deletions(-)
diff --git a/clients/window.c b/clients/window.c
index 2dcf421..613050c 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -200,12 +200,38 @@ struct output {
void *user_data;
};
+enum framebutton_action {
+ FRAMEBUTTON_NULL = 0,
+ FRAMEBUTTON_ICON = 1,
+ FRAMEBUTTON_CLOSE = 2,
+ FRAMEBUTTON_MINIMIZE = 3,
+ FRAMEBUTTON_MAXIMIZE = 4,
+};
+
+enum framebutton_pointer {
+ FRAMEBUTTON_DEFAULT = 0,
+ FRAMEBUTTON_OVER = 1,
+ FRAMEBUTTON_ACTIVE = 2,
+};
+
+struct framebutton {
+ struct widget *widget;
+ struct frame *frame;
+ cairo_surface_t *icon;
+ enum framebutton_action type;
+ enum framebutton_pointer state;
+ struct wl_list link; /* buttons_list */
+ int position_left;
+ int border;
+};
+
struct frame {
struct widget *widget;
struct widget *child;
int margin;
int width;
int titlebar_height;
+ struct wl_list buttons_list;
};
struct menu {
@@ -980,6 +1006,8 @@ frame_resize_handler(struct widget *widget,
struct widget *child = frame->child;
struct rectangle allocation;
struct display *display = widget->window->display;
+ struct framebutton * button;
+ int x_l, x_r, y, w, h;
int decoration_width, decoration_height;
int opaque_margin;
@@ -1001,6 +1029,10 @@ frame_resize_handler(struct widget *widget,
height - 2 * frame->margin);
opaque_margin = frame->margin + display->frame_radius;
+
+ wl_list_for_each(button, &frame->buttons_list, link) {
+ button->widget->opaque=0;
+ }
} else {
decoration_width = 0;
decoration_height = 0;
@@ -1010,6 +1042,10 @@ frame_resize_handler(struct widget *widget,
allocation.width = width;
allocation.height = height;
opaque_margin = 0;
+
+ wl_list_for_each(button, &frame->buttons_list, link) {
+ button->widget->opaque=1;
+ }
}
widget_set_allocation(child, allocation.x, allocation.y,
@@ -1033,6 +1069,180 @@ frame_resize_handler(struct widget *widget,
widget->allocation.width - 2 * opaque_margin,
widget->allocation.height - 2 * opaque_margin);
}
+ /* frame internal buttons */
+ x_r = frame->widget->allocation.width - frame->width - frame->margin;
+ x_l = frame->width + frame->margin;
+ y = frame->width + frame->margin;
+ wl_list_for_each(button, &frame->buttons_list, link) {
+ w = cairo_image_surface_get_width(button->icon);
+ h = cairo_image_surface_get_height(button->icon);
+
+ if (button->border){w += 10;}
+
+ if (button->position_left){
+ widget_set_allocation(button->widget,
+ x_l, y , w + 1, h + 1);
+ x_l += w;
+ x_l += 4;
+ } else {
+ x_r -= w;
+ widget_set_allocation(button->widget,
+ x_r, y , w + 1, h + 1);
+ x_r -= 4;
+ }
+ }
+}
+
+static int
+framebutton_enter_handler(struct widget *widget,
+ struct input *input, uint32_t time,
+ int32_t x, int32_t y, void *data)
+{
+ struct framebutton *framebutton = data;
+ widget_schedule_redraw(framebutton->widget);
+ framebutton->state=FRAMEBUTTON_OVER;
+ return POINTER_LEFT_PTR;
+}
+
+static int
+framebutton_leave_handler(struct widget *widget, struct input *input,
void *data)
+{
+ struct framebutton *framebutton = data;
+ widget_schedule_redraw(framebutton->widget);
+ framebutton->state=FRAMEBUTTON_DEFAULT;
+ return POINTER_LEFT_PTR;
+}
+
+static void
+framebutton_button_handler(struct widget *widget,
+ struct input *input, uint32_t time,
+ int button, int state, void *data)
+
+{
+ struct framebutton *framebutton = data;
+ struct window *window = widget->window;
+
+ if (button != BTN_LEFT)
+ return;
+
+ switch (state){
+ case 1:
+ framebutton->state=FRAMEBUTTON_ACTIVE;
+ widget_schedule_redraw(framebutton->widget);
+ return;
+ break;
+ case 0:
+ framebutton->state=FRAMEBUTTON_DEFAULT;
+ widget_schedule_redraw(framebutton->widget);
+ break;
+ }
+
+ switch (framebutton->type){
+ case FRAMEBUTTON_ICON:
+ /* FIXME: window_show_frame_menu(window, input, time); */
+ break;
+ case FRAMEBUTTON_CLOSE:
+ if (window->close_handler)
+ window->close_handler(window->parent,
+ window->user_data);
+ else
+ display_exit(window->display);
+ break;
+ case FRAMEBUTTON_MINIMIZE:
+ fprintf(stderr,"Minimize stub\n");
+ return;
+ break;
+ case FRAMEBUTTON_MAXIMIZE:
+ window_set_maximized(window, window->type != TYPE_MAXIMIZED);
+ return;
+ break;
+ default: /* Unknown operation */ return; break;
+ }
+}
+
+static void
+framebutton_redraw_handler(struct widget *widget, void *data)
+{
+ struct framebutton *framebutton = data;
+ cairo_t *cr;
+ int width, height, x, y;
+ struct window *window = widget->window;
+
+ x = widget->allocation.x;
+ y = widget->allocation.y;
+ width = widget->allocation.width;
+ height = widget->allocation.height;
+
+ if (!width)
+ return;
+ if (!height)
+ return;
+ if (widget->opaque)
+ return;
+
+ assert(window!=NULL);
+ assert(window->cairo_surface!=NULL);
+
+ cr = cairo_create(window->cairo_surface);
+
+ if (framebutton->border){
+ cairo_set_line_width(cr, 1);
+
+ cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
+ cairo_rectangle (cr, x, y, 25, 16);
+
+ cairo_stroke_preserve(cr);
+ switch (framebutton->state){
+ case FRAMEBUTTON_DEFAULT:
+ cairo_set_source_rgb(cr, 0.88, 0.88, 0.88);
+ break;
+ case FRAMEBUTTON_OVER:
+ cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
+ break;
+ case FRAMEBUTTON_ACTIVE:
+ cairo_set_source_rgb(cr, 0.7, 0.7, 0.7);
+ break;
+ }
+ cairo_fill (cr);
+
+ x += 4;
+ }
+
+ cairo_set_source_surface(cr, framebutton->icon,
+ x, y);
+ cairo_paint(cr);
+
+ cairo_destroy(cr);
+}
+
+struct widget *
+framebutton_create(struct frame *frame, void *data)
+{
+ struct framebutton *framebutton;
+ const char *icon = data;
+
+ framebutton = malloc (sizeof *framebutton);
+ memset(framebutton, 0, sizeof *framebutton);
+
+ framebutton->icon = cairo_image_surface_create_from_png(icon);
+ framebutton->widget = widget_add_widget(frame->widget, framebutton);
+ framebutton->frame = frame;
+
+ wl_list_insert(frame->buttons_list.prev, &framebutton->link);
+
+ widget_set_redraw_handler(framebutton->widget, framebutton_redraw_handler);
+ widget_set_enter_handler(framebutton->widget, framebutton_enter_handler);
+ widget_set_leave_handler(framebutton->widget, framebutton_leave_handler);
+ widget_set_button_handler(framebutton->widget, framebutton_button_handler);
+ return framebutton->widget;
+}
+
+void
+framebutton_destroy(struct framebutton *framebutton)
+{
+ wl_list_remove(&framebutton->link);
+ free(framebutton);
+ return;
}
static void
@@ -1278,6 +1488,8 @@ struct widget *
frame_create(struct window *window, void *data)
{
struct frame *frame;
+ struct widget *fr_w;
+ struct framebutton *fr_b;
frame = malloc(sizeof *frame);
memset(frame, 0, sizeof *frame);
@@ -1285,15 +1497,46 @@ frame_create(struct window *window, void *data)
frame->widget = window_add_widget(window, frame);
frame->child = widget_add_widget(frame->widget, data);
frame->margin = 32;
- frame->width = 4;
- frame->titlebar_height = 30
-;
+ frame->width = 6;
+ frame->titlebar_height = 27;
+
widget_set_redraw_handler(frame->widget, frame_redraw_handler);
widget_set_resize_handler(frame->widget, frame_resize_handler);
widget_set_enter_handler(frame->widget, frame_enter_handler);
widget_set_motion_handler(frame->widget, frame_motion_handler);
widget_set_button_handler(frame->widget, frame_button_handler);
+ /* Create empty list for frame buttons */
+ wl_list_init(&frame->buttons_list);
+
+ /* Create icon */
+ fr_w = framebutton_create(frame, DATADIR "/weston/icon_window.png");
+ fr_b = fr_w->user_data;
+ fr_b->type = FRAMEBUTTON_ICON;
+ fr_b->position_left = 1;
+ fr_b->border = 0;
+
+ /* Create close button */
+ fr_w = framebutton_create(frame, DATADIR "/weston/sign_close.png");
+ fr_b = fr_w->user_data;
+ fr_b->type = FRAMEBUTTON_CLOSE;
+ fr_b->position_left = 0;
+ fr_b->border = 1;
+
+ /* Create maximize button */
+ fr_w = framebutton_create(frame, DATADIR "/weston/sign_maximize.png");
+ fr_b = fr_w->user_data;
+ fr_b->type = FRAMEBUTTON_MAXIMIZE;
+ fr_b->position_left = 0;
+ fr_b->border = 1;
+
+ /* Create minimize button */
+ fr_w = framebutton_create(frame, DATADIR "/weston/sign_minimize.png");
+ fr_b = fr_w->user_data;
+ fr_b->type = FRAMEBUTTON_MINIMIZE;
+ fr_b->position_left = 0;
+ fr_b->border = 1;
+
window->frame = frame;
return frame->child;
@@ -1302,6 +1545,11 @@ frame_create(struct window *window, void *data)
static void
frame_destroy(struct frame *frame)
{
+ struct framebutton* button;
+ wl_list_for_each(button, &frame->buttons_list, link) {
+ framebutton_destroy(button);
+ }
+
/* frame->child must be destroyed by the application */
widget_destroy(frame->widget);
free(frame);
diff --git a/data/Makefile.am b/data/Makefile.am
index ec2723a..a8441ef 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -3,6 +3,10 @@ westondatadir = $(datadir)/weston
dist_westondata_DATA = \
wayland.svg \
$(wayland_icon_png) \
+ icon_window.png \
+ sign_close.png \
+ sign_maximize.png \
+ sign_minimize.png \
pattern.png \
terminal.png \
border.png
--
1.7.5.4
-------------- next part --------------
A non-text attachment was scrubbed...
Name: data.zip
Type: application/force-download
Size: 1243 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20120504/41d0055c/attachment-0001.bin>
More information about the wayland-devel
mailing list