Implemented the window drag stuff on GTK+. It works!

This commit is contained in:
Pietro Gagliardi 2016-10-25 00:34:12 -04:00
parent 67ff2fa855
commit 22caa5e502
3 changed files with 81 additions and 1 deletions

View File

@ -107,7 +107,7 @@ static void handlerMouseEvent(uiAreaHandler *a, uiArea *area, uiAreaMouseEvent *
#define resize(cond, edge) if (cond) { uiAreaBeginUserWindowResize(area, edge); return; } #define resize(cond, edge) if (cond) { uiAreaBeginUserWindowResize(area, edge); return; }
resize(ta.leftresize.in, uiWindowResizeEdgeLeft) resize(ta.leftresize.in, uiWindowResizeEdgeLeft)
resize(ta.topresize.in, uiWindowResizeEdgeTop) resize(ta.topresize.in, uiWindowResizeEdgeTop)
resize((ta.rightresize.in, uiWindowResizeEdgeRight) resize(ta.rightresize.in, uiWindowResizeEdgeRight)
resize(ta.bottomresize.in, uiWindowResizeEdgeBottom) resize(ta.bottomresize.in, uiWindowResizeEdgeBottom)
resize(ta.topleftresize.in, uiWindowResizeEdgeTopLeft) resize(ta.topleftresize.in, uiWindowResizeEdgeTopLeft)
resize(ta.toprightresize.in, uiWindowResizeEdgeTopRight) resize(ta.toprightresize.in, uiWindowResizeEdgeTopRight)

3
ui.h
View File

@ -301,6 +301,8 @@ _UI_ENUM(uiWindowResizeEdge) {
uiWindowResizeEdgeBottomLeft, uiWindowResizeEdgeBottomLeft,
uiWindowResizeEdgeBottomRight, uiWindowResizeEdgeBottomRight,
// TODO have one for keyboard resizes? // TODO have one for keyboard resizes?
// TODO GDK doesn't seem to have any others, including for keyboards...
// TODO way to bring up the system menu instead?
}; };
#define uiArea(this) ((uiArea *) (this)) #define uiArea(this) ((uiArea *) (this))
@ -312,6 +314,7 @@ _UI_EXTERN void uiAreaQueueRedrawAll(uiArea *a);
_UI_EXTERN void uiAreaScrollTo(uiArea *a, double x, double y, double width, double height); _UI_EXTERN void uiAreaScrollTo(uiArea *a, double x, double y, double width, double height);
// TODO document these can only be called within Mouse() handlers // TODO document these can only be called within Mouse() handlers
// TODO should these be allowed on scrolling areas? // TODO should these be allowed on scrolling areas?
// TODO decide which mouse events should be accepted; Down is the only one guaranteed to work right now
_UI_EXTERN void uiAreaBeginUserWindowMove(uiArea *a); _UI_EXTERN void uiAreaBeginUserWindowMove(uiArea *a);
_UI_EXTERN void uiAreaBeginUserWindowResize(uiArea *a, uiWindowResizeEdge edge); _UI_EXTERN void uiAreaBeginUserWindowResize(uiArea *a, uiWindowResizeEdge edge);
_UI_EXTERN uiArea *uiNewArea(uiAreaHandler *ah); _UI_EXTERN uiArea *uiNewArea(uiAreaHandler *ah);

View File

@ -46,6 +46,9 @@ struct uiArea {
// note that this is a pointer; see above // note that this is a pointer; see above
clickCounter *cc; clickCounter *cc;
// for user window drags
GdkEventButton *dragevent;
}; };
G_DEFINE_TYPE(areaWidget, areaWidget, GTK_TYPE_DRAWING_AREA) G_DEFINE_TYPE(areaWidget, areaWidget, GTK_TYPE_DRAWING_AREA)
@ -261,7 +264,11 @@ static gboolean areaWidget_button_press_event(GtkWidget *w, GdkEventButton *e)
me.Down = e->button; me.Down = e->button;
me.Up = 0; me.Up = 0;
// and set things up for window drags
a->dragevent = e;
finishMouseEvent(a, &me, e->button, e->x, e->y, e->state, e->window); finishMouseEvent(a, &me, e->button, e->x, e->y, e->state, e->window);
a->dragevent = NULL;
return GDK_EVENT_PROPAGATE; return GDK_EVENT_PROPAGATE;
} }
@ -505,6 +512,76 @@ void uiAreaScrollTo(uiArea *a, double x, double y, double width, double height)
// TODO adjust adjustments and find source for that // TODO adjust adjustments and find source for that
} }
void uiAreaBeginUserWindowMove(uiArea *a)
{
GtkWidget *toplevel;
if (a->dragevent == NULL)
userbug("cannot call uiAreaBeginUserWindowMove() outside of a Mouse() with Down != 0");
// TODO don't we have a libui function for this? did I scrap it?
// TODO widget or areaWidget?
toplevel = gtk_widget_get_toplevel(a->widget);
if (toplevel == NULL) {
// TODO
return;
}
// the docs say to do this
if (!gtk_widget_is_toplevel(toplevel)) {
// TODO
return;
}
if (!GTK_IS_WINDOW(toplevel)) {
// TODO
return;
}
gtk_window_begin_move_drag(GTK_WINDOW(toplevel),
a->dragevent->button,
a->dragevent->x_root, // TODO are these correct?
a->dragevent->y_root,
a->dragevent->time);
}
static const GdkWindowEdge edges[] = {
[uiWindowResizeEdgeLeft] = GDK_WINDOW_EDGE_WEST,
[uiWindowResizeEdgeTop] = GDK_WINDOW_EDGE_NORTH,
[uiWindowResizeEdgeRight] = GDK_WINDOW_EDGE_EAST,
[uiWindowResizeEdgeBottom] = GDK_WINDOW_EDGE_SOUTH,
[uiWindowResizeEdgeTopLeft] = GDK_WINDOW_EDGE_NORTH_WEST,
[uiWindowResizeEdgeTopRight] = GDK_WINDOW_EDGE_NORTH_EAST,
[uiWindowResizeEdgeBottomLeft] = GDK_WINDOW_EDGE_SOUTH_WEST,
[uiWindowResizeEdgeBottomRight] = GDK_WINDOW_EDGE_SOUTH_EAST,
};
void uiAreaBeginUserWindowResize(uiArea *a, uiWindowResizeEdge edge)
{
GtkWidget *toplevel;
if (a->dragevent == NULL)
userbug("cannot call uiAreaBeginUserWindowResize() outside of a Mouse() with Down != 0");
// TODO don't we have a libui function for this? did I scrap it?
// TODO widget or areaWidget?
toplevel = gtk_widget_get_toplevel(a->widget);
if (toplevel == NULL) {
// TODO
return;
}
// the docs say to do this
if (!gtk_widget_is_toplevel(toplevel)) {
// TODO
return;
}
if (!GTK_IS_WINDOW(toplevel)) {
// TODO
return;
}
gtk_window_begin_resize_drag(GTK_WINDOW(toplevel),
edges[edge],
a->dragevent->button,
a->dragevent->x_root, // TODO are these correct?
a->dragevent->y_root,
a->dragevent->time);
}
uiArea *uiNewArea(uiAreaHandler *ah) uiArea *uiNewArea(uiAreaHandler *ah)
{ {
uiArea *a; uiArea *a;