implement full Tray-API

This commit is contained in:
Gregor Biswanger
2017-10-18 05:30:36 +02:00
parent 7be3cbe524
commit 8caec22de9
8 changed files with 483 additions and 6 deletions

View File

@@ -0,0 +1,9 @@
namespace ElectronNET.API
{
public class DisplayBalloonOptions
{
public string Icon { get; set; }
public string Title { get; set; }
public string Content { get; set; }
}
}

View File

@@ -0,0 +1,20 @@
namespace ElectronNET.API.Entities
{
public enum HighlightMode
{
/// <summary>
/// Highlight the tray icon when it is clicked and also when its context menu is open. This is the default.
/// </summary>
selection,
/// <summary>
/// Always highlight the tray icon.
/// </summary>
always,
/// <summary>
/// Never highlight the tray icon.
/// </summary>
never
}
}

View File

@@ -0,0 +1,10 @@
namespace ElectronNET.API
{
public class TrayClickEventArgs
{
public bool AltKey { get; set; }
public bool ShiftKey { get; set; }
public bool CtrlKey { get; set; }
public bool MetaKey { get; set; }
}
}

View File

@@ -3,12 +3,182 @@ using ElectronNET.API.Extensions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace ElectronNET.API
{
public sealed class Tray
{
/// <summary>
/// Emitted when the tray icon is clicked.
/// </summary>
public event Action<TrayClickEventArgs, Rectangle> OnClick
{
add
{
if (_click == null)
{
BridgeConnector.Socket.On("tray-click-event", (result) =>
{
var args = ((JArray)result).ToObject<object[]>();
var trayClickEventArgs = ((JObject)args[0]).ToObject<TrayClickEventArgs>();
var bounds = ((JObject)args[1]).ToObject<Rectangle>();
_click(trayClickEventArgs, bounds);
});
BridgeConnector.Socket.Emit("register-tray-click");
}
_click += value;
}
remove
{
_click -= value;
}
}
private event Action<TrayClickEventArgs, Rectangle> _click;
/// <summary>
/// macOS, Windows: Emitted when the tray icon is right clicked.
/// </summary>
public event Action<TrayClickEventArgs, Rectangle> OnRightClick
{
add
{
if (_rightClick == null)
{
BridgeConnector.Socket.On("tray-right-click-event", (result) =>
{
var args = ((JArray)result).ToObject<object[]>();
var trayClickEventArgs = ((JObject)args[0]).ToObject<TrayClickEventArgs>();
var bounds = ((JObject)args[1]).ToObject<Rectangle>();
_rightClick(trayClickEventArgs, bounds);
});
BridgeConnector.Socket.Emit("register-tray-right-click");
}
_rightClick += value;
}
remove
{
_rightClick -= value;
}
}
private event Action<TrayClickEventArgs, Rectangle> _rightClick;
/// <summary>
/// macOS, Windows: Emitted when the tray icon is double clicked.
/// </summary>
public event Action<TrayClickEventArgs, Rectangle> OnDoubleClick
{
add
{
if (_doubleClick == null)
{
BridgeConnector.Socket.On("tray-double-click-event", (result) =>
{
var args = ((JArray)result).ToObject<object[]>();
var trayClickEventArgs = ((JObject)args[0]).ToObject<TrayClickEventArgs>();
var bounds = ((JObject)args[1]).ToObject<Rectangle>();
_doubleClick(trayClickEventArgs, bounds);
});
BridgeConnector.Socket.Emit("register-tray-double-click");
}
_doubleClick += value;
}
remove
{
_doubleClick -= value;
}
}
private event Action<TrayClickEventArgs, Rectangle> _doubleClick;
/// <summary>
/// Windows: Emitted when the tray balloon shows.
/// </summary>
public event Action OnBalloonShow
{
add
{
if (_balloonShow == null)
{
BridgeConnector.Socket.On("tray-balloon-show-event", () =>
{
_balloonShow();
});
BridgeConnector.Socket.Emit("register-tray-balloon-show");
}
_balloonShow += value;
}
remove
{
_balloonShow -= value;
}
}
private event Action _balloonShow;
/// <summary>
/// Windows: Emitted when the tray balloon is clicked.
/// </summary>
public event Action OnBalloonClick
{
add
{
if (_balloonClick == null)
{
BridgeConnector.Socket.On("tray-balloon-click-event", () =>
{
_balloonClick();
});
BridgeConnector.Socket.Emit("register-tray-balloon-click");
}
_balloonClick += value;
}
remove
{
_balloonClick -= value;
}
}
private event Action _balloonClick;
/// <summary>
/// Windows: Emitted when the tray balloon is closed
/// because of timeout or user manually closes it.
/// </summary>
public event Action OnBalloonClosed
{
add
{
if (_balloonClosed == null)
{
BridgeConnector.Socket.On("tray-balloon-closed-event", () =>
{
_balloonClosed();
});
BridgeConnector.Socket.Emit("register-tray-balloon-closed");
}
_balloonClosed += value;
}
remove
{
_balloonClosed -= value;
}
}
private event Action _balloonClosed;
// TODO: Implement macOS Events
private static Tray _tray;
internal Tray() { }
@@ -42,6 +212,91 @@ namespace ElectronNET.API
});
}
/// <summary>
/// Destroys the tray icon immediately.
/// </summary>
public void Destroy()
{
BridgeConnector.Socket.Emit("tray-destroy");
}
/// <summary>
/// Sets the image associated with this tray icon.
/// </summary>
/// <param name="image"></param>
public void SetImage(string image)
{
BridgeConnector.Socket.Emit("tray-setImage", image);
}
/// <summary>
/// Sets the image associated with this tray icon when pressed on macOS.
/// </summary>
/// <param name="image"></param>
public void SetPressedImage(string image)
{
BridgeConnector.Socket.Emit("tray-setPressedImage", image);
}
/// <summary>
/// Sets the hover text for this tray icon.
/// </summary>
/// <param name="toolTip"></param>
public void SetToolTip(string toolTip)
{
BridgeConnector.Socket.Emit("tray-setToolTip", toolTip);
}
/// <summary>
/// macOS: Sets the title displayed aside of the tray icon in the status bar.
/// </summary>
/// <param name="title"></param>
public void SetTitle(string title)
{
BridgeConnector.Socket.Emit("tray-setTitle", title);
}
/// <summary>
/// macOS: Sets when the trays icon background becomes highlighted (in blue).
///
/// Note: You can use highlightMode with a BrowserWindow by toggling between
/// 'never' and 'always' modes when the window visibility changes.
/// </summary>
/// <param name="highlightMode"></param>
public void SetHighlightMode(HighlightMode highlightMode)
{
BridgeConnector.Socket.Emit("tray-setHighlightMode", highlightMode.ToString());
}
/// <summary>
/// Windows: Displays a tray balloon.
/// </summary>
/// <param name="options"></param>
public void DisplayBalloon(DisplayBalloonOptions options)
{
BridgeConnector.Socket.Emit("tray-displayBalloon", JObject.FromObject(options, _jsonSerializer));
}
/// <summary>
/// Whether the tray icon is destroyed.
/// </summary>
/// <returns></returns>
public Task<bool> IsDestroyedAsync()
{
var taskCompletionSource = new TaskCompletionSource<bool>();
BridgeConnector.Socket.On("tray-isDestroyedCompleted", (isDestroyed) =>
{
BridgeConnector.Socket.Off("tray-isDestroyedCompleted");
taskCompletionSource.SetResult((bool)isDestroyed);
});
BridgeConnector.Socket.Emit("tray-isDestroyed");
return taskCompletionSource.Task;
}
private JsonSerializer _jsonSerializer = new JsonSerializer()
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),

