From aa171bd4a359014a74ccfa2cc0a532033123e910 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Fri, 11 Sep 2015 21:20:49 -0400 Subject: [PATCH] Started doing mouse events on OS X. --- macarea/alt/area.m | 111 +++++++++++++++++++++++++++++++++++++++++++++ macarea/alt/main.m | 15 ++++++ macarea/alt/ui.h | 51 ++++++++++++--------- 3 files changed, 155 insertions(+), 22 deletions(-) diff --git a/macarea/alt/area.m b/macarea/alt/area.m index 95affe47..97cfc615 100644 --- a/macarea/alt/area.m +++ b/macarea/alt/area.m @@ -68,6 +68,7 @@ void addConstraint(NSView *view, NSString *constraint, NSDictionary *metrics, NS uiArea *libui_a; } - (id)initWithFrame:(NSRect)r area:(uiArea *)a; +- (void)doMouseEvent:(NSEvent *)e; @end @interface areaView : NSView { @@ -82,6 +83,8 @@ void addConstraint(NSView *view, NSString *constraint, NSDictionary *metrics, NS - (void)dvFrameSizeChanged:(NSNotification *)note; - (IBAction)hscrollEvent:(id)sender; - (IBAction)vscrollEvent:(id)sender; +- (intmax_t)hscrollPos; +- (intmax_t)vscrollPos; // scroll utilities - (intmax_t)hpagesize; - (intmax_t)vpagesize; @@ -137,6 +140,104 @@ struct uiArea { return YES; } +- (BOOL)acceptsFirstResponder +{ + return YES; +} + +- (void)doMouseEvent:(NSEvent *)e +{ + uiAreaMouseEvent me; + NSPoint point; + areaView *av; + uintmax_t buttonNumber; + NSUInteger pmb; + unsigned int i, max; + + av = (areaView *) [self superview]; + + point = [self convertPoint:[e locationInWindow] fromView:nil]; + me.X = point.x; + me.Y = point.y; + me.HScrollPos = [av hscrollPos]; + me.VScrollPos = [av vscrollPos]; + // don't clip to outside the view in the case of captures + // TODO cocoa captures automatically on a drag? + + buttonNumber = [e buttonNumber] + 1; + // swap button numbers 2 and 3 (right and middle) + if (buttonNumber == 2) + buttonNumber = 3; + else if (buttonNumber == 3) + buttonNumber = 2; + + me.Down = 0; + me.Up = 0; + me.Count = 0; + switch ([e type]) { + case NSLeftMouseDown: + case NSRightMouseDown: + case NSOtherMouseDown: + me.Down = buttonNumber; + me.Count = [e clickCount]; + break; + case NSLeftMouseUp: + case NSRightMouseUp: + case NSOtherMouseUp: + me.Up = buttonNumber; + break; + case NSLeftMouseDragged: + case NSRightMouseDragged: + case NSOtherMouseDragged: + // we include the button that triggered the dragged event in the Held fields + buttonNumber = 0; + break; + } + + me.Modifiers = 0; // TODO + + pmb = [NSEvent pressedMouseButtons]; + me.Held1To64 = 0; + if (buttonNumber != 1 && (pmb & 1) != 0) + me.Held1To64 |= 1; + if (buttonNumber != 2 && (pmb & 4) != 0) + me.Held1To64 |= 2; + if (buttonNumber != 3 && (pmb & 2) != 0) + me.Held1To64 |= 4; + // buttons 4..64 + max = 32; + // TODO are the upper 32 bits just mirrored? +// if (sizeof (NSUInteger) == 8) +// max = 64; + for (i = 4; i <= max; i++) { + uint64_t j; + + if (buttonNumber == i) + continue; + j = 1 << (i - 1); + if ((pmb & j) != 0) + me.Held1To64 |= j; + } + + (*(self->libui_a->ah->MouseEvent))(self->libui_a->ah, self->libui_a, &me); +} + +#define mouseEvent(name) \ + - (void)name:(NSEvent *)e \ + { \ + [self doMouseEvent:e]; \ + } +mouseEvent(mouseMoved) +mouseEvent(mouseDragged) +mouseEvent(rightMouseDragged) +mouseEvent(otherMouseDragged) +mouseEvent(mouseDown) +mouseEvent(rightMouseDown) +mouseEvent(otherMouseDown) +mouseEvent(mouseUp) +mouseEvent(rightMouseUp) +mouseEvent(otherMouseUp) + @end @implementation areaView @@ -350,6 +451,16 @@ struct uiArea { [self vscrollTo:pos]; } +- (intmax_t)hscrollPos +{ + return self->hscrollpos; +} + +- (intmax_t)vscrollPos +{ + return self->vscrollpos; +} + // scroll utilities - (intmax_t)hpagesize diff --git a/macarea/alt/main.m b/macarea/alt/main.m index 3ee15aa6..a6306b93 100644 --- a/macarea/alt/main.m +++ b/macarea/alt/main.m @@ -110,6 +110,20 @@ static int handlerRedrawOnResize(uiAreaHandler *a, uiArea *area) return 1; } +static void handlerMouseEvent(uiAreaHandler *a, uiArea *area, uiAreaMouseEvent *e) +{ + printf("mouse (%d,%d):(%d,%d) down:%d up:%d count:%d mods:%x held:%x\n", + (int) e->X, + (int) e->Y, + (int) e->HScrollPos, + (int) e->VScrollPos, + (int) e->Down, + (int) e->Up, + (int) e->Count, + (uint32_t) e->Modifiers, + e->Held1To64); +} + // areaUpdateScroll(area); @interface appDelegate : NSObject @@ -168,6 +182,7 @@ int main(void) h.ah.HScrollMax = handlerHScrollMax; h.ah.VScrollMax = handlerVScrollMax; h.ah.RedrawOnResize = handlerRedrawOnResize; + h.ah.MouseEvent = handlerMouseEvent; app = [NSApplication sharedApplication]; [app setActivationPolicy:NSApplicationActivationPolicyRegular]; diff --git a/macarea/alt/ui.h b/macarea/alt/ui.h index 90dc0fbd..7d7c7ecb 100644 --- a/macarea/alt/ui.h +++ b/macarea/alt/ui.h @@ -3,6 +3,7 @@ typedef struct uiArea uiArea; typedef struct uiAreaHandler uiAreaHandler; typedef struct uiAreaDrawParams uiAreaDrawParams; +typedef struct uiAreaMouseEvent uiAreaMouseEvent; typedef struct uiDrawContext uiDrawContext; @@ -11,6 +12,7 @@ struct uiAreaHandler { uintmax_t (*HScrollMax)(uiAreaHandler *, uiArea *); uintmax_t (*VScrollMax)(uiAreaHandler *, uiArea *); int (*RedrawOnResize)(uiAreaHandler *, uiArea *); + void (*MouseEvent)(uiAreaHandler *, uiArea *, uiAreaMouseEvent *); }; struct uiAreaDrawParams { @@ -115,25 +117,30 @@ void uiDrawFill(uiDrawContext *, uiDrawFillMode); // - solid colors, arbitrary spaces // - shadows -// arcs -// cairo_arc/arc_negative -// - parameters: center, radius, angle1 radians, angle2 radins -// - if angle2 < angle1, TODO -// - if angle2 > angle1, TODO -// - line segment from current point to beginning of arc -// - arc: clockwise, arc_negative: counterclockwise -// - circular -// GDI Arc/Pie -// - parameters: bounding box, start point, end point -// - current position not used/changed -// - either clockwise or counterclockwise -// - elliptical -// GDI ArcTo -// - same as Arc except line segment from current point to beginning of arc -// - there does not appear to be a PieTo -// GDI AngleArc -// - parameters: center, radius, angle1 degrees, angle2 degrees -// - line segment from current position to beginning of arc -// - counterclockwise -// - circular -// - can be used to draw pies too; MSDN example demonstrates +typedef enum uiModifiers uiModifiers; + +enum uiModifiers { + uiModifierCtrl = 1 << 0, + uiModifierAlt = 1 << 1, + uiModifierShift = 1 << 2, + uiModifierSuper = 1 << 3, +}; + +struct uiAreaMouseEvent { + // notes: + // - relative to content rect + intmax_t X; + intmax_t Y; + + intmax_t HScrollPos; + intmax_t VScrollPos; + + uintmax_t Down; + uintmax_t Up; + + uintmax_t Count; + + uiModifiers Modifiers; + + uint64_t Held1To64; +};