From a4aa1dfae3e361fb2cc6922a755c43134a341806 Mon Sep 17 00:00:00 2001 From: Gregor Biswanger Date: Sun, 15 Oct 2017 21:39:52 +0200 Subject: [PATCH] implement BrowserWindow-API functions --- ElectronNET.API/BrowserWindow.cs | 598 +++++++++++++++++- .../BrowserWindowConstructorOptions.cs | 244 ------- .../Entities/BrowserWindowOptions.cs | 235 +++++++ ElectronNET.API/Entities/Rectangle.cs | 10 + ElectronNET.API/Entities/Size.cs | 9 + .../Extensions/MenuItemExtensions.cs | 53 ++ ElectronNET.API/IpcMain.cs | 17 +- ElectronNET.API/Menu.cs | 45 +- ElectronNET.API/Tray.cs | 12 + ElectronNET.API/WindowManager.cs | 6 +- ElectronNET.Host/api/browserWindows.js | 66 +- ElectronNET.Host/api/browserWindows.js.map | 2 +- ElectronNET.Host/api/browserWindows.ts | 200 +++++- ElectronNET.Host/api/dialog.js | 4 +- ElectronNET.Host/api/dialog.js.map | 2 +- ElectronNET.Host/api/dialog.ts | 4 +- ElectronNET.Host/api/ipc.js | 19 +- ElectronNET.Host/api/ipc.js.map | 2 +- ElectronNET.Host/api/ipc.ts | 8 +- ElectronNET.Host/api/tray.js | 13 + ElectronNET.Host/api/tray.js.map | 2 +- ElectronNET.Host/api/tray.ts | 16 + ElectronNET.Host/main.js | 4 +- .../Controllers/HomeController.cs | 15 +- ElectronNET.WebApp/Startup.cs | 17 +- 25 files changed, 1261 insertions(+), 342 deletions(-) delete mode 100644 ElectronNET.API/Entities/BrowserWindowConstructorOptions.cs create mode 100644 ElectronNET.API/Entities/Rectangle.cs create mode 100644 ElectronNET.API/Entities/Size.cs create mode 100644 ElectronNET.API/Extensions/MenuItemExtensions.cs diff --git a/ElectronNET.API/BrowserWindow.cs b/ElectronNET.API/BrowserWindow.cs index 55fdaa8..790f0f0 100644 --- a/ElectronNET.API/BrowserWindow.cs +++ b/ElectronNET.API/BrowserWindow.cs @@ -1,4 +1,10 @@ -namespace ElectronNET.API +using ElectronNET.API.Entities; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; +using System.Threading.Tasks; + +namespace ElectronNET.API { public class BrowserWindow { @@ -8,9 +14,599 @@ Id = id; } + /// + /// Force closing the window, the unload and beforeunload event won’t be + /// emitted for the web page, and close event will also not be emitted + /// for this window, but it guarantees the closed event will be emitted. + /// + public void Destroy() + { + BridgeConnector.Socket.Emit("browserWindow-destroy", Id); + } + + /// + /// Try to close the window. This has the same effect as a user manually + /// clicking the close button of the window. The web page may cancel the close though. + /// + public void Close() + { + BridgeConnector.Socket.Emit("browserWindow-close", Id); + } + + /// + /// Focuses on the window. + /// + public void Focus() + { + BridgeConnector.Socket.Emit("browserWindow-focus", Id); + } + + /// + /// Removes focus from the window. + /// + public void Blur() + { + BridgeConnector.Socket.Emit("browserWindow-blur", Id); + } + + /// + /// Whether the window is focused. + /// + /// + public Task IsFocusedAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-isFocused-completed", (isFocused) => { + BridgeConnector.Socket.Off("browserWindow-isFocused-completed"); + + taskCompletionSource.SetResult((bool)isFocused); + }); + + BridgeConnector.Socket.Emit("browserWindow-isFocused", Id); + + return taskCompletionSource.Task; + } + + /// + /// Whether the window is destroyed. + /// + /// + public Task IsDestroyedAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-isDestroyed-completed", (isDestroyed) => { + BridgeConnector.Socket.Off("browserWindow-isDestroyed-completed"); + + taskCompletionSource.SetResult((bool)isDestroyed); + }); + + BridgeConnector.Socket.Emit("browserWindow-isDestroyed", Id); + + return taskCompletionSource.Task; + } + + /// + /// Shows and gives focus to the window. + /// + public void Show() + { + BridgeConnector.Socket.Emit("browserWindow-show", Id); + } + + /// + /// Shows the window but doesn’t focus on it. + /// + public void ShowInactive() + { + BridgeConnector.Socket.Emit("browserWindow-showInactive", Id); + } + + /// + /// Hides the window. + /// + public void Hide() + { + BridgeConnector.Socket.Emit("browserWindow-hide", Id); + } + + /// + /// Whether the window is visible to the user. + /// + /// + public Task IsVisibleAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-isVisible-completed", (isVisible) => { + BridgeConnector.Socket.Off("browserWindow-isVisible-completed"); + + taskCompletionSource.SetResult((bool)isVisible); + }); + + BridgeConnector.Socket.Emit("browserWindow-isVisible", Id); + + return taskCompletionSource.Task; + } + + /// + /// Whether current window is a modal window. + /// + /// + public Task IsModalAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-isModal-completed", (isModal) => { + BridgeConnector.Socket.Off("browserWindow-isModal-completed"); + + taskCompletionSource.SetResult((bool)isModal); + }); + + BridgeConnector.Socket.Emit("browserWindow-isModal", Id); + + return taskCompletionSource.Task; + } + + /// + /// Maximizes the window. This will also show (but not focus) the window if it isn’t being displayed already. + /// + public void Maximize() + { + BridgeConnector.Socket.Emit("browserWindow-maximize", Id); + } + + /// + /// Unmaximizes the window. + /// + public void Unmaximize() + { + BridgeConnector.Socket.Emit("browserWindow-unmaximize", Id); + } + + /// + /// Whether the window is maximized. + /// + /// + public Task IsMaximizedAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-isMaximized-completed", (isMaximized) => { + BridgeConnector.Socket.Off("browserWindow-isMaximized-completed"); + + taskCompletionSource.SetResult((bool)isMaximized); + }); + + BridgeConnector.Socket.Emit("browserWindow-isMaximized", Id); + + return taskCompletionSource.Task; + } + + /// + /// Minimizes the window. On some platforms the minimized window will be shown in the Dock. + /// public void Minimize() { BridgeConnector.Socket.Emit("browserWindow-minimize", Id); } + + /// + /// Restores the window from minimized state to its previous state. + /// + public void Restore() + { + BridgeConnector.Socket.Emit("browserWindow-restore", Id); + } + + /// + /// Whether the window is minimized. + /// + /// + public Task IsMinimizedAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-isMinimized-completed", (isMinimized) => { + BridgeConnector.Socket.Off("browserWindow-isMinimized-completed"); + + taskCompletionSource.SetResult((bool)isMinimized); + }); + + BridgeConnector.Socket.Emit("browserWindow-isMinimized", Id); + + return taskCompletionSource.Task; + } + + /// + /// Sets whether the window should be in fullscreen mode. + /// + public void SetFullScreen(bool flag) + { + BridgeConnector.Socket.Emit("browserWindow-setFullScreen", Id, flag); + } + + /// + /// Whether the window is in fullscreen mode. + /// + /// + public Task IsFullScreenAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-isFullScreen-completed", (isFullScreen) => { + BridgeConnector.Socket.Off("browserWindow-isFullScreen-completed"); + + taskCompletionSource.SetResult((bool)isFullScreen); + }); + + BridgeConnector.Socket.Emit("browserWindow-isFullScreen", Id); + + return taskCompletionSource.Task; + } + + /// + /// This will make a window maintain an aspect ratio. The extra size allows a developer to have space, + /// specified in pixels, not included within the aspect ratio calculations. This API already takes into + /// account the difference between a window’s size and its content size. + /// + /// Consider a normal window with an HD video player and associated controls.Perhaps there are 15 pixels + /// of controls on the left edge, 25 pixels of controls on the right edge and 50 pixels of controls below + /// the player. In order to maintain a 16:9 aspect ratio (standard aspect ratio for HD @1920x1080) within + /// the player itself we would call this function with arguments of 16/9 and[40, 50]. The second argument + /// doesn’t care where the extra width and height are within the content view–only that they exist. Just + /// sum any extra width and height areas you have within the overall content view. + /// + /// The aspect ratio to maintain for some portion of the content view. + /// The extra size not to be included while maintaining the aspect ratio. + public void SetAspectRatio(int aspectRatio, Size extraSize) + { + BridgeConnector.Socket.Emit("browserWindow-setAspectRatio", Id, aspectRatio, JObject.FromObject(extraSize, _jsonSerializer)); + } + + /// + /// Uses Quick Look to preview a file at a given path. + /// + /// The absolute path to the file to preview with QuickLook. This is important as + /// Quick Look uses the file name and file extension on the path to determine the content type of the + /// file to open. + public void PreviewFile(string path) + { + BridgeConnector.Socket.Emit("browserWindow-previewFile", Id, path); + } + + /// + /// Uses Quick Look to preview a file at a given path. + /// + /// The absolute path to the file to preview with QuickLook. This is important as + /// Quick Look uses the file name and file extension on the path to determine the content type of the + /// file to open. + /// The name of the file to display on the Quick Look modal view. This is + /// purely visual and does not affect the content type of the file. Defaults to path. + public void PreviewFile(string path, string displayname) + { + BridgeConnector.Socket.Emit("browserWindow-previewFile", Id, path, displayname); + } + + /// + /// Closes the currently open Quick Look panel. + /// + public void CloseFilePreview() + { + BridgeConnector.Socket.Emit("browserWindow-closeFilePreview", Id); + } + + /// + /// Resizes and moves the window to the supplied bounds + /// + /// + public void SetBounds(Rectangle bounds) + { + BridgeConnector.Socket.Emit("browserWindow-setBounds", Id, JObject.FromObject(bounds, _jsonSerializer)); + } + + /// + /// Resizes and moves the window to the supplied bounds + /// + /// + /// + public void SetBounds(Rectangle bounds, bool animate) + { + BridgeConnector.Socket.Emit("browserWindow-setBounds", Id, JObject.FromObject(bounds, _jsonSerializer), animate); + } + + public Task GetBoundsAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-getBounds-completed", (getBounds) => { + BridgeConnector.Socket.Off("browserWindow-getBounds-completed"); + + taskCompletionSource.SetResult(((JObject)getBounds).ToObject()); + }); + + BridgeConnector.Socket.Emit("browserWindow-getBounds", Id); + + return taskCompletionSource.Task; + } + + /// + /// Resizes and moves the window’s client area (e.g. the web page) to the supplied bounds. + /// + /// + public void SetContentBounds(Rectangle bounds) + { + BridgeConnector.Socket.Emit("browserWindow-setContentBounds", Id, JObject.FromObject(bounds, _jsonSerializer)); + } + + /// + /// Resizes and moves the window’s client area (e.g. the web page) to the supplied bounds. + /// + /// + /// + public void SetContentBounds(Rectangle bounds, bool animate) + { + BridgeConnector.Socket.Emit("browserWindow-setContentBounds", Id, JObject.FromObject(bounds, _jsonSerializer), animate); + } + + public Task GetContentBoundsAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-getContentBounds-completed", (getContentBounds) => { + BridgeConnector.Socket.Off("browserWindow-getContentBounds-completed"); + + taskCompletionSource.SetResult(((JObject)getContentBounds).ToObject()); + }); + + BridgeConnector.Socket.Emit("browserWindow-getContentBounds", Id); + + return taskCompletionSource.Task; + } + + /// + /// Resizes the window to width and height. + /// + /// + /// + /// + public void SetSize(int width, int height) + { + BridgeConnector.Socket.Emit("browserWindow-setSize", Id, width, height); + } + + /// + /// Resizes the window to width and height. + /// + /// + /// + /// + public void SetSize(int width, int height, bool animate) + { + BridgeConnector.Socket.Emit("browserWindow-setSize", Id, width, height, animate); + } + + /// + /// Contains the window’s width and height. + /// + /// + public Task GetSizeAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-getSize-completed", (size) => { + BridgeConnector.Socket.Off("browserWindow-getSize-completed"); + + taskCompletionSource.SetResult(((JArray)size).ToObject()); + }); + + BridgeConnector.Socket.Emit("browserWindow-getSize", Id); + + return taskCompletionSource.Task; + } + + /// + /// Resizes the window’s client area (e.g. the web page) to width and height. + /// + /// + /// + /// + public void SetContentSize(int width, int height) + { + BridgeConnector.Socket.Emit("browserWindow-setContentSize", Id, width, height); + } + + /// + /// Resizes the window’s client area (e.g. the web page) to width and height. + /// + /// + /// + /// + public void SetContentSize(int width, int height, bool animate) + { + BridgeConnector.Socket.Emit("browserWindow-setContentSize", Id, width, height, animate); + } + + /// + /// Contains the window’s client area’s width and height. + /// + /// + public Task GetContentSizeAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-getContentSize-completed", (size) => { + BridgeConnector.Socket.Off("browserWindow-getContentSize-completed"); + + taskCompletionSource.SetResult(((JArray)size).ToObject()); + }); + + BridgeConnector.Socket.Emit("browserWindow-getContentSize", Id); + + return taskCompletionSource.Task; + } + + /// + /// Sets the minimum size of window to width and height. + /// + /// + /// + public void SetMinimumSize(int width, int height) + { + BridgeConnector.Socket.Emit("browserWindow-setMinimumSize", Id, width, height); + } + + /// + /// Contains the window’s minimum width and height. + /// + /// + public Task GetMinimumSizeAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-getMinimumSize-completed", (size) => { + BridgeConnector.Socket.Off("browserWindow-getMinimumSize-completed"); + + taskCompletionSource.SetResult(((JArray)size).ToObject()); + }); + + BridgeConnector.Socket.Emit("browserWindow-getMinimumSize", Id); + + return taskCompletionSource.Task; + } + + /// + /// Sets the maximum size of window to width and height. + /// + /// + /// + public void SetMaximumSize(int width, int height) + { + BridgeConnector.Socket.Emit("browserWindow-setMaximumSize", Id, width, height); + } + + /// + /// Contains the window’s maximum width and height. + /// + /// + public Task GetMaximumSizeAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-getMaximumSize-completed", (size) => { + BridgeConnector.Socket.Off("browserWindow-getMaximumSize-completed"); + + taskCompletionSource.SetResult(((JArray)size).ToObject()); + }); + + BridgeConnector.Socket.Emit("browserWindow-getMaximumSize", Id); + + return taskCompletionSource.Task; + } + + /// + /// Sets whether the window can be manually resized by user. + /// + /// + public void SetResizable(bool resizable) + { + BridgeConnector.Socket.Emit("browserWindow-setResizable", Id, resizable); + } + + /// + /// Whether the window can be manually resized by user. + /// + /// + public Task IsResizableAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-isResizable-completed", (resizable) => { + BridgeConnector.Socket.Off("browserWindow-isResizable-completed"); + + taskCompletionSource.SetResult((bool)resizable); + }); + + BridgeConnector.Socket.Emit("browserWindow-isResizable", Id); + + return taskCompletionSource.Task; + } + + /// + /// Sets whether the window can be moved by user. On Linux does nothing. + /// + /// + public void SetMovable(bool movable) + { + BridgeConnector.Socket.Emit("browserWindow-setMovable", Id, movable); + } + + /// + /// Whether the window can be moved by user. + /// + /// On Linux always returns true. + /// + /// On Linux always returns true. + public Task IsMovableAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-isMovable-completed", (movable) => { + BridgeConnector.Socket.Off("browserWindow-isMovable-completed"); + + taskCompletionSource.SetResult((bool)movable); + }); + + BridgeConnector.Socket.Emit("browserWindow-isMovable", Id); + + return taskCompletionSource.Task; + } + + /// + /// Sets whether the window can be manually minimized by user. On Linux does nothing. + /// + /// + public void SetMinimizable(bool minimizable) + { + BridgeConnector.Socket.Emit("browserWindow-setMinimizable", Id, minimizable); + } + + /// + /// Whether the window can be manually minimized by user. + /// + /// On Linux always returns true. + /// + /// On Linux always returns true. + public Task IsMinimizableAsync() + { + var taskCompletionSource = new TaskCompletionSource(); + + BridgeConnector.Socket.On("browserWindow-isMinimizable-completed", (minimizable) => { + BridgeConnector.Socket.Off("browserWindow-isMinimizable-completed"); + + taskCompletionSource.SetResult((bool)minimizable); + }); + + BridgeConnector.Socket.Emit("browserWindow-isMinimizable", Id); + + return taskCompletionSource.Task; + } + + /// + /// Sets whether the window can be manually maximized by user. On Linux does nothing. + /// + /// + public void SetMaximizable(bool maximizable) + { + BridgeConnector.Socket.Emit("browserWindow-setMaximizable", Id, maximizable); + } + + private JsonSerializer _jsonSerializer = new JsonSerializer() + { + ContractResolver = new CamelCasePropertyNamesContractResolver(), + NullValueHandling = NullValueHandling.Ignore, + DefaultValueHandling = DefaultValueHandling.Ignore + }; } } diff --git a/ElectronNET.API/Entities/BrowserWindowConstructorOptions.cs b/ElectronNET.API/Entities/BrowserWindowConstructorOptions.cs deleted file mode 100644 index 2e6f805..0000000 --- a/ElectronNET.API/Entities/BrowserWindowConstructorOptions.cs +++ /dev/null @@ -1,244 +0,0 @@ -namespace ElectronNET.API.Entities -{ - public class BrowserWindowConstructorOptions - { - /// - /// Window's width in pixels. Default is 800. - /// - public int Width { get; set; } - - /// - /// Window's height in pixels. Default is 600. - /// - public int Height { get; set; } - - /// - /// ( if y is used) Window's left offset from screen. Default is to center the - /// window. - /// - public int X { get; set; } - - /// - /// ( if x is used) Window's top offset from screen. Default is to center the - /// window. - /// - public int Y { get; set; } - - /// - /// The width and height would be used as web page's size, which means the actual - /// window's size will include window frame's size and be slightly larger.Default - /// is false. - /// - public bool UseContentSize { get; set; } - - /// - /// Show window in the center of the screen. - /// - public bool Center { get; set; } - - /// - /// Window's minimum width. Default is 0. - /// - public int MinWidth { get; set; } - - /// - /// Window's minimum height. Default is 0. - /// - public int MinHeight { get; set; } - - /// - /// Window's maximum width. Default is no limit. - /// - public int MaxWidth { get; set; } - - /// - /// Window's maximum height. Default is no limit. - /// - public int MaxHeight { get; set; } - - /// - /// Whether window is resizable. Default is true. - /// - public bool Resizable { get; set; } - - /// - /// Whether window is movable. This is not implemented on Linux. Default is true. - /// - public bool Movable { get; set; } - - /// - /// Whether window is minimizable. This is not implemented on Linux. Default is true. - /// - public bool Minimizable { get; set; } - - /// - /// Whether window is maximizable. This is not implemented on Linux. Default is true. - /// - public bool Maximizable { get; set; } - - /// - /// Whether window is closable. This is not implemented on Linux. Default is true. - /// - public bool Closable { get; set; } - - /// - /// Whether the window can be focused. Default is true. On Windows setting - /// focusable: false also implies setting skipTaskbar: true. On Linux setting - /// focusable: false makes the window stop interacting with wm, so the window will - /// always stay on top in all workspaces. - /// - public bool Focusable { get; set; } - - /// - /// Whether the window should always stay on top of other windows. Default is false. - /// - public bool AlwaysOnTop { get; set; } - - /// - /// Whether the window should show in fullscreen. When explicitly set to false the - /// fullscreen button will be hidden or disabled on macOS.Default is false. - /// - public bool Fullscreen { get; set; } - - /// - /// Whether the window can be put into fullscreen mode. On macOS, also whether the - /// maximize/zoom button should toggle full screen mode or maximize window.Default - /// is true. - /// - public bool Fullscreenable { get; set; } - - /// - /// Whether to show the window in taskbar. Default is false. - /// - public bool SkipTaskbar { get; set; } - - /// - /// The kiosk mode. Default is false. - /// - public bool Kiosk { get; set; } - - /// - /// Default window title. Default is "Electron.NET". - /// - public string Title { get; set; } = "Electron.NET"; - - /// - /// The window icon. On Windows it is recommended to use ICO icons to get best - /// visual effects, you can also leave it undefined so the executable's icon will be used. - /// - public string Icon { get; set; } - - /// - /// Whether window should be shown when created. Default is true. - /// - public bool Show { get; set; } - - /// - /// Specify false to create a . Default is true. - /// - public bool Frame { get; set; } - - /// - /// Whether this is a modal window. This only works when the window is a child - /// window.Default is false. - /// - public bool Modal { get; set; } - - /// - /// Whether the web view accepts a single mouse-down event that simultaneously - /// activates the window.Default is false. - /// - public bool AcceptFirstMouse { get; set; } - - /// - /// Whether to hide cursor when typing. Default is false. - /// - public bool DisableAutoHideCursor { get; set; } - - /// - /// Auto hide the menu bar unless the Alt key is pressed. Default is false. - /// - public bool AutoHideMenuBar { get; set; } - - /// - /// Enable the window to be resized larger than screen. Default is false. - /// - public bool EnableLargerThanScreen { get; set; } - - /// - /// Window's background color as Hexadecimal value, like #66CD00 or #FFF or - /// #80FFFFFF (alpha is supported). Default is #FFF (white). - /// - public string BackgroundColor { get; set; } - - /// - /// Whether window should have a shadow. This is only implemented on macOS. Default - /// is true. - /// - public bool HasShadow { get; set; } - - /// - /// Forces using dark theme for the window, only works on some GTK+3 desktop - /// environments.Default is false. - /// - public bool DarkTheme { get; set; } - - /// - /// Makes the window . Default is false. - /// - public bool Transparent { get; set; } - - /// - /// The type of window, default is normal window. See more about this below. - /// - public string Type { get; set; } - - /// - /// The style of window title bar. Default is default. Possible values are: - /// 'default' | 'hidden' | 'hidden-inset' | 'hiddenInset' | 'customButtonsOnHover' - /// - public string TitleBarStyle { get; set; } - - /// - /// Shows the title in the tile bar in full screen mode on macOS for all - /// titleBarStyle options.Default is false. - /// - public bool FullscreenWindowTitle { get; set; } - - /// - /// Use WS_THICKFRAME style for frameless windows on Windows, which adds standard - /// window frame.Setting it to false will remove window shadow and window - /// animations.Default is true. - /// - public bool ThickFrame { get; set; } - - /// - /// Add a type of vibrancy effect to the window, only on macOS. Can be - /// appearance-based, light, dark, titlebar, selection, menu, popover, sidebar, - /// medium-light or ultra-dark. - /// - public string Vibrancy { get; set; } - - /// - /// Controls the behavior on macOS when option-clicking the green stoplight button - /// on the toolbar or by clicking the Window > Zoom menu item.If true, the window - /// will grow to the preferred width of the web page when zoomed, false will cause - /// it to zoom to the width of the screen.This will also affect the behavior when - /// calling maximize() directly.Default is false. - /// - public bool ZoomToPageWidth { get; set; } - - /// - /// Tab group name, allows opening the window as a native tab on macOS 10.12+. - /// Windows with the same tabbing identifier will be grouped together.This also - /// adds a native new tab button to your window's tab bar and allows your app and - /// window to receive the new-window-for-tab event. - /// - public string TabbingIdentifier { get; set; } - - /// - /// Settings of web page's features. - /// - public WebPreferences WebPreferences { get; set; } - } -} diff --git a/ElectronNET.API/Entities/BrowserWindowOptions.cs b/ElectronNET.API/Entities/BrowserWindowOptions.cs index 8a817e7..9e6ed33 100644 --- a/ElectronNET.API/Entities/BrowserWindowOptions.cs +++ b/ElectronNET.API/Entities/BrowserWindowOptions.cs @@ -2,8 +2,243 @@ { public class BrowserWindowOptions { + /// + /// Window's width in pixels. Default is 800. + /// public int Width { get; set; } + + /// + /// Window's height in pixels. Default is 600. + /// public int Height { get; set; } + + /// + /// ( if y is used) Window's left offset from screen. Default is to center the + /// window. + /// + public int X { get; set; } + + /// + /// ( if x is used) Window's top offset from screen. Default is to center the + /// window. + /// + public int Y { get; set; } + + /// + /// The width and height would be used as web page's size, which means the actual + /// window's size will include window frame's size and be slightly larger.Default + /// is false. + /// + public bool UseContentSize { get; set; } + + /// + /// Show window in the center of the screen. + /// + public bool Center { get; set; } + + /// + /// Window's minimum width. Default is 0. + /// + public int MinWidth { get; set; } + + /// + /// Window's minimum height. Default is 0. + /// + public int MinHeight { get; set; } + + /// + /// Window's maximum width. Default is no limit. + /// + public int MaxWidth { get; set; } + + /// + /// Window's maximum height. Default is no limit. + /// + public int MaxHeight { get; set; } + + /// + /// Whether window is resizable. Default is true. + /// + public bool Resizable { get; set; } + + /// + /// Whether window is movable. This is not implemented on Linux. Default is true. + /// + public bool Movable { get; set; } + + /// + /// Whether window is minimizable. This is not implemented on Linux. Default is true. + /// + public bool Minimizable { get; set; } + + /// + /// Whether window is maximizable. This is not implemented on Linux. Default is true. + /// + public bool Maximizable { get; set; } + + /// + /// Whether window is closable. This is not implemented on Linux. Default is true. + /// + public bool Closable { get; set; } + + /// + /// Whether the window can be focused. Default is true. On Windows setting + /// focusable: false also implies setting skipTaskbar: true. On Linux setting + /// focusable: false makes the window stop interacting with wm, so the window will + /// always stay on top in all workspaces. + /// + public bool Focusable { get; set; } + + /// + /// Whether the window should always stay on top of other windows. Default is false. + /// + public bool AlwaysOnTop { get; set; } + + /// + /// Whether the window should show in fullscreen. When explicitly set to false the + /// fullscreen button will be hidden or disabled on macOS.Default is false. + /// + public bool Fullscreen { get; set; } + + /// + /// Whether the window can be put into fullscreen mode. On macOS, also whether the + /// maximize/zoom button should toggle full screen mode or maximize window.Default + /// is true. + /// + public bool Fullscreenable { get; set; } + + /// + /// Whether to show the window in taskbar. Default is false. + /// + public bool SkipTaskbar { get; set; } + + /// + /// The kiosk mode. Default is false. + /// + public bool Kiosk { get; set; } + + /// + /// Default window title. Default is "Electron.NET". + /// + public string Title { get; set; } = "Electron.NET"; + + /// + /// The window icon. On Windows it is recommended to use ICO icons to get best + /// visual effects, you can also leave it undefined so the executable's icon will be used. + /// + public string Icon { get; set; } + + /// + /// Whether window should be shown when created. Default is true. + /// public bool Show { get; set; } + + /// + /// Specify false to create a . Default is true. + /// + public bool Frame { get; set; } + + /// + /// Whether this is a modal window. This only works when the window is a child + /// window.Default is false. + /// + public bool Modal { get; set; } + + /// + /// Whether the web view accepts a single mouse-down event that simultaneously + /// activates the window.Default is false. + /// + public bool AcceptFirstMouse { get; set; } + + /// + /// Whether to hide cursor when typing. Default is false. + /// + public bool DisableAutoHideCursor { get; set; } + + /// + /// Auto hide the menu bar unless the Alt key is pressed. Default is false. + /// + public bool AutoHideMenuBar { get; set; } + + /// + /// Enable the window to be resized larger than screen. Default is false. + /// + public bool EnableLargerThanScreen { get; set; } + + /// + /// Window's background color as Hexadecimal value, like #66CD00 or #FFF or + /// #80FFFFFF (alpha is supported). Default is #FFF (white). + /// + public string BackgroundColor { get; set; } + + /// + /// Whether window should have a shadow. This is only implemented on macOS. Default + /// is true. + /// + public bool HasShadow { get; set; } + + /// + /// Forces using dark theme for the window, only works on some GTK+3 desktop + /// environments.Default is false. + /// + public bool DarkTheme { get; set; } + + /// + /// Makes the window . Default is false. + /// + public bool Transparent { get; set; } + + /// + /// The type of window, default is normal window. + /// + public string Type { get; set; } + + /// + /// The style of window title bar. Default is default. Possible values are: + /// 'default' | 'hidden' | 'hidden-inset' | 'hiddenInset' | 'customButtonsOnHover' + /// + public string TitleBarStyle { get; set; } + + /// + /// Shows the title in the tile bar in full screen mode on macOS for all + /// titleBarStyle options.Default is false. + /// + public bool FullscreenWindowTitle { get; set; } + + /// + /// Use WS_THICKFRAME style for frameless windows on Windows, which adds standard + /// window frame.Setting it to false will remove window shadow and window + /// animations.Default is true. + /// + public bool ThickFrame { get; set; } + + /// + /// Add a type of vibrancy effect to the window, only on macOS. Can be + /// appearance-based, light, dark, titlebar, selection, menu, popover, sidebar, + /// medium-light or ultra-dark. + /// + public string Vibrancy { get; set; } + + /// + /// Controls the behavior on macOS when option-clicking the green stoplight button + /// on the toolbar or by clicking the Window > Zoom menu item.If true, the window + /// will grow to the preferred width of the web page when zoomed, false will cause + /// it to zoom to the width of the screen.This will also affect the behavior when + /// calling maximize() directly.Default is false. + /// + public bool ZoomToPageWidth { get; set; } + + /// + /// Tab group name, allows opening the window as a native tab on macOS 10.12+. + /// Windows with the same tabbing identifier will be grouped together.This also + /// adds a native new tab button to your window's tab bar and allows your app and + /// window to receive the new-window-for-tab event. + /// + public string TabbingIdentifier { get; set; } + + /// + /// Settings of web page's features. + /// + public WebPreferences WebPreferences { get; set; } } } diff --git a/ElectronNET.API/Entities/Rectangle.cs b/ElectronNET.API/Entities/Rectangle.cs new file mode 100644 index 0000000..7e1a8eb --- /dev/null +++ b/ElectronNET.API/Entities/Rectangle.cs @@ -0,0 +1,10 @@ +namespace ElectronNET.API.Entities +{ + public class Rectangle + { + public int X { get; set; } + public int Y { get; set; } + public int Width { get; set; } + public int Height { get; set; } + } +} \ No newline at end of file diff --git a/ElectronNET.API/Entities/Size.cs b/ElectronNET.API/Entities/Size.cs new file mode 100644 index 0000000..459428a --- /dev/null +++ b/ElectronNET.API/Entities/Size.cs @@ -0,0 +1,9 @@ +namespace ElectronNET.API.Entities +{ + public class Size + { + public int Width { get; set; } + + public int Height { get; set; } + } +} \ No newline at end of file diff --git a/ElectronNET.API/Extensions/MenuItemExtensions.cs b/ElectronNET.API/Extensions/MenuItemExtensions.cs new file mode 100644 index 0000000..ba5f8b5 --- /dev/null +++ b/ElectronNET.API/Extensions/MenuItemExtensions.cs @@ -0,0 +1,53 @@ +using ElectronNET.API.Entities; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace ElectronNET.API.Extensions +{ + internal static class MenuItemExtensions + { + public static MenuItem[] AddMenuItemsId(this MenuItem[] menuItems) + { + for (int index = 0; index < menuItems.Length; index++) + { + var menuItem = menuItems[index]; + if (menuItem?.Submenu?.Length > 0) + { + AddMenuItemsId(menuItem.Submenu); + } + + if (string.IsNullOrEmpty(menuItem.Role) && + string.IsNullOrEmpty(menuItem.Id)) + { + menuItem.Id = Guid.NewGuid().ToString(); + } + } + + return menuItems; + } + + public static MenuItem GetMenuItem(this List menuItems, string id) + { + MenuItem result = new MenuItem(); + + foreach (var item in menuItems) + { + if (item.Id == id) + { + result = item; + } + else if (item?.Submenu?.Length > 0) + { + var menuItem = GetMenuItem(item.Submenu.ToList(), id); + if (menuItem.Id == id) + { + result = menuItem; + } + } + } + + return result; + } + } +} diff --git a/ElectronNET.API/IpcMain.cs b/ElectronNET.API/IpcMain.cs index 5f3dc62..b0f56f9 100644 --- a/ElectronNET.API/IpcMain.cs +++ b/ElectronNET.API/IpcMain.cs @@ -1,4 +1,7 @@ -using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; +using System; namespace ElectronNET.API { @@ -63,11 +66,19 @@ namespace ElectronNET.API /// no functions or prototype chain will be included. The renderer process handles it by /// listening for channel with ipcRenderer module. /// + /// BrowserWindow with channel. /// Channelname. /// Arguments data. - public void Send(string channel, params object[] data) + public void Send(BrowserWindow browserWindow, string channel, params object[] data) { - BridgeConnector.Socket.Emit("sendToIpcRenderer", channel, data); + BridgeConnector.Socket.Emit("sendToIpcRenderer", JObject.FromObject(browserWindow, _jsonSerializer), channel, data); } + + private JsonSerializer _jsonSerializer = new JsonSerializer() + { + ContractResolver = new CamelCasePropertyNamesContractResolver(), + NullValueHandling = NullValueHandling.Ignore, + DefaultValueHandling = DefaultValueHandling.Ignore + }; } } \ No newline at end of file diff --git a/ElectronNET.API/Menu.cs b/ElectronNET.API/Menu.cs index 4a82028..cfd1af5 100644 --- a/ElectronNET.API/Menu.cs +++ b/ElectronNET.API/Menu.cs @@ -5,6 +5,7 @@ using Newtonsoft.Json.Serialization; using System.Collections.Generic; using System; using System.Linq; +using ElectronNET.API.Extensions; namespace ElectronNET.API { @@ -32,56 +33,16 @@ namespace ElectronNET.API public void SetApplicationMenu(MenuItem[] menuItems) { - AddMenuItemsId(menuItems); + menuItems.AddMenuItemsId(); BridgeConnector.Socket.Emit("menu-setApplicationMenu", JArray.FromObject(menuItems, _jsonSerializer)); _items.AddRange(menuItems); BridgeConnector.Socket.On("menuItemClicked", (id) => { - MenuItem menuItem = GetMenuItem(_items, id.ToString()); + MenuItem menuItem = _items.GetMenuItem(id.ToString()); menuItem?.Click(); }); } - private void AddMenuItemsId(MenuItem[] menuItems) - { - for (int index = 0; index < menuItems.Length; index++) - { - var menuItem = menuItems[index]; - if(menuItem?.Submenu?.Length > 0) - { - AddMenuItemsId(menuItem.Submenu); - } - - if(string.IsNullOrEmpty(menuItem.Role)) - { - menuItem.Id = Guid.NewGuid().ToString(); - } - } - } - - private MenuItem GetMenuItem(List menuItems, string id) - { - MenuItem result = new MenuItem(); - - foreach (var item in menuItems) - { - if(item.Id == id) - { - result = item; - } - else if(item?.Submenu?.Length > 0) - { - var menuItem = GetMenuItem(item.Submenu.ToList(), id); - if(menuItem.Id == id) - { - result = menuItem; - } - } - } - - return result; - } - private JsonSerializer _jsonSerializer = new JsonSerializer() { ContractResolver = new CamelCasePropertyNamesContractResolver(), diff --git a/ElectronNET.API/Tray.cs b/ElectronNET.API/Tray.cs index 417812e..01599d9 100644 --- a/ElectronNET.API/Tray.cs +++ b/ElectronNET.API/Tray.cs @@ -1,7 +1,9 @@ using ElectronNET.API.Entities; +using ElectronNET.API.Extensions; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Serialization; +using System.Collections.Generic; namespace ElectronNET.API { @@ -24,9 +26,19 @@ namespace ElectronNET.API } } + public IReadOnlyCollection Items { get { return _items.AsReadOnly(); } } + private List _items = new List(); + public void Show(string image, MenuItem[] menuItems) { + menuItems.AddMenuItemsId(); BridgeConnector.Socket.Emit("create-tray", image, JArray.FromObject(menuItems, _jsonSerializer)); + _items.AddRange(menuItems); + + BridgeConnector.Socket.On("trayMenuItemClicked", (id) => { + MenuItem menuItem = _items.GetMenuItem(id.ToString()); + menuItem?.Click(); + }); } private JsonSerializer _jsonSerializer = new JsonSerializer() diff --git a/ElectronNET.API/WindowManager.cs b/ElectronNET.API/WindowManager.cs index 9622ef4..2103041 100644 --- a/ElectronNET.API/WindowManager.cs +++ b/ElectronNET.API/WindowManager.cs @@ -31,15 +31,17 @@ namespace ElectronNET.API public async Task CreateWindowAsync(string loadUrl = "http://localhost") { - return await CreateWindowAsync(new BrowserWindowConstructorOptions(), loadUrl); + return await CreateWindowAsync(new BrowserWindowOptions(), loadUrl); } - public Task CreateWindowAsync(BrowserWindowConstructorOptions options, string loadUrl = "http://localhost") + public Task CreateWindowAsync(BrowserWindowOptions options, string loadUrl = "http://localhost") { var taskCompletionSource = new TaskCompletionSource(); BridgeConnector.Socket.On("BrowserWindowCreated", (id) => { + BridgeConnector.Socket.Off("BrowserWindowCreated"); + string windowId = id.ToString(); BrowserWindow browserWindow = new BrowserWindow(int.Parse(windowId)); _browserWindows.Add(browserWindow); diff --git a/ElectronNET.Host/api/browserWindows.js b/ElectronNET.Host/api/browserWindows.js index 39efbb2..9ff87d5 100644 --- a/ElectronNET.Host/api/browserWindows.js +++ b/ElectronNET.Host/api/browserWindows.js @@ -2,7 +2,6 @@ exports.__esModule = true; var electron_1 = require("electron"); var windows = []; -var ipc; module.exports = function (socket) { socket.on('createBrowserWindow', function (options, loadUrl) { var window = new electron_1.BrowserWindow(options); @@ -19,19 +18,76 @@ module.exports = function (socket) { } } }); - // TODO: IPC Lösung für mehrere Fenster finden - if (ipc == undefined) { - ipc = require('./ipc')(socket, window); - } if (loadUrl) { window.loadURL(loadUrl); } windows.push(window); socket.emit('BrowserWindowCreated', window.id); }); + socket.on('browserWindow-destroy', function (id) { + getWindowById(id).destroy(); + }); + socket.on('browserWindow-close', function (id) { + getWindowById(id).close(); + }); + socket.on('browserWindow-focus', function (id) { + getWindowById(id).focus(); + }); + socket.on('browserWindow-blur', function (id) { + getWindowById(id).blur(); + }); + socket.on('browserWindow-isFocused', function (id) { + var isFocused = getWindowById(id).isFocused(); + socket.emit('browserWindow-isFocused-completed', isFocused); + }); + socket.on('browserWindow-isDestroyed', function (id) { + var isDestroyed = getWindowById(id).isDestroyed(); + socket.emit('browserWindow-isDestroyed-completed', isDestroyed); + }); + socket.on('browserWindow-show', function (id) { + getWindowById(id).show(); + }); + socket.on('browserWindow-showInactive', function (id) { + getWindowById(id).showInactive(); + }); + socket.on('browserWindow-hide', function (id) { + getWindowById(id).hide(); + }); + socket.on('browserWindow-isVisible', function (id) { + var isVisible = getWindowById(id).isVisible(); + socket.emit('browserWindow-isVisible-completed', isVisible); + }); + socket.on('browserWindow-isModal', function (id) { + var isModal = getWindowById(id).isModal(); + socket.emit('browserWindow-isModal-completed', isModal); + }); + socket.on('browserWindow-maximize', function (id) { + getWindowById(id).maximize(); + }); + socket.on('browserWindow-unmaximize', function (id) { + getWindowById(id).unmaximize(); + }); + socket.on('browserWindow-isMaximized', function (id) { + var isMaximized = getWindowById(id).isMaximized(); + socket.emit('browserWindow-isMaximized-completed', isMaximized); + }); socket.on('browserWindow-minimize', function (id) { getWindowById(id).minimize(); }); + socket.on('browserWindow-restore', function (id) { + getWindowById(id).restore(); + }); + socket.on('browserWindow-isMinimized', function (id) { + var isMinimized = getWindowById(id).isMinimized(); + socket.emit('browserWindow-isMinimized-completed', isMinimized); + }); + socket.on('browserWindow-setFullScreen', function (id, fullscreen) { + getWindowById(id).setFullScreen(fullscreen); + }); + socket.on('browserWindow-isFullScreen', function (id) { + var isFullScreen = getWindowById(id).isFullScreen(); + socket.emit('browserWindow-isFullScreen-completed', isFullScreen); + }); function getWindowById(id) { for (var index = 0; index < windows.length; index++) { var element = windows[index]; diff --git a/ElectronNET.Host/api/browserWindows.js.map b/ElectronNET.Host/api/browserWindows.js.map index 3e67861..b819a5b 100644 --- a/ElectronNET.Host/api/browserWindows.js.map +++ b/ElectronNET.Host/api/browserWindows.js.map @@ -1 +1 @@ -{"version":3,"file":"browserWindows.js","sourceRoot":"","sources":["browserWindows.ts"],"names":[],"mappings":";;AAAA,qCAAyC;AACzC,IAAI,OAAO,GAA6B,EAAE,CAAA;AAC1C,IAAI,GAAG,CAAC;AAER,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB;IACrC,MAAM,CAAC,EAAE,CAAC,qBAAqB,EAAE,UAAC,OAAO,EAAE,OAAO;QAC9C,IAAI,MAAM,GAAG,IAAI,wBAAa,CAAC,OAAO,CAAC,CAAC;QAExC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAC,MAAM;YACvB,GAAG,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;gBAClD,IAAI,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;gBAChC,IAAI,CAAC;oBACD,UAAU,CAAC,EAAE,CAAC;gBAClB,CAAC;gBAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;oBACb,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,KAAK,2BAA2B,CAAC,CAAC,CAAC;wBAChD,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;oBAC7B,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,+CAA+C;QAC/C,EAAE,CAAC,CAAC,GAAG,IAAI,SAAS,CAAC,CAAC,CAAC;YACnB,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC3C,CAAC;QAED,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YACV,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC5B,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrB,MAAM,CAAC,IAAI,CAAC,sBAAsB,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,wBAAwB,EAAE,UAAC,EAAE;QACnC,aAAa,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,uBAAuB,EAAU;QAC7B,GAAG,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;YAClD,IAAI,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;YAC7B,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;gBACnB,MAAM,CAAC,OAAO,CAAC;YACnB,CAAC;QACL,CAAC;IACL,CAAC;AACL,CAAC,CAAA"} \ No newline at end of file +{"version":3,"file":"browserWindows.js","sourceRoot":"","sources":["browserWindows.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/ElectronNET.Host/api/browserWindows.ts b/ElectronNET.Host/api/browserWindows.ts index 105b9ed..0614241 100644 --- a/ElectronNET.Host/api/browserWindows.ts +++ b/ElectronNET.Host/api/browserWindows.ts @@ -1,6 +1,5 @@ import { BrowserWindow } from "electron"; -let windows: Electron.BrowserWindow[] = [] -let ipc; +const windows: Electron.BrowserWindow[] = [] module.exports = (socket: SocketIO.Server) => { socket.on('createBrowserWindow', (options, loadUrl) => { @@ -19,11 +18,6 @@ module.exports = (socket: SocketIO.Server) => { } }); - // TODO: IPC Lösung für mehrere Fenster finden - if (ipc == undefined) { - ipc = require('./ipc')(socket, window); - } - if (loadUrl) { window.loadURL(loadUrl); } @@ -32,10 +26,202 @@ module.exports = (socket: SocketIO.Server) => { socket.emit('BrowserWindowCreated', window.id); }); + socket.on('browserWindow-destroy', (id) => { + getWindowById(id).destroy(); + }); + + socket.on('browserWindow-close', (id) => { + getWindowById(id).close(); + }); + + socket.on('browserWindow-focus', (id) => { + getWindowById(id).focus(); + }); + + socket.on('browserWindow-blur', (id) => { + getWindowById(id).blur(); + }); + + socket.on('browserWindow-isFocused', (id) => { + const isFocused = getWindowById(id).isFocused(); + + socket.emit('browserWindow-isFocused-completed', isFocused); + }); + + socket.on('browserWindow-isDestroyed', (id) => { + const isDestroyed = getWindowById(id).isDestroyed(); + + socket.emit('browserWindow-isDestroyed-completed', isDestroyed); + }); + + socket.on('browserWindow-show', (id) => { + getWindowById(id).show(); + }); + + socket.on('browserWindow-showInactive', (id) => { + getWindowById(id).showInactive(); + }); + + socket.on('browserWindow-hide', (id) => { + getWindowById(id).hide(); + }); + + socket.on('browserWindow-isVisible', (id) => { + const isVisible = getWindowById(id).isVisible(); + + socket.emit('browserWindow-isVisible-completed', isVisible); + }); + + socket.on('browserWindow-isModal', (id) => { + const isModal = getWindowById(id).isModal(); + + socket.emit('browserWindow-isModal-completed', isModal); + }); + + socket.on('browserWindow-maximize', (id) => { + getWindowById(id).maximize(); + }); + + socket.on('browserWindow-unmaximize', (id) => { + getWindowById(id).unmaximize(); + }); + + socket.on('browserWindow-isMaximized', (id) => { + const isMaximized = getWindowById(id).isMaximized(); + + socket.emit('browserWindow-isMaximized-completed', isMaximized); + }); + socket.on('browserWindow-minimize', (id) => { getWindowById(id).minimize(); }); + socket.on('browserWindow-restore', (id) => { + getWindowById(id).restore(); + }); + + socket.on('browserWindow-isMinimized', (id) => { + const isMinimized = getWindowById(id).isMinimized(); + + socket.emit('browserWindow-isMinimized-completed', isMinimized); + }); + + socket.on('browserWindow-setFullScreen', (id, fullscreen) => { + getWindowById(id).setFullScreen(fullscreen); + }); + + socket.on('browserWindow-isFullScreen', (id) => { + const isFullScreen = getWindowById(id).isFullScreen(); + + socket.emit('browserWindow-isFullScreen-completed', isFullScreen); + }); + + socket.on('browserWindow-setAspectRatio', (id, aspectRatio, extraSize) => { + getWindowById(id).setAspectRatio(aspectRatio, extraSize); + }); + + socket.on('browserWindow-previewFile', (id, path, displayname) => { + getWindowById(id).previewFile(path, displayname); + }); + + socket.on('browserWindow-closeFilePreview', (id) => { + getWindowById(id).closeFilePreview(); + }); + + socket.on('browserWindow-setBounds', (id, bounds, animate) => { + getWindowById(id).setBounds(bounds, animate); + }); + + socket.on('browserWindow-getBounds', (id) => { + const rectangle = getWindowById(id).getBounds(); + + socket.emit('browserWindow-getBounds-completed', rectangle); + }); + + socket.on('browserWindow-setContentBounds', (id, bounds, animate) => { + getWindowById(id).setContentBounds(bounds, animate); + }); + + socket.on('browserWindow-getContentBounds', (id) => { + const rectangle = getWindowById(id).getContentBounds(); + + socket.emit('browserWindow-getContentBounds-completed', rectangle); + }); + + socket.on('browserWindow-setSize', (id, width, height, animate) => { + getWindowById(id).setSize(width, height, animate); + }); + + socket.on('browserWindow-getSize', (id) => { + const size = getWindowById(id).getSize(); + + socket.emit('browserWindow-getSize-completed', size); + }); + + socket.on('browserWindow-setContentSize', (id, width, height, animate) => { + getWindowById(id).setContentSize(width, height, animate); + }); + + socket.on('browserWindow-getContentSize', (id) => { + const size = getWindowById(id).getContentSize(); + + socket.emit('browserWindow-getContentSize-completed', size); + }); + + socket.on('browserWindow-setMinimumSize', (id, width, height) => { + getWindowById(id).setMinimumSize(width, height); + }); + + socket.on('browserWindow-getMinimumSize', (id) => { + const size = getWindowById(id).getMinimumSize(); + + socket.emit('browserWindow-getMinimumSize-completed', size); + }); + + socket.on('browserWindow-setMaximumSize', (id, width, height) => { + getWindowById(id).setMaximumSize(width, height); + }); + + socket.on('browserWindow-getMaximumSize', (id) => { + const size = getWindowById(id).getMaximumSize(); + + socket.emit('browserWindow-getMaximumSize-completed', size); + }); + + socket.on('browserWindow-setResizable', (id, resizable) => { + getWindowById(id).setResizable(resizable); + }); + + socket.on('browserWindow-isResizable', (id) => { + const resizable = getWindowById(id).isResizable(); + + socket.emit('browserWindow-isResizable-completed', resizable); + }); + + socket.on('browserWindow-setMovable', (id, movable) => { + getWindowById(id).setMovable(movable); + }); + + socket.on('browserWindow-isMovable', (id) => { + const movable = getWindowById(id).isMovable(); + + socket.emit('browserWindow-isMovable-completed', movable); + }); + + socket.on('browserWindow-setMinimizable', (id, minimizable) => { + getWindowById(id).setMinimizable(minimizable); + }); + + socket.on('browserWindow-isMinimizable', (id) => { + const minimizable = getWindowById(id).isMinimizable(); + + socket.emit('browserWindow-isMinimizable-completed', minimizable); + }); + + socket.on('browserWindow-setMaximizable', (id, maximizable) => { + getWindowById(id).setMaximizable(maximizable); + }); + function getWindowById(id: number): Electron.BrowserWindow { for (var index = 0; index < windows.length; index++) { var element = windows[index]; diff --git a/ElectronNET.Host/api/dialog.js b/ElectronNET.Host/api/dialog.js index e3f106e..7d0a88a 100644 --- a/ElectronNET.Host/api/dialog.js +++ b/ElectronNET.Host/api/dialog.js @@ -6,12 +6,12 @@ module.exports = function (socket) { if ("id" in browserWindow) { var window = electron_1.BrowserWindow.fromId(browserWindow.id); electron_1.dialog.showMessageBox(window, options, function (response, checkboxChecked) { - socket.emit('showMessageBoxComplete', response, checkboxChecked); + socket.emit('showMessageBoxComplete', [response, checkboxChecked]); }); } else { electron_1.dialog.showMessageBox(browserWindow, function (response, checkboxChecked) { - socket.emit('showMessageBoxComplete', response, checkboxChecked); + socket.emit('showMessageBoxComplete', [response, checkboxChecked]); }); } }); diff --git a/ElectronNET.Host/api/dialog.js.map b/ElectronNET.Host/api/dialog.js.map index f7a9d8d..672e716 100644 --- a/ElectronNET.Host/api/dialog.js.map +++ b/ElectronNET.Host/api/dialog.js.map @@ -1 +1 @@ -{"version":3,"file":"dialog.js","sourceRoot":"","sources":["dialog.ts"],"names":[],"mappings":";;AAAA,qCAAiD;AAEjD,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB;IACrC,MAAM,CAAC,EAAE,CAAC,gBAAgB,EAAE,UAAC,aAAa,EAAE,OAAO;QAC/C,EAAE,CAAA,CAAC,IAAI,IAAI,aAAa,CAAC,CAAC,CAAC;YACvB,IAAI,MAAM,GAAG,wBAAa,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;YAEpD,iBAAM,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,UAAC,QAAQ,EAAE,eAAe;gBAC7D,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;YACrE,CAAC,CAAC,CAAC;QACP,CAAC;QAAC,IAAI,CAAC,CAAC;YACJ,iBAAM,CAAC,cAAc,CAAC,aAAa,EAAE,UAAC,QAAQ,EAAE,eAAe;gBAC3D,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;YACrE,CAAC,CAAC,CAAC;QACP,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC,CAAA"} \ No newline at end of file +{"version":3,"file":"dialog.js","sourceRoot":"","sources":["dialog.ts"],"names":[],"mappings":";;AAAA,qCAAiD;AAEjD,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB;IACrC,MAAM,CAAC,EAAE,CAAC,gBAAgB,EAAE,UAAC,aAAa,EAAE,OAAO;QAC/C,EAAE,CAAA,CAAC,IAAI,IAAI,aAAa,CAAC,CAAC,CAAC;YACvB,IAAI,MAAM,GAAG,wBAAa,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;YAEpD,iBAAM,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,UAAC,QAAQ,EAAE,eAAe;gBAC7D,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC;YACvE,CAAC,CAAC,CAAC;QACP,CAAC;QAAC,IAAI,CAAC,CAAC;YACJ,iBAAM,CAAC,cAAc,CAAC,aAAa,EAAE,UAAC,QAAQ,EAAE,eAAe;gBAC3D,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC;YACvE,CAAC,CAAC,CAAC;QACP,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC,CAAA"} \ No newline at end of file diff --git a/ElectronNET.Host/api/dialog.ts b/ElectronNET.Host/api/dialog.ts index c445e51..24a03c2 100644 --- a/ElectronNET.Host/api/dialog.ts +++ b/ElectronNET.Host/api/dialog.ts @@ -6,11 +6,11 @@ module.exports = (socket: SocketIO.Server) => { var window = BrowserWindow.fromId(browserWindow.id); dialog.showMessageBox(window, options, (response, checkboxChecked) => { - socket.emit('showMessageBoxComplete', response, checkboxChecked); + socket.emit('showMessageBoxComplete', [response, checkboxChecked]); }); } else { dialog.showMessageBox(browserWindow, (response, checkboxChecked) => { - socket.emit('showMessageBoxComplete', response, checkboxChecked); + socket.emit('showMessageBoxComplete', [response, checkboxChecked]); }); } }); diff --git a/ElectronNET.Host/api/ipc.js b/ElectronNET.Host/api/ipc.js index 80535a6..81d465d 100644 --- a/ElectronNET.Host/api/ipc.js +++ b/ElectronNET.Host/api/ipc.js @@ -1,23 +1,26 @@ -var ipcMain = require('electron').ipcMain; -module.exports = function (socket, window) { +"use strict"; +exports.__esModule = true; +var electron_1 = require("electron"); +module.exports = function (socket) { socket.on('registerIpcMainChannel', function (channel) { - ipcMain.on(channel, function (event, args) { + electron_1.ipcMain.on(channel, function (event, args) { socket.emit(channel, [event.preventDefault(), args]); }); }); socket.on('registerOnceIpcMainChannel', function (channel) { - ipcMain.once(channel, function (event, args) { + electron_1.ipcMain.once(channel, function (event, args) { socket.emit(channel, [event.preventDefault(), args]); }); }); socket.on('removeAllListenersIpcMainChannel', function (channel) { - ipcMain.removeAllListeners(channel); + electron_1.ipcMain.removeAllListeners(channel); }); - socket.on('sendToIpcRenderer', function (channel) { + socket.on('sendToIpcRenderer', function (browserWindow, channel) { var data = []; - for (var _i = 1; _i < arguments.length; _i++) { - data[_i - 1] = arguments[_i]; + for (var _i = 2; _i < arguments.length; _i++) { + data[_i - 2] = arguments[_i]; } + var window = electron_1.BrowserWindow.fromId(browserWindow.id); if (window) { window.webContents.send(channel, data); } diff --git a/ElectronNET.Host/api/ipc.js.map b/ElectronNET.Host/api/ipc.js.map index 36547f4..dea2f4c 100644 --- a/ElectronNET.Host/api/ipc.js.map +++ b/ElectronNET.Host/api/ipc.js.map @@ -1 +1 @@ -{"version":3,"file":"ipc.js","sourceRoot":"","sources":["ipc.ts"],"names":[],"mappings":"AAAQ,IAAA,qCAAO,CAAyB;AAExC,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB,EAAE,MAAM;IAC7C,MAAM,CAAC,EAAE,CAAC,wBAAwB,EAAE,UAAC,OAAO;QACxC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,UAAC,KAAK,EAAE,IAAI;YAC5B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,cAAc,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,4BAA4B,EAAE,UAAC,OAAO;QAC5C,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,UAAC,KAAK,EAAE,IAAI;YAC9B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,cAAc,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,kCAAkC,EAAE,UAAC,OAAO;QAClD,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,mBAAmB,EAAE,UAAC,OAAO;QAAE,cAAO;aAAP,UAAO,EAAP,qBAAO,EAAP,IAAO;YAAP,6BAAO;;QAC5C,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YACT,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC3C,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC,CAAA"} \ No newline at end of file +{"version":3,"file":"ipc.js","sourceRoot":"","sources":["ipc.ts"],"names":[],"mappings":";;AAAA,qCAAkD;AAElD,MAAM,CAAC,OAAO,GAAG,UAAC,MAAuB;IACrC,MAAM,CAAC,EAAE,CAAC,wBAAwB,EAAE,UAAC,OAAO;QACxC,kBAAO,CAAC,EAAE,CAAC,OAAO,EAAE,UAAC,KAAK,EAAE,IAAI;YAC5B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,cAAc,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,4BAA4B,EAAE,UAAC,OAAO;QAC5C,kBAAO,CAAC,IAAI,CAAC,OAAO,EAAE,UAAC,KAAK,EAAE,IAAI;YAC9B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,cAAc,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,kCAAkC,EAAE,UAAC,OAAO;QAClD,kBAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,mBAAmB,EAAE,UAAC,aAAa,EAAE,OAAO;QAAE,cAAO;aAAP,UAAO,EAAP,qBAAO,EAAP,IAAO;YAAP,6BAAO;;QAC3D,IAAM,MAAM,GAAG,wBAAa,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;QAEtD,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YACT,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC3C,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC,CAAA"} \ No newline at end of file diff --git a/ElectronNET.Host/api/ipc.ts b/ElectronNET.Host/api/ipc.ts index 7f65581..b3a7b2b 100644 --- a/ElectronNET.Host/api/ipc.ts +++ b/ElectronNET.Host/api/ipc.ts @@ -1,6 +1,6 @@ -const { ipcMain } = require('electron'); +import { ipcMain, BrowserWindow } from 'electron'; -module.exports = (socket: SocketIO.Server, window) => { +module.exports = (socket: SocketIO.Server) => { socket.on('registerIpcMainChannel', (channel) => { ipcMain.on(channel, (event, args) => { socket.emit(channel, [event.preventDefault(), args]); @@ -17,7 +17,9 @@ module.exports = (socket: SocketIO.Server, window) => { ipcMain.removeAllListeners(channel); }); - socket.on('sendToIpcRenderer', (channel, ...data) => { + socket.on('sendToIpcRenderer', (browserWindow, channel, ...data) => { + const window = BrowserWindow.fromId(browserWindow.id); + if (window) { window.webContents.send(channel, data); } diff --git a/ElectronNET.Host/api/tray.js b/ElectronNET.Host/api/tray.js index 8cc6e97..1a9a53f 100644 --- a/ElectronNET.Host/api/tray.js +++ b/ElectronNET.Host/api/tray.js @@ -6,9 +6,22 @@ var tray; module.exports = function (socket) { socket.on('create-tray', function (image, menuItems) { var menu = electron_1.Menu.buildFromTemplate(menuItems); + addMenuItemClickConnector(menu.items, function (id) { + socket.emit("trayMenuItemClicked", id); + }); var imagePath = path.join(__dirname.replace('api', ''), 'bin', image); tray = new electron_1.Tray(imagePath); tray.setContextMenu(menu); }); + function addMenuItemClickConnector(menuItems, callback) { + menuItems.forEach(function (item) { + if (item.submenu && item.submenu.items.length > 0) { + addMenuItemClickConnector(item.submenu.items, callback); + } + if ("id" in item && item.id) { + item.click = function () { callback(item.id); }; + } + }); + } }; //# sourceMappingURL=tray.js.map \ No newline at end of file diff --git a/ElectronNET.Host/api/tray.js.map b/ElectronNET.Host/api/tray.js.map index 6ceee68..e28487a 100644 --- a/ElectronNET.Host/api/tray.js.map +++ b/ElectronNET.Host/api/tray.js.map @@ -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,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;AACP,CAAC,CAAA"} \ No newline at end of file +{"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"} \ No newline at end of file diff --git a/ElectronNET.Host/api/tray.ts b/ElectronNET.Host/api/tray.ts index a0ec1c8..01b8150 100644 --- a/ElectronNET.Host/api/tray.ts +++ b/ElectronNET.Host/api/tray.ts @@ -6,9 +6,25 @@ module.exports = (socket: SocketIO.Server) => { socket.on('create-tray', (image, menuItems) => { const menu = Menu.buildFromTemplate(menuItems); + addMenuItemClickConnector(menu.items, (id) => { + socket.emit("trayMenuItemClicked", id); + }); + const imagePath = path.join(__dirname.replace('api', ''), 'bin', image); tray = new Tray(imagePath); tray.setContextMenu(menu); }); + + function addMenuItemClickConnector(menuItems, callback) { + menuItems.forEach((item) => { + if(item.submenu && item.submenu.items.length > 0) { + addMenuItemClickConnector(item.submenu.items, callback); + } + + if("id" in item && item.id) { + item.click = () => { callback(item.id); }; + } + }); + } } \ No newline at end of file diff --git a/ElectronNET.Host/main.js b/ElectronNET.Host/main.js index 4c01f71..0e766de 100644 --- a/ElectronNET.Host/main.js +++ b/ElectronNET.Host/main.js @@ -3,7 +3,7 @@ const fs = require('fs'); const path = require('path'); const process = require('child_process').spawn; const portfinder = require('detect-port'); -let io, browserWindows, apiProcess, loadURL, appApi, menu, dialog, notification, tray; +let io, browserWindows, ipc, apiProcess, loadURL, appApi, menu, dialog, notification, tray; app.on('ready', () => { portfinder(8000, (error, port) => { @@ -20,6 +20,7 @@ function startSocketApiBridge(port) { appApi = require('./api/app')(socket, app); browserWindows = require('./api/browserWindows')(socket); + ipc = require('./api/ipc')(socket); menu = require('./api/menu')(socket); dialog = require('./api/dialog')(socket); notification = require('./api/notification')(socket); @@ -27,7 +28,6 @@ function startSocketApiBridge(port) { }); } - function startAspCoreBackend(electronPort) { portfinder(8000, (error, electronWebPort) => { loadURL = `http://localhost:${electronWebPort}` diff --git a/ElectronNET.WebApp/Controllers/HomeController.cs b/ElectronNET.WebApp/Controllers/HomeController.cs index 5f2146c..2690c75 100644 --- a/ElectronNET.WebApp/Controllers/HomeController.cs +++ b/ElectronNET.WebApp/Controllers/HomeController.cs @@ -12,16 +12,21 @@ namespace ElectronNET.WebApp.Controllers Electron.IpcMain.On("SayHello", (args) => { Electron.Notification.Show(new NotificationOptions("Hallo Robert","Nachricht von ASP.NET Core App")); - Electron.IpcMain.Send("Goodbye", "Elephant!"); + Electron.IpcMain.Send(Electron.WindowManager.BrowserWindows.First(), "Goodbye", "Elephant!"); }); Electron.IpcMain.On("GetPath", async (args) => { - string pathName = await Electron.App.GetPathAsync(PathName.pictures); - Electron.IpcMain.Send("GetPathComplete", pathName); + var currentBrowserWindow = Electron.WindowManager.BrowserWindows.First(); - Electron.WindowManager.BrowserWindows.First().Minimize(); - await Electron.WindowManager.CreateWindowAsync("http://www.google.de"); + string pathName = await Electron.App.GetPathAsync(PathName.pictures); + Electron.IpcMain.Send(currentBrowserWindow, "GetPathComplete", pathName); + + currentBrowserWindow.Minimize(); + await Electron.WindowManager.CreateWindowAsync(new BrowserWindowOptions { + Title = "My second Window", + AutoHideMenuBar = true + },"http://www.google.de"); }); diff --git a/ElectronNET.WebApp/Startup.cs b/ElectronNET.WebApp/Startup.cs index 8ad87aa..c7c3b49 100644 --- a/ElectronNET.WebApp/Startup.cs +++ b/ElectronNET.WebApp/Startup.cs @@ -43,7 +43,7 @@ namespace ElectronNET.WebApp public async void Bootstrap() { - Electron.Menu.SetApplicationMenu(new MenuItem[] { + var menuItems = new MenuItem[] { new MenuItem { Label = "File", Submenu = new MenuItem[] { @@ -66,19 +66,12 @@ namespace ElectronNET.WebApp }); } } - }); + }; + + Electron.Menu.SetApplicationMenu(menuItems); + Electron.Tray.Show("/Assets/electron_32x32.png", menuItems); var browserWindow = await Electron.WindowManager.CreateWindowAsync(); - - Electron.Tray.Show("/Assets/electron_32x32.png", new MenuItem[] { - new MenuItem { - Label = "Exit", - Click = () => - { - Electron.App.Exit(); - } - } - }); } } }