View File

@@ -4,6 +4,48 @@ var electron_1 = require("electron");
var path = require('path');
var tray;
module.exports = function (socket) {
socket.on('register-tray-click', function () {
if (tray) {
tray.on('click', function (event, bounds) {
socket.emit('tray-click-event', [event.__proto__, bounds]);
});
}
});
socket.on('register-tray-right-click', function () {
if (tray) {
tray.on('right-click', function (event, bounds) {
socket.emit('tray-right-click-event', [event.__proto__, bounds]);
});
}
});
socket.on('register-tray-double-click', function () {
if (tray) {
tray.on('double-click', function (event, bounds) {
socket.emit('tray-double-click-event', [event.__proto__, bounds]);
});
}
});
socket.on('register-tray-balloon-show', function () {
if (tray) {
tray.on('balloon-show', function () {
socket.emit('tray-balloon-show-event');
});
}
});
socket.on('register-tray-balloon-click', function () {
if (tray) {
tray.on('balloon-click', function () {
socket.emit('tray-balloon-click-event');
});
}
});
socket.on('register-tray-balloon-closed', function () {
if (tray) {
tray.on('balloon-closed', function () {
socket.emit('tray-balloon-closed-event');
});
}
});
socket.on('create-tray', function (image, menuItems) {
var menu = electron_1.Menu.buildFromTemplate(menuItems);
addMenuItemClickConnector(menu.items, function (id) {
@@ -13,6 +55,48 @@ module.exports = function (socket) {
tray = new electron_1.Tray(imagePath);
tray.setContextMenu(menu);
});
socket.on('tray-destroy', function () {
if (tray) {
tray.destroy();
}
});
socket.on('tray-setImage', function (image) {
if (tray) {
tray.setImage(image);
}
});
socket.on('tray-setPressedImage', function (image) {
if (tray) {
var img = electron_1.nativeImage.createFromPath(image);
tray.setPressedImage(img);
}
});
socket.on('tray-setToolTip', function (toolTip) {
if (tray) {
tray.setToolTip(toolTip);
}
});
socket.on('tray-setTitle', function (title) {
if (tray) {
tray.setTitle(title);
}
});
socket.on('tray-setHighlightMode', function (mode) {
if (tray) {
tray.setHighlightMode(mode);
}
});
socket.on('tray-displayBalloon', function (options) {
if (tray) {
tray.displayBalloon(options);
}
});
socket.on('tray-isDestroyed', function () {
if (tray) {
var isDestroyed = tray.isDestroyed();
socket.emit('tray-isDestroyedCompleted', isDestroyed);
}
});
function addMenuItemClickConnector(menuItems, callback) {
menuItems.forEach(function (item) {
if (item.submenu && item.submenu.items.length > 0) {

View File

@@ -1 +1 @@
{"version":3,"file":"tray.js","sourceRoot":"","sources":["tray.ts"],"names":[],"mappings":";;AAAA,qCAAsC;AACtC,IAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAC7B,IAAI,IAAI,CAAC;AAET,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB;IACrC,MAAM,CAAC,EAAE,CAAC,aAAa,EAAE,UAAC,KAAK,EAAE,SAAS;QACtC,IAAM,IAAI,GAAG,eAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAE/C,yBAAyB,CAAC,IAAI,CAAC,KAAK,EAAE,UAAC,EAAE;YACrC,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,IAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QAExE,IAAI,GAAG,IAAI,eAAI,CAAC,SAAS,CAAC,CAAC;QAC3B,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,mCAAmC,SAAS,EAAE,QAAQ;QAClD,SAAS,CAAC,OAAO,CAAC,UAAC,IAAI;YACnB,EAAE,CAAA,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC/C,yBAAyB,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YAC5D,CAAC;YAED,EAAE,CAAA,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBACzB,IAAI,CAAC,KAAK,GAAG,cAAQ,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9C,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;AACL,CAAC,CAAA"}
{"version":3,"file":"tray.js","sourceRoot":"","sources":["tray.ts"],"names":[],"mappings":"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"}

View File

@@ -1,8 +1,56 @@
import { Menu, Tray } from "electron";
import { Menu, Tray, nativeImage } from "electron";
const path = require('path');
let tray;
let tray: Electron.Tray;
module.exports = (socket: SocketIO.Server) => {
socket.on('register-tray-click', () => {
if (tray) {
tray.on('click', (event, bounds) => {
socket.emit('tray-click-event', [(<any>event).__proto__, bounds]);
});
}
});
socket.on('register-tray-right-click', () => {
if (tray) {
tray.on('right-click', (event, bounds) => {
socket.emit('tray-right-click-event', [(<any>event).__proto__, bounds]);
});
}
});
socket.on('register-tray-double-click', () => {
if (tray) {
tray.on('double-click', (event, bounds) => {
socket.emit('tray-double-click-event', [(<any>event).__proto__, bounds]);
});
}
});
socket.on('register-tray-balloon-show', () => {
if (tray) {
tray.on('balloon-show', () => {
socket.emit('tray-balloon-show-event');
});
}
});
socket.on('register-tray-balloon-click', () => {
if (tray) {
tray.on('balloon-click', () => {
socket.emit('tray-balloon-click-event');
});
}
});
socket.on('register-tray-balloon-closed', () => {
if (tray) {
tray.on('balloon-closed', () => {
socket.emit('tray-balloon-closed-event');
});
}
});
socket.on('create-tray', (image, menuItems) => {
const menu = Menu.buildFromTemplate(menuItems);
@@ -16,13 +64,63 @@ module.exports = (socket: SocketIO.Server) => {
tray.setContextMenu(menu);
});
socket.on('tray-destroy', () => {
if (tray) {
tray.destroy();
}
});
socket.on('tray-setImage', (image) => {
if (tray) {
tray.setImage(image);
}
});
socket.on('tray-setPressedImage', (image) => {
if (tray) {
let img = nativeImage.createFromPath(image);
tray.setPressedImage(img);
}
});
socket.on('tray-setToolTip', (toolTip) => {
if (tray) {
tray.setToolTip(toolTip);
}
});
socket.on('tray-setTitle', (title) => {
if (tray) {
tray.setTitle(title);
}
});
socket.on('tray-setHighlightMode', (mode) => {
if (tray) {
tray.setHighlightMode(mode);
}
});
socket.on('tray-displayBalloon', (options) => {
if (tray) {
tray.displayBalloon(options);
}
});
socket.on('tray-isDestroyed', () => {
if (tray) {
let isDestroyed = tray.isDestroyed();
socket.emit('tray-isDestroyedCompleted', isDestroyed);
}
});
function addMenuItemClickConnector(menuItems, callback) {
menuItems.forEach((item) => {
if(item.submenu && item.submenu.items.length > 0) {
if (item.submenu && item.submenu.items.length > 0) {
addMenuItemClickConnector(item.submenu.items, callback);
}
if("id" in item && item.id) {
if ("id" in item && item.id) {
item.click = () => { callback(item.id); };
}
});

View File

@@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Threading;