Compare commits

..

3 Commits

18 changed files with 372 additions and 97 deletions

View File

@ -1,4 +1,4 @@
using FakeeDeck.Class; using FakeDeck.Class;
using Microsoft.VisualBasic.Logging; using Microsoft.VisualBasic.Logging;
using System.Configuration; using System.Configuration;
using System.Data; using System.Data;

View File

@ -3,32 +3,46 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TrayNotify;
namespace FakeeDeck.ButtonType namespace FakeDeck.ButtonType
{ {
internal class Button internal class Button
{ {
public static string getButtonHTML(string icon, string image, string name, string action, Dictionary<string, string> parameters = null) public static string getButtonHTML(string icon, string image, string name, string action = null, string jsAction = null, Dictionary<string, string> parameters = null, string color = null)
{ {
string body = ""; string body = "";
string styles = "style=\"background-size: cover; " + (!string.IsNullOrEmpty(image) ? "background-image: url('" + image + "');" : "") + " width: 150px; height: 150px; " + (!string.IsNullOrEmpty(image) ? "background-image: url('" + image + "');" : "") + (!string.IsNullOrEmpty(color) ? " background-color: " + color + "; " : "") + "\"";
body += "<div class=\"m-2\">"; body += "<div>";
body += "<form style=\"margin-bottom: 0px;\" method=\"post\" action=\"" + action + "\">"; if (action != null)
if (parameters is not null)
{ {
foreach (var parameter in parameters) body += "<form style=\"margin-bottom: 0px;\" method=\"post\" action=\"" + action + "\">";
if (parameters is not null)
{ {
body += "<input type=\"hidden\" name=\"" + parameter.Key + "\" value=\"" + parameter.Value + "\">"; foreach (var parameter in parameters)
{
body += "<input type=\"hidden\" name=\"" + parameter.Key + "\" value=\"" + parameter.Value + "\">";
}
} }
body += "<button class=\"button\" type=\"submit\" value=\"submit\" " + styles + ">";
body += (!string.IsNullOrEmpty(icon) ? "<i class=\"fa-solid " + icon + "\"></i>" : name);
body += "</button>";
body += "</form>";
}
else if (jsAction != null)
{
body += "<button class=\"button\" onclick=\"" + jsAction + "\" " + styles + " >";
body += (!string.IsNullOrEmpty(icon) ? "<i class=\"fa-solid " + icon + "\"></i>" : name);
body += "</button>";
}
else
{
body += "<div class=\"button\" " + styles + "></div>";
} }
body += "<button type=\"submit\" value=\"submit\" style=\"background-size: cover; " + (!string.IsNullOrEmpty(image) ? "background-image: url('" + image + "');" : "") + " width: 150px;height: 150px; background-color: aquamarine;\" >";
body += (!string.IsNullOrEmpty(icon) ? "<i class=\"fa-solid " + icon + "\"></i>" : name);
body += "</button>";
body += "</form>";
body += "</div>"; body += "</div>";
return body; return body;

View File

@ -0,0 +1,38 @@
using FakeDeck.ButtonType;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace FakeDeck.ButtonType
{
internal class FakeDeckMacro : Button
{
public static Dictionary<string, string> actionIcons = new Dictionary<string, string>
{
{ "full-screen", "fa-maximize"},
{ "set-page", "fa-page"},
};
public static string getButton(string Key, string Image = null, string PageId = null, string Color = null)
{
if (Key == "full-screen")
{
return getButtonHTML(actionIcons[Key], Image, Key, null, "!document.fullscreenElement?document.documentElement.requestFullscreen():document.exitFullscreen();", null, Color);
}
if (Key == "set-page")
{
return getButtonHTML(actionIcons[Key], Image, Key, null, "loadPage('"+ PageId + "')", null, Color);
}
if (Key == "spacer")
{
return getButtonHTML(null, null, null, null, null, null, Color);
}
else {
return "NIC";
}
}
}
}

View File

@ -1,4 +1,4 @@
using FakeeDeck.Class; using FakeDeck.Class;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
@ -7,7 +7,7 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using static System.Net.WebRequestMethods; using static System.Net.WebRequestMethods;
namespace FakeeDeck.ButtonType namespace FakeDeck.ButtonType
{ {
class HelldiversTwoMacro : Button class HelldiversTwoMacro : Button
{ {
@ -76,7 +76,7 @@ namespace FakeeDeck.ButtonType
public static string getButton(string Key) public static string getButton(string Key)
{ {
return getButtonHTML(null, stratogemsIcons[Key].ToString(), Key, "button\\HelldiversTwoMacro", new Dictionary<string, string>() { { "stratogem", Key } }); return getButtonHTML(null, stratogemsIcons[Key].ToString(), Key, "button\\HelldiversTwoMacro", null, new Dictionary<string, string>() { { "stratogem", Key } });
} }
public static bool invokeAction(string stratogem) public static bool invokeAction(string stratogem)

View File

@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace FakeeDeck.ButtonType namespace FakeDeck.ButtonType
{ {
internal class KeyboardMacro internal class KeyboardMacro
{ {

View File

@ -4,7 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace FakeeDeck.ButtonType namespace FakeDeck.ButtonType
{ {
internal class MediaMacro : Button internal class MediaMacro : Button
{ {
@ -27,7 +27,7 @@ namespace FakeeDeck.ButtonType
public static string getButton(string Key) public static string getButton(string Key)
{ {
return getButtonHTML(mediaIcons[Key], null, Key, "button\\MediaMacro", new Dictionary<string, string>() { { "control_action", Key } }); return getButtonHTML(mediaIcons[Key], null, Key, "button\\MediaMacro", null, new Dictionary<string, string>() { { "control_action", Key } });
} }
public static bool invokeAction(string control_action) public static bool invokeAction(string control_action)

View File

@ -6,13 +6,13 @@ using System.Text;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace FakeeDeck.Class namespace FakeDeck.Class
{ {
internal class AbstractionHelper internal class AbstractionHelper
{ {
public static Type? resolvType(string className) public static Type? resolvType(string className)
{ {
string cleanClass = "FakeeDeck.ButtonType." + className.Trim('/'); string cleanClass = "FakeDeck.ButtonType." + className.Trim('/');
Type? buttonClass = Type.GetType(cleanClass, true); Type? buttonClass = Type.GetType(cleanClass, true);
@ -25,13 +25,20 @@ namespace FakeeDeck.Class
public static string getButtonVisual(JsonElement button) public static string getButtonVisual(JsonElement button)
{ {
string calssName = button.GetProperty("function").ToString(); string calssName = button.GetProperty("function").ToString();
MethodInfo? renderMethod = AbstractionHelper.resolvType(calssName).GetMethod("getButton"); MethodInfo? renderMethod = resolvType(calssName).GetMethod("getButton");
ParameterInfo[] pars = renderMethod.GetParameters(); ParameterInfo[] pars = renderMethod.GetParameters();
List<object> parameters = new List<object>(); List<object> parameters = new List<object>();
foreach (ParameterInfo p in pars) foreach (ParameterInfo p in pars)
{ {
JsonElement parameter = button.GetProperty("parameters").EnumerateArray().SingleOrDefault(item => item.GetProperty("name").ToString() == p.Name); JsonElement parameter = button.GetProperty("parameters").EnumerateArray().SingleOrDefault(item => item.GetProperty("name").ToString() == p.Name);
if (string.IsNullOrEmpty(parameter.ToString()))
{
parameters.Insert(p.Position, p.DefaultValue);
continue;
}
parameters.Insert(p.Position, parameter.GetProperty("value").ToString()); parameters.Insert(p.Position, parameter.GetProperty("value").ToString());
} }

View File

@ -12,7 +12,7 @@ using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
namespace FakeeDeck.Class namespace FakeDeck.Class
{ {
public class AutoUpdateHelper public class AutoUpdateHelper
{ {

View File

@ -1,71 +1,66 @@
using System.Diagnostics; using System.Diagnostics;
using System.IO;
using System.Net; using System.Net;
using System.Reflection; using System.Reflection;
using System.Reflection.PortableExecutable; using System.Reflection.PortableExecutable;
using System.Text; using System.Text;
using System.Text.Json; using System.Text.Json;
using System.Windows;
using static System.Text.Json.JsonElement;
namespace FakeeDeck.Class namespace FakeDeck.Class
{ {
internal class FakeDeckMain internal class FakeDeckMain
{ {
private static string cachePath = "./cache/";
public static string pageHeader = public static string pageHeader =
"<!DOCTYPE>" + "<!DOCTYPE>" +
"<html>" + "<html lang=\"en\">" +
" <head>" + " <head>" +
" <title>HttpListener Example</title>" + " <title>HttpListener Example</title>" +
" <meta charset=\"utf-8\">" +
" <meta name = \"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=yes\">" +
" <link href=\"https://yarnpkg.com/en/package/normalize.css\" rel=\"stylesheet\">" + " <link href=\"https://yarnpkg.com/en/package/normalize.css\" rel=\"stylesheet\">" +
" <link href=\"https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css\" rel=\"stylesheet\">" + " <link href=\"https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css\" rel=\"stylesheet\">" +
" <link href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css\" rel=\"stylesheet\">" + " <link href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css\" rel=\"stylesheet\">" +
" <link href=\"StaticFiles/style.css\" rel=\"stylesheet\">" +
" </head>" + " </head>" +
" <body>" + " <body>" +
" <div class=\"d-flex flex-wrap\">" + " <div id=\"main\" class=\"d-flex flex-wrap\" style=\"transform-origin: left top;\">";
" <div class=\"m-2\">" +
" <p style=\"margin-bottom: 0px; width: 150px;height: 150px;background-color: aquamarine;\" >Page Views: {0}</p>" +
" </div>";
public static string pageFooter = public static string pageFooter =
" <div class=\"m-2\">" +
" <button style=\"width: 150px;height: 150px;background-color: aquamarine;\" onclick=\"!document.fullscreenElement ? document.documentElement.requestFullscreen() : document.exitFullscreen();\">" +
" <i class=\"fa-solid fa-maximize\"></i>" +
" </button>" +
" </div>" +
" </div>" + " </div>" +
" <script src=\"StaticFiles/app.js\"></script>" + " <script src=\"StaticFiles/app.js\"></script>" +
" </body>" + " </body>" +
"</html>"; "</html>";
public string pageData = ""; public string pageData = "";
private ArrayEnumerator pages;
public FakeDeckMain(YamlHelper yaml) public FakeDeckMain(YamlHelper yaml)
{ {
HttpServer server = new HttpServer(yaml.getData().GetProperty("server").GetProperty("port").ToString());
foreach (JsonElement item in yaml.getData().GetProperty("pages").EnumerateArray()) HttpServer server = new HttpServer(yaml.getData().GetProperty("server").GetProperty("port").ToString());
pages = yaml.getData().GetProperty("pages").EnumerateArray();
//ClearCache
if (Directory.Exists(cachePath))
{ {
Debug.WriteLine("PAGE: " + item.GetProperty("page")); DirectoryInfo di = new DirectoryInfo(cachePath);
foreach (JsonElement button in item.GetProperty("buttons").EnumerateArray()) foreach (FileInfo file in di.EnumerateFiles())
{ {
pageData += AbstractionHelper.getButtonVisual(button); file.Delete();
} }
} }
pageData = renderPageView();
server.addRoute(servViewResponseAsync, "GET", "/"); server.addRoute(servViewResponseAsync, "GET", "/");
server.addRoute(servButtonResponseAsync, "POST", "/button/"); server.addRoute(servButtonResponseAsync, "POST", "/button/");
server.addRoute(servPageResponseAsync, "POST", "/page");
/*foreach (var stratogem in HelldiversTwoMacro.stratogems)
{
server.pageData += HelldiversTwoMacro.getButton(stratogem.Key);
}
foreach (var control in MediaMacro.mediaControls)
{
server.pageData += MediaMacro.getButton(control.Key);
}*/
server.serv(); server.serv();
} }
private static void callButtonAction(string module, Dictionary<string, string> postParams) private static void callButtonAction(string module, Dictionary<string, string> postParams)
{ {
string cleanClass = "FakeeDeck.ButtonType." + module.Trim('/'); string cleanClass = "FakeDeck.ButtonType." + module.Trim('/');
Type? buttonClass = Type.GetType(cleanClass, true); Type? buttonClass = Type.GetType(cleanClass, true);
@ -115,9 +110,10 @@ namespace FakeeDeck.Class
try try
{ {
string module = req.Url.AbsolutePath.Replace("/button", ""); string module = req.Url.AbsolutePath.Replace("/button", "");
Console.WriteLine("Call module " + module); Debug.WriteLine("Call module " + module);
callButtonAction(module, postParams); callButtonAction(module, postParams);
resp.StatusCode = (int)HttpStatusCode.OK; resp.StatusCode = (int)HttpStatusCode.OK;
await resp.OutputStream.FlushAsync();
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -129,5 +125,50 @@ namespace FakeeDeck.Class
await resp.OutputStream.WriteAsync(errorData, 0, errorData.Length); await resp.OutputStream.WriteAsync(errorData, 0, errorData.Length);
} }
} }
private async Task servPageResponseAsync(HttpListenerRequest req, HttpListenerResponse resp, Dictionary<string, string> postParams)
{
string pageContent = "";
try
{
pageContent = renderPageView(postParams["Key"]);
resp.StatusCode = (int)HttpStatusCode.OK;
}
catch (Exception ex)
{
pageContent = ex.Message;
resp.StatusCode = (int)HttpStatusCode.InternalServerError;
}
byte[] errorData = Encoding.UTF8.GetBytes(pageContent);
resp.ContentType = "text/html";
resp.ContentEncoding = Encoding.UTF8;
resp.ContentLength64 = errorData.LongLength;
await resp.OutputStream.WriteAsync(errorData, 0, errorData.Length);
}
private string renderPageView(string page = null)
{
JsonElement selectedPage = pages.First();
if (page != null)
selectedPage = pages.SingleOrDefault(item => item.GetProperty("page").ToString() == page);
string SelectedPageName = selectedPage.GetProperty("page").ToString();
if (File.Exists(cachePath + SelectedPageName + ".html"))
return File.ReadAllText(cachePath + SelectedPageName + ".html");
string pageContent = "";
foreach (JsonElement button in selectedPage.GetProperty("buttons").EnumerateArray())
{
pageContent += AbstractionHelper.getButtonVisual(button);
}
if (Directory.Exists(cachePath))
Directory.CreateDirectory(cachePath);
File.WriteAllText(cachePath + SelectedPageName + ".html", pageContent);
return pageContent;
}
} }
} }

View File

@ -9,7 +9,7 @@ using System.IO;
using System.Text; using System.Text;
using System.Net; using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using FakeeDeck.ButtonType; using FakeDeck.ButtonType;
using System.Web; using System.Web;
using static System.Net.WebRequestMethods; using static System.Net.WebRequestMethods;
using File = System.IO.File; using File = System.IO.File;
@ -21,7 +21,7 @@ using System.Collections;
using System.Diagnostics; using System.Diagnostics;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
namespace FakeeDeck.Class namespace FakeDeck.Class
{ {
internal class HttpServer internal class HttpServer
{ {
@ -133,13 +133,13 @@ namespace FakeeDeck.Class
Debug.WriteLine(req.UserHostName); Debug.WriteLine(req.UserHostName);
Debug.WriteLine(req.UserAgent);*/ Debug.WriteLine(req.UserAgent);*/
bool isMatch = false;
if (req.HttpMethod == "GET" && req.Url.AbsolutePath.Contains(".")) if (req.HttpMethod == "GET" && req.Url.AbsolutePath.Contains("."))
{ {
await servFileResponseAsync(req, resp); await servFileResponseAsync(req, resp);
} }
else else
{ {
bool isMatch = false;
foreach (var route in routes[req.HttpMethod]) foreach (var route in routes[req.HttpMethod])
{ {
isMatch = Regex.IsMatch(req.Url.AbsolutePath, route.Key, RegexOptions.IgnoreCase); isMatch = Regex.IsMatch(req.Url.AbsolutePath, route.Key, RegexOptions.IgnoreCase);
@ -151,16 +151,18 @@ namespace FakeeDeck.Class
{ {
Dictionary<string, string> postParams = parsePostRequestParameters(req); Dictionary<string, string> postParams = parsePostRequestParameters(req);
gelegate.DynamicInvoke([req, resp, postParams]); gelegate.DynamicInvoke([req, resp, postParams]);
break;
} }
else
{ gelegate.DynamicInvoke([req, resp]);
gelegate.DynamicInvoke([req, resp]); break;
}
} }
} }
if (!isMatch) if (!isMatch)
{ {
Debug.WriteLine("NO ROUTE MATCHED");
resp.StatusCode = (int)HttpStatusCode.NotFound; resp.StatusCode = (int)HttpStatusCode.NotFound;
await resp.OutputStream.FlushAsync(); await resp.OutputStream.FlushAsync();
} }
@ -192,6 +194,7 @@ namespace FakeeDeck.Class
if (!File.Exists(filename)) if (!File.Exists(filename))
{ {
resp.StatusCode = (int)HttpStatusCode.NotFound; resp.StatusCode = (int)HttpStatusCode.NotFound;
resp.OutputStream.Flush();
return; return;
} }
@ -212,8 +215,8 @@ namespace FakeeDeck.Class
while ((nbytes = input.Read(buffer, 0, buffer.Length)) > 0) while ((nbytes = input.Read(buffer, 0, buffer.Length)) > 0)
resp.OutputStream.Write(buffer, 0, nbytes); resp.OutputStream.Write(buffer, 0, nbytes);
input.Close(); input.Close();
resp.OutputStream.Flush();
resp.StatusCode = (int)HttpStatusCode.OK; resp.StatusCode = (int)HttpStatusCode.OK;
resp.OutputStream.Flush();
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -4,7 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace FakeeDeck.Class namespace FakeDeck.Class
{ {
internal class KeyboardCode internal class KeyboardCode
{ {

View File

@ -7,7 +7,7 @@ using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using YamlDotNet.Serialization; using YamlDotNet.Serialization;
namespace FakeeDeck.Class namespace FakeDeck.Class
{ {
public class YamlHelper public class YamlHelper
{ {

View File

@ -19,6 +19,9 @@
<None Update="StaticFiles\app.js"> <None Update="StaticFiles\app.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Update="StaticFiles\style.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -5,10 +5,10 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:FakeDeck" xmlns:local="clr-namespace:FakeDeck"
mc:Ignorable="d" mc:Ignorable="d"
Title="MainWindow" Height="450" Width="270" Activated="FakeDeckUI_Activated" WindowStartupLocation="CenterScreen"> Title="MainWindow"Activated="FakeDeckUI_Activated" WindowStartupLocation="CenterScreen">
<Grid> <Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="270*"/> <RowDefinition Height="270"/>
<RowDefinition Height="50*"/> <RowDefinition Height="50*"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Image x:Name="qr_code" Margin="10,10,10,10"/> <Image x:Name="qr_code" Margin="10,10,10,10"/>

View File

@ -1,5 +1,5 @@
using FakeDeck.Class; using FakeDeck.Class;
using FakeeDeck.Class; using FakeDeck.Class;
using QRCoder; using QRCoder;
using System.Reflection.Emit; using System.Reflection.Emit;
using System.Text; using System.Text;

View File

@ -1,30 +1,3 @@
[].forEach.call(document.querySelectorAll('form'), function (form) {
form.addEventListener('submit', function (event) {
event.preventDefault();
const target = event.currentTarget;
console.log(target.method, target.action);
console.log(form.method, form.action);
console.log(form === target);
var formData = new FormData(form);
const xhttp = new XMLHttpRequest();
xhttp.onload = function () { }
xhttp.onreadystatechange = function () {
if (xhttp.readyState === 4) {
if (xhttp.status === 200) {
console.log('successful');
} else {
console.log('failed');
}
}
}
xhttp.open(target.method, target.action, true);
xhttp.send(urlencodeFormData(formData));
});
});
function urlencodeFormData(fd){ function urlencodeFormData(fd){
var s = ''; var s = '';
@ -36,3 +9,94 @@ function urlencodeFormData(fd){
} }
return s; return s;
} }
function resizeGrid(){
var width = document.body.clientWidth;
var height = document.body.clientHeight;
var biggerSizeW = (width / 5);
var biggerSizeH = (height / 3);
var biggerSize = biggerSizeW;
if(biggerSizeW < biggerSizeH){
biggerSize = biggerSizeW;
}
console.log(biggerSize);
[].forEach.call(document.querySelectorAll('.button'), function (button) {
var size = biggerSize
button.style.height = size;
button.style.width = size;
//console.log(size);
});
}
function loadPage(pageId){
event.preventDefault();
var formData = new FormData();
formData.append('Key', pageId)
const xhttp = new XMLHttpRequest();
xhttp.onload = function () { }
xhttp.onreadystatechange = function () {
if (xhttp.readyState === 4) {
if (xhttp.status === 200) {
console.log('successful');
document.querySelector('div#main').innerHTML = xhttp.responseText;
console.log(xhttp.responseText);
resizeGrid();
formToAjax();
} else {
console.log('failed');
}
}
}
xhttp.open("POST", "/page", true);
xhttp.send(urlencodeFormData(formData));
}
function formToAjax(){
[].forEach.call(document.querySelectorAll('form'), function (form) {
form.addEventListener('submit', function (event) {
event.preventDefault();
const target = event.currentTarget;
target.style.opacity = "0.5"
console.log(target.method, target.action);
console.log(form.method, form.action);
console.log(form === target);
var formData = new FormData(form);
const xhttp = new XMLHttpRequest();
xhttp.onload = function () { }
xhttp.onreadystatechange = function () {
if (xhttp.readyState === 4) {
if (xhttp.status === 200) {
console.log('successful');
} else {
console.log('failed');
}
target.style.opacity = "1"
}
}
xhttp.open(target.method, target.action, true);
xhttp.send(urlencodeFormData(formData));
});
});
}
window.addEventListener('resize', function(event) {
resizeGrid();
}, true);
window.addEventListener('orientationchange', function(event) {
console.log("Rotated");
resizeGrid();
}, true);
resizeGrid();
formToAjax();

View File

@ -0,0 +1 @@
/*https://stackoverflow.com/questions/62371077/create-dynamic-equal-sized-small-squares-grid-in-fixed-size-big-square/

View File

@ -52,7 +52,62 @@ pages:
parameters: parameters:
- name: Key - name: Key
value: bomb value: bomb
- button: spacer
function: FakeDeckMacro
parameters:
- name: Key
value: "spacer"
- name: Color
value: orange
- button: spacer
function: FakeDeckMacro
parameters:
- name: Key
value: "full-screen"
- name: Color
value: orange
- button: spacer
function: FakeDeckMacro
parameters:
- name: Key
value: "spacer"
- name: Color
value: red
- button: spacer
function: FakeDeckMacro
parameters:
- name: Key
value: "spacer"
- name: Color
value: red
- button: spacer
function: FakeDeckMacro
parameters:
- name: Key
value: "spacer"
- name: Color
value: red
- button: spacer
function: FakeDeckMacro
parameters:
- name: Key
value: "spacer"
- name: Color
value: red
- button: page
function: FakeDeckMacro
parameters:
- name: Key
value: "set-page"
- name: PageId
value: "media"
- name: Image
value: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTdEjIsQcn8NwYWhwISL74xXLGtRHeW1Mn67g&s"
- page: media
buttons:
- button: mute - button: mute
function: MediaMacro function: MediaMacro
parameters: parameters:
@ -76,3 +131,52 @@ pages:
parameters: parameters:
- name: Key - name: Key
value: "next" value: "next"
- button: spacer
function: FakeDeckMacro
parameters:
- name: Key
value: "full-screen"
- name: Color
value: orange
- button: spacer
function: FakeDeckMacro
parameters:
- name: Key
value: "spacer"
- name: Color
value: red
- button: spacer
function: FakeDeckMacro
parameters:
- name: Key
value: "spacer"
- name: Color
value: red
- button: spacer
function: FakeDeckMacro
parameters:
- name: Key
value: "spacer"
- name: Color
value: red
- button: spacer
function: FakeDeckMacro
parameters:
- name: Key
value: "spacer"
- name: Color
value: red
- button: page
function: FakeDeckMacro
parameters:
- name: Key
value: "set-page"
- name: PageId
value: "helldivers"
- name: Image
value: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT2oyk6yqmBxt9ejwqBaordr6X9s-dZFnHrvg&s"