149 lines
4.7 KiB
Plaintext
149 lines
4.7 KiB
Plaintext
/*
|
|
* This file is part of espanso.
|
|
*
|
|
* Copyright (C) 2019-2021 Federico Terzi
|
|
*
|
|
* espanso is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* espanso is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#import "AppDelegate.h"
|
|
|
|
void addSeparatorMenu(NSMenu * parent);
|
|
void addSingleMenu(NSMenu * parent, id item);
|
|
void addSubMenu(NSMenu * parent, NSArray * items);
|
|
|
|
@implementation AppDelegate
|
|
|
|
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
|
{
|
|
if (options.show_icon) {
|
|
statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength] retain];
|
|
[self setIcon: 0];
|
|
}
|
|
|
|
[[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];
|
|
|
|
// Heartbeat timer setup
|
|
[NSTimer scheduledTimerWithTimeInterval:1.0
|
|
target:self
|
|
selector:@selector(heartbeatHandler:)
|
|
userInfo:nil
|
|
repeats:YES];
|
|
}
|
|
|
|
- (void) setIcon: (int32_t)iconIndex {
|
|
if (options.show_icon) {
|
|
char * iconPath = options.icon_paths[iconIndex];
|
|
NSString *nsIconPath = [NSString stringWithUTF8String:iconPath];
|
|
|
|
NSImage *statusImage = [[NSImage alloc] initWithContentsOfFile:nsIconPath];
|
|
[statusImage setTemplate:YES];
|
|
|
|
[statusItem.button setImage:statusImage];
|
|
[statusItem setHighlightMode:YES];
|
|
[statusItem.button setAction:@selector(statusIconClick:)];
|
|
[statusItem.button setTarget:self];
|
|
}
|
|
}
|
|
|
|
- (IBAction) statusIconClick: (id) sender {
|
|
UIEvent event = {};
|
|
event.event_type = UI_EVENT_TYPE_ICON_CLICK;
|
|
if (event_callback && rust_instance) {
|
|
event_callback(rust_instance, event);
|
|
}
|
|
}
|
|
|
|
- (void) popupMenu: (NSString *) payload {
|
|
NSError *jsonError;
|
|
NSData *data = [payload dataUsingEncoding:NSUTF8StringEncoding];
|
|
NSArray *jsonMenuItems = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError];
|
|
NSMenu *menu = [[NSMenu alloc] initWithTitle:@"Espanso"];
|
|
addSubMenu(menu, jsonMenuItems);
|
|
[statusItem popUpStatusItemMenu: menu];
|
|
}
|
|
|
|
- (IBAction) contextMenuClick: (id) sender {
|
|
NSInteger itemId = [[sender valueForKey:@"tag"] integerValue];
|
|
|
|
UIEvent event = {};
|
|
event.event_type = UI_EVENT_TYPE_CONTEXT_MENU_CLICK;
|
|
event.context_menu_id = (uint32_t) [itemId intValue];
|
|
if (event_callback && rust_instance) {
|
|
event_callback(rust_instance, event);
|
|
}
|
|
}
|
|
|
|
- (void) showNotification: (NSString *) message withDelay: (double) delay {
|
|
NSUserNotification *notification = [[NSUserNotification alloc] init];
|
|
notification.title = @"Espanso";
|
|
notification.informativeText = message;
|
|
notification.soundName = nil;
|
|
|
|
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
|
|
[[NSUserNotificationCenter defaultUserNotificationCenter] performSelector:@selector(removeDeliveredNotification:) withObject:notification afterDelay:delay];
|
|
}
|
|
|
|
- (void) heartbeatHandler: (NSTimer *)timer {
|
|
UIEvent event = {};
|
|
event.event_type = UI_EVENT_TYPE_HEARTBEAT;
|
|
if (event_callback && rust_instance) {
|
|
event_callback(rust_instance, event);
|
|
}
|
|
}
|
|
|
|
@end
|
|
|
|
// Menu utility methods
|
|
|
|
void addSeparatorMenu(NSMenu * parent)
|
|
{
|
|
[parent addItem: [NSMenuItem separatorItem]];
|
|
}
|
|
|
|
void addSingleMenu(NSMenu * parent, id item)
|
|
{
|
|
id label = [item objectForKey:@"label"];
|
|
id raw_id = [item objectForKey:@"id"];
|
|
if (label == nil || raw_id == nil)
|
|
{
|
|
return;
|
|
}
|
|
NSMenuItem *newMenu = [[NSMenuItem alloc] initWithTitle:label action:@selector(contextMenuClick:) keyEquivalent:@""];
|
|
[newMenu setTag:(NSInteger)raw_id];
|
|
[parent addItem: newMenu];
|
|
}
|
|
|
|
void addSubMenu(NSMenu * parent, NSArray * items)
|
|
{
|
|
for (id item in items) {
|
|
id type = [item objectForKey:@"type"];
|
|
if ([type isEqualToString:@"simple"])
|
|
{
|
|
addSingleMenu(parent, item);
|
|
}
|
|
else if ([type isEqualToString:@"separator"])
|
|
{
|
|
addSeparatorMenu(parent);
|
|
}
|
|
else if ([type isEqualToString:@"sub"])
|
|
{
|
|
NSMenuItem *menuItem = [[NSMenuItem alloc] initWithTitle:[item objectForKey:@"label"] action:nil keyEquivalent:@""];
|
|
NSMenu *subMenu = [[NSMenu alloc] init];
|
|
[parent addItem: menuItem];
|
|
addSubMenu(subMenu, [item objectForKey:@"items"]);
|
|
[menuItem setSubmenu: subMenu];
|
|
}
|
|
}
|
|
} |