mouse-initiated window resizes

This commit is contained in:
Kevin Lange 2014-04-17 00:24:54 -07:00
parent b3410b4b4b
commit 0535ccd993
3 changed files with 98 additions and 16 deletions

View File

@ -327,11 +327,8 @@ static void set_thickness_thin(void * button, struct yutani_msg_window_mouse_eve
ttk_render();
}
static void resize_derp(void * button, struct yutani_msg_window_mouse_event * event) {
yutani_window_resize(yctx, wina, 600, 600);
yutani_msg_t * m = yutani_wait_for(yctx, YUTANI_MSG_RESIZE_OFFER);
struct yutani_msg_window_resize * wr = (void*)m->data;
yutani_window_resize_accept(yctx, wina, wr->width, wr->height);
static void resize_finish(int width, int height) {
yutani_window_resize_accept(yctx, wina, width, height);
reinit_graphics_yutani(ctx, wina);
((ttk_object *)close_button)->x = wina->width - 28;
ttk_render();
@ -339,6 +336,14 @@ static void resize_derp(void * button, struct yutani_msg_window_mouse_event * ev
yutani_flip(yctx, wina);
}
static void resize_button(void * button, struct yutani_msg_window_mouse_event * event) {
yutani_window_resize(yctx, wina, 600, 600);
yutani_msg_t * m = yutani_wait_for(yctx, YUTANI_MSG_RESIZE_OFFER);
struct yutani_msg_window_resize * wr = (void*)m->data;
resize_finish(wr->width, wr->height);
free(m);
}
void keep_drawing(struct yutani_msg_window_mouse_event * mouse) {
double thickness = thick ? 2.0 : 0.5;;
@ -439,17 +444,10 @@ int main (int argc, char ** argv) {
button_thin->fill_color = rgb(127,127,127);
button_thin->fore_color = rgb(255,255,255);
button_thin = ttk_button_new("*", resize_derp);
ttk_position((ttk_object *)button_thin, decor_left_width + 410, decor_top_height + 3, 20, 20);
button_thin->fill_color = rgb(127,127,127);
button_thin->fore_color = rgb(255,255,255);
#if 0
ttk_button * button_quit = ttk_button_new("X", quit_app);
ttk_position((ttk_object *)button_quit, width - 33, 12, 20, 20);
button_quit->fill_color = rgb(255,0,0);
button_quit->fore_color = rgb(255,255,255);
#endif
ttk_button * button_resize = ttk_button_new("*", resize_button);
ttk_position((ttk_object *)button_resize, decor_left_width + 410, decor_top_height + 3, 20, 20);
button_resize->fill_color = rgb(127,127,127);
button_resize->fore_color = rgb(255,255,255);
drawing_surface = ttk_raw_surface_new(width - 30, height - 70);
((ttk_object *)drawing_surface)->y = 60;
@ -497,6 +495,12 @@ int main (int argc, char ** argv) {
}
}
break;
case YUTANI_MSG_RESIZE_OFFER:
{
struct yutani_msg_window_resize * wr = (void*)m->data;
resize_finish(wr->width, wr->height);
}
break;
default:
break;
}

View File

@ -585,6 +585,37 @@ static int yutani_blit_window(yutani_globals_t * yg, yutani_server_window_t * wi
return 0;
}
static void draw_resizing_box(yutani_globals_t * yg) {
cairo_t * cr = yg->framebuffer_ctx;
cairo_save(cr);
int32_t t_x, t_y;
int32_t s_x, s_y;
int32_t r_x, r_y;
int32_t q_x, q_y;
window_to_device(yg->resizing_window, 0, 0, &t_x, &t_y);
window_to_device(yg->resizing_window, yg->resizing_w, yg->resizing_h, &s_x, &s_y);
window_to_device(yg->resizing_window, 0, yg->resizing_h, &r_x, &r_y);
window_to_device(yg->resizing_window, yg->resizing_w, 0, &q_x, &q_y);
cairo_set_line_width(cr, 2.0);
cairo_move_to(cr, t_x, t_y);
cairo_line_to(cr, q_x, q_y);
cairo_line_to(cr, s_x, s_y);
cairo_line_to(cr, r_x, r_y);
cairo_line_to(cr, t_x, t_y);
cairo_close_path(cr);
cairo_stroke_preserve(cr);
cairo_set_source_rgba(cr, 0.33, 0.55, 1.0, 0.5);
cairo_fill(cr);
cairo_set_source_rgba(cr, 0.0, 0.4, 1.0, 0.9);
cairo_stroke(cr);
cairo_restore(cr);
}
static void redraw_windows(yutani_globals_t * yg) {
/* Save the cairo contexts so we can apply clipping */
save_cairo_states(yg);
@ -634,6 +665,11 @@ static void redraw_windows(yutani_globals_t * yg) {
}
}
if (yg->resizing_window) {
/* Draw box */
draw_resizing_box(yg);
}
/*
* Draw the cursor.
* We may also want to draw other compositor elements, like effects, but those
@ -855,6 +891,26 @@ static void handle_mouse_event(yutani_globals_t * yg, struct yutani_msg_mouse_ev
make_top(yg, yg->mouse_window);
}
}
} else if ((me->event.buttons & YUTANI_MOUSE_BUTTON_MIDDLE) && (yg->kbd_state.k_alt)) {
set_focused_at(yg, yg->mouse_x / MOUSE_SCALE, yg->mouse_y / MOUSE_SCALE);
yg->mouse_window = get_focused(yg);
if (yg->mouse_window) {
if (yg->mouse_window->z == YUTANI_ZORDER_BOTTOM || yg->mouse_window->z == YUTANI_ZORDER_TOP) {
yg->mouse_state = YUTANI_MOUSE_STATE_NORMAL;
yg->mouse_window = NULL;
} else {
fprintf(stderr, "[yutani-server] resize starting for wid=%d\n", yg->mouse_window -> wid);
yg->mouse_state = YUTANI_MOUSE_STATE_RESIZING;
yg->mouse_init_x = yg->mouse_x;
yg->mouse_init_y = yg->mouse_y;
yg->mouse_win_x = yg->mouse_window->x;
yg->mouse_win_y = yg->mouse_window->y;
yg->resizing_window = yg->mouse_window;
yg->resizing_w = yg->mouse_window->width;
yg->resizing_h = yg->mouse_window->height;
make_top(yg, yg->mouse_window);
}
}
} else if ((me->event.buttons & YUTANI_MOUSE_BUTTON_LEFT) && (!yg->kbd_state.k_alt)) {
yg->mouse_state = YUTANI_MOUSE_STATE_DRAGGING;
set_focused_at(yg, yg->mouse_x / MOUSE_SCALE, yg->mouse_y / MOUSE_SCALE);
@ -916,7 +972,25 @@ static void handle_mouse_event(yutani_globals_t * yg, struct yutani_msg_mouse_ev
break;
case YUTANI_MOUSE_STATE_RESIZING:
{
int width_diff = (yg->mouse_x - yg->mouse_init_x) / MOUSE_SCALE;
int height_diff = (yg->mouse_y - yg->mouse_init_y) / MOUSE_SCALE;
mark_window_relative(yg, yg->mouse_window, -2, -2, yg->resizing_w + 10, yg->resizing_h + 10);
yg->resizing_w = yg->resizing_window->width + width_diff;
yg->resizing_h = yg->resizing_window->height + height_diff;
mark_window_relative(yg, yg->mouse_window, -2, -2, yg->resizing_w + 10, yg->resizing_h + 10);
if (!(me->event.buttons & YUTANI_MOUSE_BUTTON_MIDDLE)) {
fprintf(stderr, "[yutani-server] resize complete, now %d x %d\n", yg->resizing_w, yg->resizing_h);
yutani_msg_t * response = yutani_msg_build_window_resize(YUTANI_MSG_RESIZE_OFFER, yg->resizing_window->wid, yg->resizing_w, yg->resizing_h, 0);
pex_send(yg->server, yg->resizing_window->owner, response->size, (char *)response);
free(response);
yg->resizing_window = NULL;
yg->mouse_window = NULL;
yg->mouse_state = YUTANI_MOUSE_STATE_NORMAL;
}
}
break;
default:

View File

@ -95,6 +95,10 @@ typedef struct {
key_event_state_t kbd_state;
yutani_server_window_t * resizing_window;
int32_t resizing_w;
int32_t resizing_h;
} yutani_globals_t;