Started implementing keyboard events on OS X uiArea.

This commit is contained in:
Pietro Gagliardi 2015-09-13 19:26:40 -04:00
parent 1ac9bdaa02
commit fed92cdf34
4 changed files with 119 additions and 3 deletions

View File

@ -2,6 +2,7 @@
#import <Cocoa/Cocoa.h>
#import <stdint.h>
#import "ui.h"
#import "uipriv_darwin.h"
extern uiArea *newArea(uiAreaHandler *ah);

View File

@ -68,7 +68,13 @@ void addConstraint(NSView *view, NSString *constraint, NSDictionary *metrics, NS
uiArea *libui_a;
}
- (id)initWithFrame:(NSRect)r area:(uiArea *)a;
- (uiModifiers)parseModifiers:(NSEvent *)e;
- (void)doMouseEvent:(NSEvent *)e;
- (int)sendKeyEvent:(uiAreaKeyEvent *)ke;
- (int)doKeyDownUp:(NSEvent *)e up:(int)up;
- (int)doKeyDown:(NSEvent *)e;
- (int)doKeyUp:(NSEvent *)e;
- (int)doFlagsChanged:(NSEvent *)e;
@end
@interface areaView : NSView {
@ -116,6 +122,7 @@ struct uiArea {
{
CGContextRef c;
uiAreaDrawParams dp;
areaView *av;
c = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
dp.Context = newContext(c);
@ -130,7 +137,9 @@ struct uiArea {
// TODO DPI
// TODO scroll position
av = (areaView *) [self superview];
dp.HScrollPos = [av hscrollPos];
dp.VScrollPos = [av vscrollPos];
(*(self->libui_a->ah->Draw))(self->libui_a->ah, self->libui_a, &dp);
}
@ -145,6 +154,24 @@ struct uiArea {
return YES;
}
- (uiModifiers)parseModifiers:(NSEvent *)e
{
NSEventModifierFlags mods;
uiModifiers m;
m = 0;
mods = [e modifierFlags];
if ((mods & NSControlKeyMask) != 0)
m |= uiModifierCtrl;
if ((mods & NSAlternateKeyMask) != 0)
m |= uiModifierAlt;
if ((mods & NSShiftKeyMask) != 0)
m |= uiModifierShift;
if ((mods & NSCommandKeyMask) != 0)
m |= uiModifierSuper;
return m;
}
// capture on drag is done automatically on OS X
- (void)doMouseEvent:(NSEvent *)e
{
@ -196,7 +223,7 @@ struct uiArea {
break;
}
me.Modifiers = 0; // TODO
me.Modifiers = [self parseModifiers:e];
pmb = [NSEvent pressedMouseButtons];
me.Held1To64 = 0;
@ -245,8 +272,90 @@ mouseEvent(otherMouseUp)
// even if I invoke the task switcher and switch processes, the mouse grab will still be held until I let go of all buttons
// therefore, no DragBroken()
- (int)sendKeyEvent:(uiAreaKeyEvent *)ke
{
return (*(self->libui_a->ah->KeyEvent))(self->libui_a->ah, self->libui_a, ke);
}
- (int)doKeyDownUp:(NSEvent *)e up:(int)up
{
uiKeyEvent ke;
ke.Key = 0;
ke.ExtKey = 0;
ke.Modifier = 0;
ke.Modifiers = [self parseModifiers:e];
ke.Up = up;
if (!fromKeycode([e keyCode], &ke))
return 0;
return [self sendKeyEvent:&ke];
}
- (int)doKeyDown:(NSEvent *)e
{
return [self doKeyDownUp:e up:0];
}
- (int)doKeyUp:(NSEvent *)e
{
return [self doKeyDownUp:e up:1];
}
- (int)doFlagsChanged:(NSEvent *)e
{
uiAreaKeyEvent ke;
uiModifiers whichmod;
ke.Key = 0;
ke.ExtKey = 0;
// Mac OS X sends this event on both key up and key down.
// Fortunately -[e keyCode] IS valid here, so we can simply map from key code to Modifiers, get the value of [e modifierFlags], and check if the respective bit is set or not that will give us the up/down state
if (!keycodeModifier([e keyCode], &whichmod))
return 0;
ke.Modifier = whichmod;
ke.Modifiers = [self parseModifiers:e];
ke.Up = (ke.Modifiers & ke.Modifier) == 0;
// and then drop the current modifier from Modifiers
ke.Modifiers &= ~ke.Modifier;
return [self sendKeyEvent:&ke];
}
@end
// called by subclasses of -[NSApplication sendEvent:]
// by default, NSApplication eats some key events
// this prevents that from happening with uiArea
// see http://stackoverflow.com/questions/24099063/how-do-i-detect-keyup-in-my-nsview-with-the-command-key-held and http://lists.apple.com/archives/cocoa-dev/2003/Oct/msg00442.html
int sendAreaEvents(NSEvent *e)
{
NSEventType type;
id focused;
areaDrawingView *view;
type = [e type];
if (type != NSKeyDown && type != NSKeyUp && type != NSFlagsChanged)
return 0;
focused = [[e window] firstResponder];
if (focused == nil)
return 0;
if (![focused isKindOfClass:[areaDrawingView class]])
return 0;
view = (areaDrawingView *) focused;
switch (type) {
case NSKeyDown:
return [view doKeyDown:e];
case NSKeyUp:
return [view doKeyUp:e];
case NSFlagsChanged:
return [view doFlagsChanged:e];
}
return 0;
}
@implementation areaView
- (id)initWithFrame:(NSRect)r area:(uiArea *)a

View File

@ -145,7 +145,7 @@ static int handlerKeyEvent(uiAreaHandler *ah, uiArea *a, uiAreaKeyEvent *e)
k,
(int) e->ExtKey,
(int) e->Modifier,
(int) e->Modifiers;
(int) e->Modifiers,
e->Up);
return 0;
}

View File

@ -0,0 +1,6 @@
// area.m
extern int sendAreaEvents(NSEvent *e);
// events.m
extern BOOL fromKeycode(unsigned short keycode, uiAreaKeyEvent *ke);
extern BOOL keycodeModifier(unsigned short keycode, uiModifiers *mod);