entry: add onKeyEvent for macos

This commit is contained in:
Rustam Gamidov 2020-03-09 20:46:35 +02:00 committed by Rustam Gamidov
parent 599f483914
commit 7f8712d2f5
3 changed files with 73 additions and 0 deletions

View File

@ -59,6 +59,7 @@ struct uiEntry {
NSTextField *textfield; NSTextField *textfield;
void (*onChanged)(uiEntry *, void *); void (*onChanged)(uiEntry *, void *);
void *onChangedData; void *onChangedData;
int (*onKeyEvent)(uiEntry *, uiAreaKeyEvent *);
}; };
static BOOL isSearchField(NSTextField *tf) static BOOL isSearchField(NSTextField *tf)
@ -66,8 +67,37 @@ static BOOL isSearchField(NSTextField *tf)
return [tf isKindOfClass:[NSSearchField class]]; return [tf isKindOfClass:[NSSearchField class]];
} }
static 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;
}
static void triggerOnKeyEvent(void *key, void *e, void *data)
{
uiEntry *entry = (uiEntry *)e;
void *firstResponder = [entry->textfield window].firstResponder;
BOOL sameObj = (entry->textfield == firstResponder);
BOOL currentEditor = (entry->textfield.currentEditor && entry->textfield.currentEditor == firstResponder);
if (sameObj || currentEditor)
entry->onKeyEvent(entry, data);
}
@interface entryDelegateClass : NSObject<NSTextFieldDelegate> { @interface entryDelegateClass : NSObject<NSTextFieldDelegate> {
uiprivMap *entries; uiprivMap *entries;
id eventMonitor;
} }
- (void)controlTextDidChange:(NSNotification *)note; - (void)controlTextDidChange:(NSNotification *)note;
- (IBAction)onSearch:(id)sender; - (IBAction)onSearch:(id)sender;
@ -82,11 +112,27 @@ static BOOL isSearchField(NSTextField *tf)
self = [super init]; self = [super init];
if (self) if (self)
self->entries = uiprivNewMap(); self->entries = uiprivNewMap();
NSEvent* (^eventHandler)(NSEvent*) = ^(NSEvent *theEvent) {
uiAreaKeyEvent ke;
ke.Key = 0;
ke.ExtKey = 0;
ke.Modifier = 0;
ke.Modifiers = parseModifiers(theEvent);
if (uiprivFromKeycode([theEvent keyCode], &ke))
uiprivMapWalkWithData(self->entries, &ke, triggerOnKeyEvent);
return theEvent;
};
eventMonitor = [NSEvent addLocalMonitorForEventsMatchingMask:NSKeyDownMask handler:eventHandler];
return self; return self;
} }
- (void)dealloc - (void)dealloc
{ {
[NSEvent removeMonitor:eventMonitor];
uiprivMapDestroy(self->entries); uiprivMapDestroy(self->entries);
[super dealloc]; [super dealloc];
} }
@ -155,6 +201,11 @@ void uiEntryOnChanged(uiEntry *e, void (*f)(uiEntry *, void *), void *data)
e->onChangedData = data; e->onChangedData = data;
} }
void uiEntryOnKeyEvent(uiEntry *e, int (*f)(uiEntry *, uiAreaKeyEvent *))
{
e->onKeyEvent = f;
}
int uiEntryReadOnly(uiEntry *e) int uiEntryReadOnly(uiEntry *e)
{ {
return [e->textfield isEditable] == NO; return [e->textfield isEditable] == NO;
@ -175,6 +226,12 @@ static void defaultOnChanged(uiEntry *e, void *data)
// do nothing // do nothing
} }
static int defaultOnKeyEvent(uiEntry *e, uiAreaKeyEvent *ke)
{
// do nothing
return FALSE;
}
// these are based on interface builder defaults; my comments in the old code weren't very good so I don't really know what talked about what, sorry :/ // these are based on interface builder defaults; my comments in the old code weren't very good so I don't really know what talked about what, sorry :/
void uiprivFinishNewTextField(NSTextField *t, BOOL isEntry) void uiprivFinishNewTextField(NSTextField *t, BOOL isEntry)
{ {
@ -220,6 +277,7 @@ static uiEntry *finishNewEntry(Class class)
} }
[entryDelegate registerEntry:e]; [entryDelegate registerEntry:e];
uiEntryOnChanged(e, defaultOnChanged, NULL); uiEntryOnChanged(e, defaultOnChanged, NULL);
uiEntryOnKeyEvent(e, defaultOnKeyEvent);
return e; return e;
} }

View File

@ -55,6 +55,20 @@ void uiprivMapWalk(uiprivMap *m, void (*f)(void *key, void *value))
NSEndMapTableEnumeration(&e); NSEndMapTableEnumeration(&e);
} }
void uiprivMapWalkWithData(uiprivMap *m, void *data, void (*f)(void *key, void *value, void *data))
{
NSMapEnumerator e;
void *k, *v;
e = NSEnumerateMapTable(m->m);
k = NULL;
v = NULL;
while (NSNextMapEnumeratorPair(&e, &k, &v))
f(k, v, data);
NSEndMapTableEnumeration(&e);
}
void uiprivMapReset(uiprivMap *m) void uiprivMapReset(uiprivMap *m)
{ {
NSResetMapTable(m->m); NSResetMapTable(m->m);

View File

@ -31,6 +31,7 @@ extern void *uiprivMapGet(uiprivMap *m, void *key);
extern void uiprivMapSet(uiprivMap *m, void *key, void *value); extern void uiprivMapSet(uiprivMap *m, void *key, void *value);
extern void uiprivMapDelete(uiprivMap *m, void *key); extern void uiprivMapDelete(uiprivMap *m, void *key);
extern void uiprivMapWalk(uiprivMap *m, void (*f)(void *key, void *value)); extern void uiprivMapWalk(uiprivMap *m, void (*f)(void *key, void *value));
extern void uiprivMapWalkWithData(uiprivMap *m, void *data, void (*f)(void *key, void *value, void *data));
extern void uiprivMapReset(uiprivMap *m); extern void uiprivMapReset(uiprivMap *m);
// menu.m // menu.m