diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..af4a851 --- /dev/null +++ b/.gitignore @@ -0,0 +1,60 @@ +## A streamlined .gitignore for modern .NET projects +## including temporary files, build results, and +## files generated by popular .NET tools. If you are +## developing with Visual Studio, the VS .gitignore +## https://github.com/github/gitignore/blob/main/VisualStudio.gitignore +## has more thorough IDE-specific entries. +## +## Get latest from https://github.com/github/gitignore/blob/main/Dotnet.gitignore + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg + +# dotenv environment variables file +.env + +# Others +~$* +*~ +CodeCoverage/ + +# MSBuild Binary and Structured Log +*.binlog + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +temp +nuget.config \ No newline at end of file diff --git a/Photino-Boilerplate.csproj b/Photino-Boilerplate.csproj new file mode 100644 index 0000000..2b7ed89 --- /dev/null +++ b/Photino-Boilerplate.csproj @@ -0,0 +1,25 @@ + + + Exe + net8.0 + AnyCPU + Photino_Boilerplate + enable + enable + false + + + + $([System.IO.Path]::Combine('$(PkgBrikPackager)', 'lib', 'net8.0', 'BrikPackager.dll')) + $([System.IO.Path]::Combine('$(MSBuildProjectDirectory)', 'src', 'resources', 'renderer')) + $([System.IO.Path]::Combine('$(TargetDir)', 'root.dat')) + + + + + + + + + + \ No newline at end of file diff --git a/Photino-Boilerplate.sln b/Photino-Boilerplate.sln new file mode 100644 index 0000000..b092ffb --- /dev/null +++ b/Photino-Boilerplate.sln @@ -0,0 +1,24 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.2.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Photino-Boilerplate", "Photino-Boilerplate.csproj", "{5FF73963-D009-62ED-7350-FF17EC625A26}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5FF73963-D009-62ED-7350-FF17EC625A26}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5FF73963-D009-62ED-7350-FF17EC625A26}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5FF73963-D009-62ED-7350-FF17EC625A26}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5FF73963-D009-62ED-7350-FF17EC625A26}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {5D254170-B473-471E-AD56-26A8F4C4189E} + EndGlobalSection +EndGlobal diff --git a/README.md b/README.md index 7007b46..32c83c3 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# PhotinoBase +# Photino-Boilerplate diff --git a/src/main/Program.cs b/src/main/Program.cs new file mode 100644 index 0000000..2f6371f --- /dev/null +++ b/src/main/Program.cs @@ -0,0 +1,78 @@ +using System.Reflection; +using System.Text.Json; +using BrikPackager; +using PhotinoBoilerplate.Utils; +using Photino.NET; + +namespace PhotinoBoilerplate; + +class Program{ + + public static readonly JsonSerializerOptions _jsonOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; + private static readonly string __dirname = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!; + + [STAThread] + static void Main(string[] args) { + CreateMainWindow().WaitForClose(); + } + + public static PhotinoWindow CreateMainWindow() { + BrikPackage bpkg = new BrikPackage(Path.Combine(__dirname, "root.dat"), 66); + List entries = bpkg.ListEntries(); + var window = new PhotinoWindow() + .SetTitle("Photino Boilerplate") + .SetUseOsDefaultLocation(false) + .SetUseOsDefaultSize(false) + .RegisterCustomSchemeHandler("http", (object sender, string scheme, string url, out string contentType) =>{ + Uri uri = new Uri(url); + switch (uri.Host){ + case "internal": + string internalPath = uri.AbsolutePath; + contentType = MimeHelper.GetMimeType(uri.AbsolutePath); + byte[] fileData = bpkg.GetFileBytes(internalPath.TrimStart('/')); + return fileData != null ? new MemoryStream(fileData) : null; + default: + contentType = null!; + return null; + } + }); + + window.WindowCreated += (sender, e) => { + SetupBridge(window); + WindowHelper.setSize(window, 900, 600); + window.Center(); + }; + + + window.Load("http://internal/index.html"); + + return window; + } + + public static void SetupBridge(PhotinoWindow window) { + window.RegisterWebMessageReceivedHandler(async (object? sender, string message) => { + try { + var json = JsonDocument.Parse(message); + string requestId = json.RootElement.GetProperty("requestId").GetString()!; + string method = json.RootElement.GetProperty("functionName").GetString()!; + var jsonPayload = json.RootElement.GetProperty("payload"); + var pw = (PhotinoWindow)sender!; + + object? payload = null; + + switch (method) { + case "hello::world": + payload = "Hello from C#"; + break; + + } + + var response = new { requestId, payload }; + window.SendWebMessage(JsonSerializer.Serialize(response, _jsonOptions)); + } catch (Exception ex) { + Console.WriteLine($"Error stacktrace: {ex.StackTrace}"); + Console.WriteLine($"Bridge error: {ex.Message}"); + } + }); + } +} \ No newline at end of file diff --git a/src/main/helpers/Window.cs b/src/main/helpers/Window.cs new file mode 100644 index 0000000..91ed8cb --- /dev/null +++ b/src/main/helpers/Window.cs @@ -0,0 +1,29 @@ +using Photino.NET; +using System.Drawing; + +namespace PhotinoBoilerplate.Utils; + +public static class WindowHelper { + + private const float StandardDpi = 96.0f; + + + + public static Size GetScaledSize(PhotinoWindow window, int logicalWidth, int logicalHeight) { + float currentDpi = window.ScreenDpi > 0 ? window.ScreenDpi : StandardDpi; + float scaleFactor = currentDpi / StandardDpi; + + return new Size( + (int)(logicalWidth * scaleFactor), + (int)(logicalHeight * scaleFactor) + ); + } + + public static void setSize(PhotinoWindow window, int width, int height) { + Size targetSize = GetScaledSize(window, width, height); + window + .SetResizable(true) + .SetSize(targetSize) + .SetMinSize(targetSize.Width, targetSize.Height); + } +} \ No newline at end of file diff --git a/src/resources/renderer/assets/css/index.css b/src/resources/renderer/assets/css/index.css new file mode 100644 index 0000000..055c3c5 --- /dev/null +++ b/src/resources/renderer/assets/css/index.css @@ -0,0 +1,45 @@ +@import url("https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"); + +* { + margin: 0px; + padding: 0px; + box-sizing: border-box; +} + +main { + display: flex; + position: absolute; + top: 0px; + left: 0px; + right: 0px; + bottom: 0px; + flex-wrap: wrap; + flex-direction: column; + gap: 10px; + color: #cecece; + background-color: #404551; + align-items: center; + justify-content: center; + font-family: "Poppins", sans-serif; +} + +button { + cursor: pointer; + padding: 7px 7px 7px 7px; + color: #cecece; + font-weight: 500; + border: none; + outline: none; + border-radius: 5px; + background-color: #c8850a; + transition: .3s all; + font-family: "Poppins", sans-serif; +} + +button:hover { + filter: brightness(0.95); +} + +button:active { + filter: brightness(1.10); +} diff --git a/src/resources/renderer/assets/js/index.js b/src/resources/renderer/assets/js/index.js new file mode 100644 index 0000000..b6e9954 --- /dev/null +++ b/src/resources/renderer/assets/js/index.js @@ -0,0 +1,4 @@ +async function callCSharp() { + const result = await system.call("hello::world") + alert(result) +} \ No newline at end of file diff --git a/src/resources/renderer/assets/js/ipc.js b/src/resources/renderer/assets/js/ipc.js new file mode 100644 index 0000000..6f54d74 --- /dev/null +++ b/src/resources/renderer/assets/js/ipc.js @@ -0,0 +1,34 @@ +const system = { + _pendingRequests: new Map(), + + init: function() { + window.external.receiveMessage(response => { + try { + const res = JSON.parse(response) + if (res.requestId && this._pendingRequests.has(res.requestId)) { + const { resolve } = this._pendingRequests.get(res.requestId) + this._pendingRequests.delete(res.requestId) + resolve(res.payload) + } + } catch (e) { + console.error("Erreur format message :", e) + } + }) + }, + + call: function(functionName, data = {}) { + return new Promise((resolve, reject) => { + const requestId = Math.random().toString(36).substring(7) + + this._pendingRequests.set(requestId, { resolve, reject }) + + window.external.sendMessage(JSON.stringify({ + requestId: requestId, + functionName: functionName, + payload: data + })) + }) + } +} + +system.init() \ No newline at end of file diff --git a/src/resources/renderer/index.html b/src/resources/renderer/index.html new file mode 100644 index 0000000..0306745 --- /dev/null +++ b/src/resources/renderer/index.html @@ -0,0 +1,24 @@ + + + + + + + + + + +
+

+ Bienvenue dans Photino +

+ +
+ + + + + + \ No newline at end of file