And implemented moves on OS X.
This commit is contained in:
parent
81b95a59b1
commit
17dc5f407e
|
@ -7,6 +7,9 @@ This README is being written.<br>
|
|||
|
||||
## Announcements
|
||||
|
||||
* **2 November 2016**
|
||||
* Added two new functions to replace the deleted `uiWindowPosition()` and friends: `uiAreaBeginUserWindowMove()` and `uiAreaBeginUserWindowResize()`. When used in a `uiAreaHandler.Mouse()` event handler, these let you initiate a user-driven mouse move or mouse resize of the window at any point in a uiArea.
|
||||
|
||||
* **31 October 2016**
|
||||
* @krakjoe noticed that I accidentally used thread-unsafe code in uiQueueMain() on Unix. Fixed.
|
||||
|
||||
|
|
|
@ -140,4 +140,5 @@ extern NSTextField *newLabel(NSString *str);
|
|||
extern NSImage *imageImage(uiImage *);
|
||||
|
||||
// winmoveresize.m
|
||||
extern void doManualMove(NSWindow *w, NSEvent *initialEvent);
|
||||
extern void doManualResize(NSWindow *w, NSEvent *initialEvent, uiWindowResizeEdge edge);
|
||||
|
|
|
@ -22,7 +22,7 @@ struct uiWindow {
|
|||
|
||||
- (void)libui_doMove:(NSEvent *)initialEvent
|
||||
{
|
||||
// TODO
|
||||
doManualMove(self, initialEvent);
|
||||
}
|
||||
|
||||
- (void)libui_doResize:(NSEvent *)initialEvent on:(uiWindowResizeEdge)edge
|
||||
|
|
|
@ -1,6 +1,76 @@
|
|||
// 1 november 2016
|
||||
#import "uipriv_darwin.h"
|
||||
|
||||
// because we are changing the window frame each time the mouse moves, the successive -[NSEvent locationInWindow]s cannot be meaningfully used together
|
||||
// make sure they are all following some sort of standard to avoid this problem; the screen is the most obvious possibility since it requires only one conversion (the only one that a NSWindow provides)
|
||||
static NSPoint makeIndependent(NSPoint p, NSWindow *w)
|
||||
{
|
||||
NSRect r;
|
||||
|
||||
r.origin = p;
|
||||
// mikeash in irc.freenode.net/#macdev confirms both that any size will do and that we can safely ignore the resultant size
|
||||
r.size = NSZeroSize;
|
||||
return [w convertRectToScreen:r].origin;
|
||||
}
|
||||
|
||||
struct onMoveDragParams {
|
||||
NSWindow *w;
|
||||
// using the previous point causes weird issues like the mouse seeming to fall behind the window edge... so do this instead
|
||||
// TODO will this make things like the menubar and dock easier too?
|
||||
NSRect initialFrame;
|
||||
NSPoint initialPoint;
|
||||
};
|
||||
|
||||
void onMoveDrag(struct onMoveDragParams *p, NSEvent *e)
|
||||
{
|
||||
NSPoint new;
|
||||
NSRect frame;
|
||||
CGFloat offx, offy;
|
||||
|
||||
new = makeIndependent([e locationInWindow], p->w);
|
||||
frame = p->initialFrame;
|
||||
|
||||
offx = new.x - p->initialPoint.x;
|
||||
offy = new.y - p->initialPoint.y;
|
||||
frame.origin.x += offx;
|
||||
frame.origin.y += offy;
|
||||
|
||||
// TODO handle the menubar
|
||||
// TODO wait the system does this for us already?!
|
||||
|
||||
[p->w setFrameOrigin:frame.origin];
|
||||
}
|
||||
|
||||
// LONGTERM FUTURE -[NSWindow performWindowDragWithEvent:] would be better but that's 10.11-only
|
||||
void doManualMove(NSWindow *w, NSEvent *initialEvent)
|
||||
{
|
||||
__block struct onMoveDragParams mdp;
|
||||
struct nextEventArgs nea;
|
||||
BOOL (^handleEvent)(NSEvent *e);
|
||||
__block BOOL done;
|
||||
|
||||
mdp.w = w;
|
||||
mdp.initialFrame = [mdp.w frame];
|
||||
mdp.initialPoint = makeIndependent([initialEvent locationInWindow], mdp.w);
|
||||
|
||||
nea.mask = NSLeftMouseDraggedMask | NSLeftMouseUpMask;
|
||||
nea.duration = [NSDate distantFuture];
|
||||
nea.mode = NSEventTrackingRunLoopMode; // nextEventMatchingMask: docs suggest using this for manual mouse tracking
|
||||
nea.dequeue = YES;
|
||||
handleEvent = ^(NSEvent *e) {
|
||||
if ([e type] == NSLeftMouseUp) {
|
||||
done = YES;
|
||||
return YES; // do not send
|
||||
}
|
||||
onMoveDrag(&mdp, e);
|
||||
return YES; // do not send
|
||||
};
|
||||
done = NO;
|
||||
while (mainStep(&nea, handleEvent))
|
||||
if (done)
|
||||
break;
|
||||
}
|
||||
|
||||
// see http://stackoverflow.com/a/40352996/3408572
|
||||
static void minMaxAutoLayoutSizes(NSWindow *w, NSSize *min, NSSize *max)
|
||||
{
|
||||
|
@ -93,18 +163,6 @@ struct onResizeDragParams {
|
|||
NSSize max;
|
||||
};
|
||||
|
||||
// because we are changing the window frame each time the mouse moves, the successive -[NSEvent locationInWindow]s cannot be meaningfully used together
|
||||
// make sure they are all following some sort of standard to avoid this problem; the screen is the most obvious possibility since it requires only one conversion (the only one that a NSWindow provides)
|
||||
static NSPoint makeIndependent(NSPoint p, NSWindow *w)
|
||||
{
|
||||
NSRect r;
|
||||
|
||||
r.origin = p;
|
||||
// mikeash in irc.freenode.net/#macdev confirms both that any size will do and that we can safely ignore the resultant size
|
||||
r.size = NSZeroSize;
|
||||
return [w convertRectToScreen:r].origin;
|
||||
}
|
||||
|
||||
static void onResizeDrag(struct onResizeDragParams *p, NSEvent *e)
|
||||
{
|
||||
NSPoint new;
|
||||
|
|
Loading…
Reference in New Issue