Initial commit

This commit is contained in:
Brik
2026-02-01 20:45:27 +01:00
commit 2d7e543163
11 changed files with 334 additions and 0 deletions

78
src/main/Program.cs Normal file
View File

@@ -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<string> 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}");
}
});
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -0,0 +1,4 @@
async function callCSharp() {
const result = await system.call("hello::world")
alert(result)
}

View File

@@ -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()

View File

@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./assets/css/index.css">
<title></title>
</head>
<body>
<main>
<h2>
Bienvenue dans Photino
</h2>
<button onclick="callCSharp()">
Appellez une fonction C#
</button>
</main>
<script src="./assets/js/ipc.js"></script>
<script src="./assets/js/index.js"></script>
</body>
</html>