mirror of
https://github.com/libsdl-org/SDL.git
synced 2024-11-27 13:53:37 +08:00
Added SDL_HITTEST_RESIZE_*, and implemented for X11.
This commit is contained in:
parent
b861efde14
commit
2d38a71a1f
@ -800,7 +800,14 @@ typedef enum
|
||||
{
|
||||
SDL_HITTEST_NORMAL, /**< Region is normal. No special properties. */
|
||||
SDL_HITTEST_DRAGGABLE, /**< Region can drag entire window. */
|
||||
/* !!! FIXME: resize enums here. */
|
||||
SDL_HITTEST_RESIZE_TOPLEFT,
|
||||
SDL_HITTEST_RESIZE_TOP,
|
||||
SDL_HITTEST_RESIZE_TOPRIGHT,
|
||||
SDL_HITTEST_RESIZE_RIGHT,
|
||||
SDL_HITTEST_RESIZE_BOTTOMRIGHT,
|
||||
SDL_HITTEST_RESIZE_BOTTOM,
|
||||
SDL_HITTEST_RESIZE_BOTTOMLEFT,
|
||||
SDL_HITTEST_RESIZE_LEFT
|
||||
} SDL_HitTestResult;
|
||||
|
||||
/**
|
||||
|
@ -40,8 +40,40 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef _NET_WM_MOVERESIZE_SIZE_TOPLEFT
|
||||
#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
|
||||
#endif
|
||||
|
||||
#ifndef _NET_WM_MOVERESIZE_SIZE_TOP
|
||||
#define _NET_WM_MOVERESIZE_SIZE_TOP 1
|
||||
#endif
|
||||
|
||||
#ifndef _NET_WM_MOVERESIZE_SIZE_TOPRIGHT
|
||||
#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
|
||||
#endif
|
||||
|
||||
#ifndef _NET_WM_MOVERESIZE_SIZE_RIGHT
|
||||
#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
|
||||
#endif
|
||||
|
||||
#ifndef _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT
|
||||
#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
|
||||
#endif
|
||||
|
||||
#ifndef _NET_WM_MOVERESIZE_SIZE_BOTTOM
|
||||
#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
|
||||
#endif
|
||||
|
||||
#ifndef _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT
|
||||
#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
|
||||
#endif
|
||||
|
||||
#ifndef _NET_WM_MOVERESIZE_SIZE_LEFT
|
||||
#define _NET_WM_MOVERESIZE_SIZE_LEFT 7
|
||||
#endif
|
||||
|
||||
#ifndef _NET_WM_MOVERESIZE_MOVE
|
||||
#define _NET_WM_MOVERESIZE_MOVE 8
|
||||
#define _NET_WM_MOVERESIZE_MOVE 8
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
@ -290,7 +322,7 @@ InitiateWindowMove(_THIS, const SDL_WindowData *data, const SDL_Point *point)
|
||||
XEvent evt;
|
||||
evt.xclient.type = ClientMessage;
|
||||
evt.xclient.window = data->xwindow;
|
||||
evt.xclient.message_type = X11_XInternAtom(display, "_NET_WM_MOVERESIZE", False);
|
||||
evt.xclient.message_type = X11_XInternAtom(display, "_NET_WM_MOVERESIZE", True);
|
||||
evt.xclient.format = 32;
|
||||
evt.xclient.data.l[0] = window->x + point->x;
|
||||
evt.xclient.data.l[1] = window->y + point->y;
|
||||
@ -302,21 +334,96 @@ InitiateWindowMove(_THIS, const SDL_WindowData *data, const SDL_Point *point)
|
||||
X11_XSync(display, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
InitiateWindowResize(_THIS, const SDL_WindowData *data, const SDL_Point *point, int direction)
|
||||
{
|
||||
SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata;
|
||||
SDL_Window* window = data->window;
|
||||
Display *display = viddata->display;
|
||||
|
||||
if (direction < _NET_WM_MOVERESIZE_SIZE_TOPLEFT || direction > _NET_WM_MOVERESIZE_SIZE_LEFT)
|
||||
return;
|
||||
|
||||
/* !!! FIXME: we need to regrab this if necessary when the drag is done. */
|
||||
X11_XUngrabPointer(display, 0L);
|
||||
X11_XFlush(display);
|
||||
|
||||
XEvent evt;
|
||||
evt.xclient.type = ClientMessage;
|
||||
evt.xclient.window = data->xwindow;
|
||||
evt.xclient.message_type = X11_XInternAtom(display, "_NET_WM_MOVERESIZE", True);
|
||||
evt.xclient.format = 32;
|
||||
evt.xclient.data.l[0] = window->x + point->x;
|
||||
evt.xclient.data.l[1] = window->y + point->y;
|
||||
evt.xclient.data.l[2] = direction;
|
||||
evt.xclient.data.l[3] = Button1;
|
||||
evt.xclient.data.l[4] = 0;
|
||||
X11_XSendEvent(display, DefaultRootWindow(display), False, SubstructureRedirectMask | SubstructureNotifyMask, &evt);
|
||||
|
||||
X11_XSync(display, 0);
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
ProcessHitTest(_THIS, const SDL_WindowData *data, const XEvent *xev)
|
||||
{
|
||||
SDL_Window *window = data->window;
|
||||
SDL_bool ret = SDL_FALSE;
|
||||
|
||||
if (window->hit_test) {
|
||||
const SDL_Point point = { xev->xbutton.x, xev->xbutton.y };
|
||||
const SDL_HitTestResult rc = window->hit_test(window, &point, window->hit_test_data);
|
||||
if (rc == SDL_HITTEST_DRAGGABLE) {
|
||||
InitiateWindowMove(_this, data, &point);
|
||||
return SDL_TRUE; /* dragging, drop this event. */
|
||||
switch (rc) {
|
||||
case SDL_HITTEST_DRAGGABLE: {
|
||||
InitiateWindowMove(_this, data, &point);
|
||||
ret = SDL_TRUE;
|
||||
}
|
||||
break;
|
||||
case SDL_HITTEST_RESIZE_TOPLEFT: {
|
||||
InitiateWindowResize(_this, data, &point, _NET_WM_MOVERESIZE_SIZE_TOPLEFT);
|
||||
ret = SDL_TRUE;
|
||||
}
|
||||
break;
|
||||
case SDL_HITTEST_RESIZE_TOP: {
|
||||
InitiateWindowResize(_this, data, &point, _NET_WM_MOVERESIZE_SIZE_TOP);
|
||||
ret = SDL_TRUE;
|
||||
}
|
||||
break;
|
||||
case SDL_HITTEST_RESIZE_TOPRIGHT: {
|
||||
InitiateWindowResize(_this, data, &point, _NET_WM_MOVERESIZE_SIZE_TOPRIGHT);
|
||||
ret = SDL_TRUE;
|
||||
}
|
||||
break;
|
||||
case SDL_HITTEST_RESIZE_RIGHT: {
|
||||
InitiateWindowResize(_this, data, &point, _NET_WM_MOVERESIZE_SIZE_RIGHT);
|
||||
ret = SDL_TRUE;
|
||||
}
|
||||
break;
|
||||
case SDL_HITTEST_RESIZE_BOTTOMRIGHT: {
|
||||
InitiateWindowResize(_this, data, &point, _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT);
|
||||
ret = SDL_TRUE;
|
||||
}
|
||||
break;
|
||||
case SDL_HITTEST_RESIZE_BOTTOM: {
|
||||
InitiateWindowResize(_this, data, &point, _NET_WM_MOVERESIZE_SIZE_BOTTOM);
|
||||
ret = SDL_TRUE;
|
||||
}
|
||||
break;
|
||||
case SDL_HITTEST_RESIZE_BOTTOMLEFT: {
|
||||
InitiateWindowResize(_this, data, &point, _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT);
|
||||
ret = SDL_TRUE;
|
||||
}
|
||||
break;
|
||||
case SDL_HITTEST_RESIZE_LEFT: {
|
||||
InitiateWindowResize(_this, data, &point, _NET_WM_MOVERESIZE_SIZE_LEFT);
|
||||
ret = SDL_TRUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return SDL_FALSE; /* not a drag area. */
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
/* !!! FIXME: rewrite this to be wired in to test framework. */
|
||||
|
||||
#define RESIZE_BORDER 20
|
||||
|
||||
const SDL_Rect drag_areas[] = {
|
||||
{ 20, 20, 100, 100 },
|
||||
{ 200, 70, 100, 100 },
|
||||
@ -16,6 +18,8 @@ static SDL_HitTestResult
|
||||
hitTest(SDL_Window *window, const SDL_Point *pt, void *data)
|
||||
{
|
||||
int i;
|
||||
int w, h;
|
||||
|
||||
for (i = 0; i < numareas; i++) {
|
||||
if (SDL_PointInRect(pt, &areas[i])) {
|
||||
SDL_Log("HIT-TEST: DRAGGABLE\n");
|
||||
@ -23,6 +27,24 @@ hitTest(SDL_Window *window, const SDL_Point *pt, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
SDL_GetWindowSize(window, &w, &h);
|
||||
if (pt->x < RESIZE_BORDER && pt->y < RESIZE_BORDER)
|
||||
return SDL_HITTEST_RESIZE_TOPLEFT;
|
||||
if (pt->x > RESIZE_BORDER && pt->x < w - RESIZE_BORDER && pt->y < RESIZE_BORDER)
|
||||
return SDL_HITTEST_RESIZE_TOP;
|
||||
if (pt->x > w - RESIZE_BORDER && pt->y < RESIZE_BORDER)
|
||||
return SDL_HITTEST_RESIZE_TOPRIGHT;
|
||||
if (pt->x > w - RESIZE_BORDER && pt->y > RESIZE_BORDER && pt->y < h - RESIZE_BORDER)
|
||||
return SDL_HITTEST_RESIZE_RIGHT;
|
||||
if (pt->x > w - RESIZE_BORDER && pt->y > h - RESIZE_BORDER)
|
||||
return SDL_HITTEST_RESIZE_BOTTOMRIGHT;
|
||||
if (pt->x < w - RESIZE_BORDER && pt->x > RESIZE_BORDER && pt->y > h - RESIZE_BORDER)
|
||||
return SDL_HITTEST_RESIZE_BOTTOM;
|
||||
if (pt->x < RESIZE_BORDER && pt->y > h - RESIZE_BORDER)
|
||||
return SDL_HITTEST_RESIZE_BOTTOMLEFT;
|
||||
if (pt->x < RESIZE_BORDER && pt->y < h - RESIZE_BORDER && pt->y > RESIZE_BORDER)
|
||||
return SDL_HITTEST_RESIZE_LEFT;
|
||||
|
||||
SDL_Log("HIT-TEST: NORMAL\n");
|
||||
return SDL_HITTEST_NORMAL;
|
||||
}
|
||||
@ -36,7 +58,7 @@ int main(int argc, char **argv)
|
||||
|
||||
/* !!! FIXME: check for errors. */
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
window = SDL_CreateWindow("Drag the red boxes", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_BORDERLESS);
|
||||
window = SDL_CreateWindow("Drag the red boxes", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE);
|
||||
renderer = SDL_CreateRenderer(window, -1, 0);
|
||||
|
||||
if (SDL_SetWindowHitTest(window, hitTest, NULL) == -1) {
|
||||
|
Loading…
Reference in New Issue
Block a user