static void Main(string[] args) { // API host configuration string[] apiArgs = new string[] { $"URLS={_apiBaseUri}", $"ENVIRONMENT={_apiEnvironment}" }; // Prepare the API host of the API project using (var api = PhotinoAPI.Program.CreateHostBuilder(apiArgs).Build()) { // Start API host api.StartAsync(); // Window configuration string windowTitle = "Photino for .NET Demo App + ASP.NET API"; // Prepare the PhotinoWindow instance var window = new PhotinoWindow(windowTitle, WindowConfigurationAction) .Resize(1280, 800) .Center() .UserCanResize(false) .Load($"{_wwwrootPath}/index.html"); window.WaitForClose(); // Starts the application event loop } }
public static void Run <TStartup>(string windowTitle, string hostHtmlPath, bool fullscreen = false, int x = 0, int y = 0, int width = 800, int height = 600) { DesktopSynchronizationContext.UnhandledException += (sender, exception) => { UnhandledException(exception); }; photinoWindow = new PhotinoWindow(windowTitle, options => { var contentRootAbsolute = Path.GetDirectoryName(Path.GetFullPath(hostHtmlPath)); options.CustomSchemeHandlers.Add(BlazorAppScheme, (string url, out string contentType) => { // TODO: Only intercept for the hostname 'app' and passthrough for others // TODO: Prevent directory traversal? var appFile = Path.Combine(contentRootAbsolute, new Uri(url).AbsolutePath.Substring(1)); if (appFile == contentRootAbsolute) { appFile = hostHtmlPath; } contentType = GetContentType(appFile); return(File.Exists(appFile) ? File.OpenRead(appFile) : null); }); // framework:// is resolved as embedded resources options.CustomSchemeHandlers.Add("framework", (string url, out string contentType) => { contentType = GetContentType(url); return(SupplyFrameworkFile(url)); }); }, width, height, x, y, fullscreen); CancellationTokenSource appLifetimeCts = new CancellationTokenSource(); Task.Factory.StartNew(async() => { try { var ipc = new IPC(photinoWindow); await RunAsync <TStartup>(ipc, appLifetimeCts.Token); } catch (Exception ex) { UnhandledException(ex); throw; } }); try { photinoWindow.Load(BlazorAppScheme + "://app/"); photinoWindow.WaitForClose(); } finally { appLifetimeCts.Cancel(); } }
private static void FluentStyle() { var iconFile = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "wwwroot/photino-logo.ico" : "wwwroot/photino-logo.png"; mainWindow = new PhotinoWindow() .SetIconFile(iconFile) .SetTitle($"My Photino Window {_windowNumber++}") //.Load(new Uri("https://google.com")) .Load("wwwroot/main.html") //.LoadRawString("<h1>Hello Photino!</h1>") //.SetChromeless(true) //.SetFullScreen(true) //.SetMaximized(true) //.SetMinimized(true) //.SetResizable(false) //.SetTopMost(true) //.SetUseOsDefaultLocation(false) //.SetUseOsDefaultSize(false) //.SetZoom(150) //.SetContextMenuEnabled(false) //.SetDevToolsEnabled(false) //.SetGrantBrowserPermissions(false) //.Center() //.SetSize(800, 600) //.SetHeight(600) //.SetWidth(800) //.SetLocation(new Point(50, 50)) //.SetTop(50) //.SetLeft(50) //.MoveTo(new Point(10, 10)) //.MoveTo(20, 20) //.Offset(new Point(150, 150)) //.Offset(250, 250) .RegisterCustomSchemeHandler("app", AppCustomSchemeUsed) .RegisterWindowCreatingHandler(WindowCreating) .RegisterWindowCreatedHandler(WindowCreated) .RegisterLocationChangedHandler(WindowLocationChanged) .RegisterSizeChangedHandler(WindowSizeChanged) .RegisterWebMessageReceivedHandler(MessageReceivedFromWindow) .RegisterWindowClosingHandler(WindowIsClosing) //.SetTemporaryFilesPath(@"C:\Temp") .SetLogVerbosity(_logEvents ? 2 : 0); mainWindow.WaitForClose(); mainWindow.Center(); //will never happen - this is blocking. }
private static void PropertyInitStyle() { var iconFile = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "wwwroot/photino-logo.ico" : "wwwroot/photino-logo.png"; mainWindow = new PhotinoWindow { IconFile = iconFile, Title = $"My Photino Window {_windowNumber++}", //StartUrl = "https://google.com", StartUrl = "wwwroot/main.html", //StartString = "<h1>Hello Photino!</h1>", //Centered = true, //Chromeless = true, //FullScreen = true, //Maximized = true, //Minimized = true, //Resizable = false, //TopMost = true, //UseOsDefaultLocation = false, //UseOsDefaultSize = false, //Zoom = 300, //ContextMenuEnabled = false, //DevToolsEnabled = false, //GrantBrowserPermissions = false, //CenterOnInitialize = true, //Size = new Size(800, 600), //Height = 600, //Width = 800, //Location = new Point(50, 50), //Top = 50, //Left = 50, WindowCreatingHandler = WindowCreating, WindowCreatedHandler = WindowCreated, WindowLocationChangedHandler = WindowLocationChanged, WindowSizeChangedHandler = WindowSizeChanged, WebMessageReceivedHandler = MessageReceivedFromWindow, WindowClosingHandler = WindowIsClosing, //TemporaryFilesPath = @"C:\Temp", LogVerbosity = _logEvents ? 2 : 0, }; //Can this be done with a property? mainWindow.RegisterCustomSchemeHandler("app", AppCustomSchemeUsed); mainWindow.WaitForClose(); Console.WriteLine("Done Blocking!"); }
public static void Main(string[] args) { CreateHostBuilder(args).Build().RunAsync(); string windowTitle = "Hello Photino for .NET Advanced!"; Action <PhotinoWindowOptions> windowConfiguration = options => { //options.CustomSchemeHandlers.Add("app", (string url, out string contentType) => //{ // contentType = "text/javascript"; // return new MemoryStream(Encoding.UTF8.GetBytes(@" // (() =>{ // window.setTimeout(() => { // alert(`🎉 Dynamically inserted JavaScript.`); // }, 1000); // })(); // ")); //}); options.WindowCreatingHandler += (object sender, EventArgs args) => { var window = (PhotinoWindow)sender; Console.WriteLine($"Creating new PhotinoWindow instance."); }; options.WindowCreatedHandler += (object sender, EventArgs args) => { var window = (PhotinoWindow)sender; Console.WriteLine($"Created new PhotinoWindow instance with title {window.Title}."); }; }; var window = new PhotinoWindow(windowTitle, windowConfiguration) .RegisterWebMessageReceivedHandler((object sender, string message) => { var window = (PhotinoWindow)sender; string response = $"Received message: \"{message}\""; window.SendWebMessage(response); }); Size windowSize = new Size(800, 650); Size workAreaSize = window.MainMonitor.WorkArea.Size; Point centeredPosition = new Point( ((workAreaSize.Width / 2) - (windowSize.Width / 2)), ((workAreaSize.Height / 2) - (windowSize.Height / 2)) ); window .Resize(windowSize) .MoveTo(centeredPosition) .Load("wwwroot/index.html"); window.WaitForClose(); }
public static void Main(string[] args) { CreateHostBuilder(args).Build().RunAsync(); // Window title declared here for visibility string windowTitle = "Photino for .NET, gRPC enabled"; // Creating a new PhotinoWindow instance with the fluent API var window = new PhotinoWindow() .SetTitle(windowTitle) // Resize to a percentage of the main monitor work area .SetUseOsDefaultSize(false) .SetSize(new Size(800, 400)) // Center window in the middle of the screen .Center() // Users can resize windows by default. // Let's make this one fixed instead. .SetResizable(false) .RegisterCustomSchemeHandler("app", (object sender, string scheme, string url, out string contentType) => { contentType = "text/javascript"; return(new MemoryStream(Encoding.UTF8.GetBytes(@" (() =>{ window.setTimeout(() => { alert(`🎉 Dynamically inserted JavaScript.`); }, 1000); })(); "))); }) // Most event handlers can be registered after the // PhotinoWindow was instantiated by calling a registration // method like the following RegisterWebMessageReceivedHandler. // This could be added in the PhotinoWindowOptions if preferred. .RegisterWebMessageReceivedHandler((object sender, string message) => { var window = (PhotinoWindow)sender; // The message argument is coming in from sendMessage. // "window.external.sendMessage(message: string)" string response = $"Received message: \"{message}\""; // Send a message back the to JavaScript event handler. // "window.external.receiveMessage(callback: Function)" window.SendWebMessage(response); }) .Load("wwwroot/index.html"); // Can be used with relative path strings or "new URI()" instance to load a website. window.WaitForClose(); }
static void Main(string[] args) { // Window title declared here for visibility string windowTitle = "Photino.React 3D App"; // Creating a new PhotinoWindow instance with the fluent API var window = new PhotinoWindow(windowTitle) // Resize to a percentage of the main monitor work area .Resize(50, 50, "%") // Center window in the middle of the screen .Center() // Users can resize windows by default. // Let's make this one fixed instead. .UserCanResize(false) .Load("wwwroot/index.html"); // Can be used with relative path strings or "new URI()" instance to load a website. window.WaitForClose(); // Starts the application event loop }
internal static void ShowFatalError(string workingDir, string title, string error) { _mainWindow = CreateWindow(workingDir, $"smtp4dev - {title}"); _mainWindow.LoadRawString($"<html><h1>{HttpUtility.HtmlEncode(title)}</h1><pre>{HttpUtility.HtmlEncode(error)}</pre><button type='button' onclick='window.location = \'https://www.google.co.uk\''>Close</button></body></html>"); _mainWindow.WaitForClose(); }
internal static void Run(string workingDir, Uri baseUrl) { _mainWindow = CreateWindow(workingDir); _mainWindow.Load(baseUrl); _mainWindow.WaitForClose(); }
public static void Main(string[] args) { CreateHostBuilder(args).Build().RunAsync(); // Window title declared here for visibility string windowTitle = "Photino for .NET, gRPC enabled"; // Define the PhotinoWindow options. Some handlers // can only be registered before a PhotinoWindow instance // is initialized. Currently there are three handlers // that must be defined here. Action <PhotinoWindowOptions> windowConfiguration = options => { // Custom scheme handlers can only be registered during // initialization of a PhotinoWindow instance. options.CustomSchemeHandlers.Add("app", (string url, out string contentType) => { contentType = "text/javascript"; return(new MemoryStream(Encoding.UTF8.GetBytes(@" (() =>{ window.setTimeout(() => { alert(`🎉 Dynamically inserted JavaScript.`); }, 1000); })(); "))); }); // Window creating and created handlers can only be // registered during initialization of a PhotinoWindow instance. // These handlers are fired before and after the native constructor // method is called. options.WindowCreatingHandler += (object sender, EventArgs args) => { var window = (PhotinoWindow)sender; // Instance is not initialized at this point. Class properties are not set yet. Console.WriteLine($"Creating new PhotinoWindow instance."); }; options.WindowCreatedHandler += (object sender, EventArgs args) => { var window = (PhotinoWindow)sender; // Instance is initialized. Class properties are now set and can be used. Console.WriteLine($"Created new PhotinoWindow instance with title {window.Title}."); }; }; // Creating a new PhotinoWindow instance with the fluent API var window = new PhotinoWindow(windowTitle, windowConfiguration) // Resize to a percentage of the main monitor work area .Resize(50, 50, "%") // Center window in the middle of the screen .Center() // Users can resize windows by default. // Let's make this one fixed instead. .UserCanResize(false) // Most event handlers can be registered after the // PhotinoWindow was instantiated by calling a registration // method like the following RegisterWebMessageReceivedHandler. // This could be added in the PhotinoWindowOptions if preferred. .RegisterWebMessageReceivedHandler((object sender, string message) => { var window = (PhotinoWindow)sender; // The message argument is coming in from sendMessage. // "window.external.sendMessage(message: string)" string response = $"Received message: \"{message}\""; // Send a message back the to JavaScript event handler. // "window.external.receiveMessage(callback: Function)" window.SendWebMessage(response); }) .Load("wwwroot/index.html"); // Can be used with relative path strings or "new URI()" instance to load a website. window.WaitForClose(); }
static void Main(string[] args) { FileDialogs.Init(); var serverStream = new SimplexStream(); var clientStream = new SimplexStream(); var encoding = new UTF8Encoding(false); var writer = new StreamWriter(serverStream, encoding); var formatter = new JsonMessageFormatter(encoding); Serializer.PrepareSerializer(formatter.JsonSerializer); var messageHandler = new NewLineDelimitedMessageHandler(clientStream, serverStream, formatter); var server = new FullServer(messageHandler); server.Workspace.SettingsService.RegisterSetting(DisplaySettingsNames.Theme, typeof(string), "xp/98.css"); server.Agent.IsReady += (o, e) => { if (args.Length == 1) { var _ = server.Workspace.ExecuteCommand("File.Open", args[0]); } }; // try to load settings string[] settingsLines = Array.Empty <string>(); var settingsFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".bcadconfig"); try { settingsLines = File.ReadAllLines(settingsFilePath); server.Workspace.SettingsService.LoadFromLines(settingsLines); server.Workspace.Update(isDirty: false); } catch { // don't really care if it failed } #if DEBUG var allowDebugging = true; var logVerbosity = 1; var clientArguments = new[] { "--", "debug" }; #else var allowDebugging = false; var logVerbosity = 0; var clientArguments = new[] { "--" }; #endif var window = new PhotinoWindow() .SetUseOsDefaultSize(true) .SetContextMenuEnabled(false) .Center() .SetDevToolsEnabled(allowDebugging) .SetResizable(true) .SetLogVerbosity(logVerbosity) .RegisterWebMessageReceivedHandler((object sender, string message) => { try { // forward JSON from client to server writer.WriteLine(message); writer.Flush(); } catch { // don't let this die } }); SetTitle(window, server.Workspace); window.RegisterCustomSchemeHandler("app", (object sender, string scheme, string url, out string contentType) => { contentType = "text/javascript"; var script = $"var clientArguments = [{string.Join(", ", clientArguments.Select(arg => $"\"{arg}\""))}];"; return(new MemoryStream(Encoding.UTF8.GetBytes(script))); }); var fileSystemService = new FileSystemService(action => { window.Invoke(action); }); server.Workspace.RegisterService(fileSystemService); server.Workspace.WorkspaceChanged += (sender, args) => SetTitle(window, server.Workspace); var doHardClose = false; window.WindowClosing += (sender, args) => { if (doHardClose) { // close immediately return(false); } if (server.Workspace.IsDirty) { var _ = Task.Run(async() => { var result = await server.Workspace.PromptForUnsavedChanges(); if (result != UnsavedChangesResult.Cancel) { doHardClose = true; window.Close(); } }); // don't close yet return(true); } return(false); }; var _ = Task.Run(async() => { var reader = new StreamReader(clientStream, encoding); while (true) { try { var line = await reader.ReadLineAsync(); window.SendWebMessage(line); } catch { // don't let this die } } }); server.Start(); var indexPath = Path.Combine(AppContext.BaseDirectory, "wwwroot", "index.html"); window.Load(indexPath); window.WaitForClose(); // try to save settings try { var newSettingsContents = server.Workspace.SettingsService.WriteWithLines(settingsLines); File.WriteAllText(settingsFilePath, newSettingsContents); } catch { // don't really care if it failed } }
/// <summary> /// Shows the window and waits for it to be closed. /// </summary> public void Run() { _manager.Navigate("/"); _window.WaitForClose(); }
private static void MessageReceivedFromWindow(object sender, string message) { Log(sender, $"MessageRecievedFromWindow Callback Fired."); var currentWindow = sender as PhotinoWindow; if (string.Compare(message, "child-window", true) == 0) { var iconFile = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "wwwroot/photino-logo.ico" : "wwwroot/photino-logo.png"; var x = new PhotinoWindow(currentWindow) .SetTitle($"Child Window {_windowNumber++}") //.SetIconFile(iconFile) .Load("wwwroot/main.html") .SetUseOsDefaultLocation(true) .SetHeight(600) .SetWidth(800) .SetGrantBrowserPermissions(false) .RegisterWindowCreatingHandler(WindowCreating) .RegisterWindowCreatedHandler(WindowCreated) .RegisterLocationChangedHandler(WindowLocationChanged) .RegisterSizeChangedHandler(WindowSizeChanged) .RegisterWebMessageReceivedHandler(MessageReceivedFromWindow) .RegisterWindowClosingHandler(WindowIsClosing) .RegisterCustomSchemeHandler("app", AppCustomSchemeUsed) .SetTemporaryFilesPath(currentWindow.TemporaryFilesPath) .SetLogVerbosity(_logEvents ? 2 : 0); x.WaitForClose(); //x.Center(); //WaitForClose() is non-blocking for child windows //x.SetHeight(800); //x.Close(); } else if (string.Compare(message, "zoom-in", true) == 0) { currentWindow.Zoom += 5; Log(sender, $"Zoom: {currentWindow.Zoom}"); } else if (string.Compare(message, "zoom-out", true) == 0) { currentWindow.Zoom -= 5; Log(sender, $"Zoom: {currentWindow.Zoom}"); } else if (string.Compare(message, "center", true) == 0) { currentWindow.Center(); } else if (string.Compare(message, "close", true) == 0) { currentWindow.Close(); } else if (string.Compare(message, "minimize", true) == 0) { currentWindow.SetMinimized(!currentWindow.Minimized); } else if (string.Compare(message, "maximize", true) == 0) { currentWindow.SetMaximized(!currentWindow.Maximized); } else if (string.Compare(message, "setcontextmenuenabled", true) == 0) { currentWindow.SetContextMenuEnabled(!currentWindow.ContextMenuEnabled); } else if (string.Compare(message, "setdevtoolsenabled", true) == 0) { currentWindow.SetDevToolsEnabled(!currentWindow.DevToolsEnabled); } else if (string.Compare(message, "setgrantbrowserpermissions", true) == 0) { currentWindow.SetGrantBrowserPermissions(!currentWindow.GrantBrowserPermissions); } else if (string.Compare(message, "seticonfile", true) == 0) { var iconFile = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "wwwroot/photino-logo.ico" : "wwwroot/photino-logo.png"; currentWindow.SetIconFile(iconFile); } else if (string.Compare(message, "setposition", true) == 0) { currentWindow.SetLeft(currentWindow.Left + 5); currentWindow.SetTop(currentWindow.Top + 5); } else if (string.Compare(message, "setresizable", true) == 0) { currentWindow.SetResizable(!currentWindow.Resizable); } else if (string.Compare(message, "setsize-up", true) == 0) { currentWindow.SetHeight(currentWindow.Height + 5); currentWindow.SetWidth(currentWindow.Width + 5); } else if (string.Compare(message, "setsize-down", true) == 0) { currentWindow.SetHeight(currentWindow.Height - 5); currentWindow.SetWidth(currentWindow.Width - 5); } else if (string.Compare(message, "settitle", true) == 0) { currentWindow.SetTitle(currentWindow.Title + "*"); } else if (string.Compare(message, "settopmost", true) == 0) { currentWindow.SetTopMost(!currentWindow.Topmost); } else if (string.Compare(message, "setfullscreen", true) == 0) { currentWindow.SetFullScreen(!currentWindow.FullScreen); } else if (string.Compare(message, "showproperties", true) == 0) { var properties = GetPropertiesDisplay(currentWindow); currentWindow.OpenAlertWindow("Settings", properties); } else if (string.Compare(message, "sendWebMessage", true) == 0) { currentWindow.SendWebMessage("alert('web message');"); } else if (string.Compare(message, "toastNotification", true) == 0) { currentWindow.SendNotification("Toast Title", " Taoast message!"); } else { throw new Exception($"Unknown message '{message}'"); } }