Add "Einstellungen" interface and improve Lua execution flow

Introduced a new "Einstellungen" (Settings) interface with an HTML page and integrated it into the application workflow. Enhanced Lua execution handling with optional console output and improved UI updates. Adjusted installer UI to better align buttons and icons with user experience.
This commit is contained in:
2024-12-16 23:16:22 +01:00
parent 5b61db140e
commit f5dd50a9f7
13 changed files with 379 additions and 64 deletions

View File

@@ -1,13 +1,49 @@
#pragma once
#include "tray.h"
#include "toolboxWindow.h"
class toolboxTray {
#include <functional>
class toolboxTray : public tray {
public:
// Konstruktor mit optionalen Parametern für Icon und Tooltip
toolboxTray(const char* icon = nullptr, const char* tooltip = nullptr) {
this->icon = icon;
this->tooltip = const_cast<char*>(tooltip);
this->menu = nullptr; // Initialisiere ohne Menü (kann später gesetzt werden)
}
// Funktion, um die gewünschte Aktion für den Linksklick zu setzen
void setLeftClickAction(const std::function<void()>& action) {
leftClickAction = action;
}
// Funktion zum Setzen des Tray-Menüs
void setTrayMenu(tray_menu* menu) {
this->menu = menu;
}
// Ereignis-Handler für Mausklicks
void handleMouseClick(int button) {
if (button == LEFT_CLICK && leftClickAction) {
// Führt die Linksklick-Aktion aus
leftClickAction();
} else if (button == RIGHT_CLICK) {
// Zeigt das Menü
showMenu();
}
}
enum MouseButton {
LEFT_CLICK = 0,
RIGHT_CLICK = 1
};
private:
std::function<void()> leftClickAction; // Aktion für Linksklick
// Zeigt das Menü an (Rechtsklick)
void showMenu() {
if (this->menu) {
tray_update(this); // Update des Trays mit dem Menü
}
}
};

View File

@@ -72,4 +72,8 @@ private:
void open_file_system();
void SetJsonItems();
void openEinst();
void openIndex();
};

View File

@@ -1,16 +0,0 @@
//
// Created by slave on 06.12.2024.
//
#ifndef TOOLBOX_TOOLBOX_TRAY_H
#define TOOLBOX_TOOLBOX_TRAY_H
#include "tray.h"
class toolbox_tray {
};
#endif //TOOLBOX_TOOLBOX_TRAY_H

View File

@@ -7,8 +7,8 @@ def encode_file_to_base64(file_path):
# Base64-kodierte Strings generieren
exe_base64 = encode_file_to_base64("D:/Repos/toolbox/cmake-build-release-visual-studio/Toolbox.exe")
icon_base64 = encode_file_to_base64("D:/Repos/toolbox/cmake-build-release-visual-studio/toolbox.ico")
exe_base64 = encode_file_to_base64("D:/Repos/toolbox/cmake-build-minsizerel-visual-studio/Toolbox.exe")
icon_base64 = encode_file_to_base64("D:/Repos/toolbox/cmake-build-MinSizeRel-visual-studio/toolbox.ico")
# Base64-Strings in eine Python-Datei schreiben
with open("base64_strings.py", 'w') as py_file:

View File

@@ -78,7 +78,7 @@ def extract_files():
return
exe_path = os.path.join(output_directory, "application.exe")
icon_path = os.path.join(output_directory, "icon.ico")
icon_path = os.path.join(output_directory, "toolbox.ico")
try:
# Ensure the output directory exists
@@ -107,7 +107,8 @@ def show_readme():
"Vielen Dank, dass Sie 'Toolbox' installiert haben!\n\nWeitere Informationen finden Sie auf unserer Website.")
readme_text.configure(state='disabled')
readme_text.pack(pady=10)
Button(readme_window, text="Beenden", command=root.quit).pack(pady=10)
button = Button(readme_window, text="Beenden", command=root.quit)
button.place(relx=0.9, rely=0.9, anchor='se')
def next_page():
@@ -130,7 +131,10 @@ def setup_page_1():
Label(welcome_page, text="Willkommen beim Installer!", bg="#2e2e2e", fg="white", font=("Helvetica", 16)).pack(
pady=20)
Label(welcome_page, text="Klicken Sie auf 'Weiter', um fortzufahren.", bg="#2e2e2e", fg="white").pack(pady=10)
Button(welcome_page, text="Weiter", command=lambda: (welcome_page.pack_forget(), next_page())).pack()
# Button unten rechts positionieren
button = Button(welcome_page, text="Weiter", command=lambda: (welcome_page.pack_forget(), next_page()))
button.place(relx=0.9, rely=0.9, anchor='se') # Position relativ, unten rechts ankern
def setup_page_2():
@@ -143,7 +147,8 @@ def setup_page_2():
Label(folder_page, text="Installationsordner wählen:", bg="#2e2e2e", fg="white").pack(pady=5)
Entry(folder_page, textvariable=output_dir_var, width=50).pack(pady=5)
Button(folder_page, text="Durchsuchen...", command=select_directory).pack(pady=5)
Button(folder_page, text="Weiter", command=lambda: (folder_page.pack_forget(), next_page())).pack()
button = Button(folder_page, text="Weiter", command=lambda: (folder_page.pack_forget(), next_page()))
button.place(relx=0.9, rely=0.9, anchor='se')
def setup_page_3():
@@ -157,7 +162,8 @@ def setup_page_3():
progress_bar = Progressbar(progress_page, orient='horizontal', length=400, variable=progress_var,
style='Horizontal.TProgressbar')
progress_bar.pack(pady=10)
Button(progress_page, text="Weiter", command=lambda: (progress_page.pack_forget(), show_readme())).pack()
button = Button(progress_page, text="Weiter", command=lambda: (progress_page.pack_forget(), show_readme()))
button.place(relx=0.9, rely=0.9, anchor='se')
# Tkinter Setup

View File

@@ -1,20 +1,21 @@
#include <saucer/app.hpp>
#include "toolboxWindow.h"
#include "tray.h"
#include "toolboxTray.h"
#include "resource.h"
ToolboxWindow* g_toolboxWindow = nullptr;
void on_quit(struct tray_menu *item) {
tray_exit();
}
void on_click(struct tray_menu *item) {
if (g_toolboxWindow->m_bShow)
g_toolboxWindow->hide();
else
g_toolboxWindow->show();
void on_click(struct tray_menu *item = nullptr) {
if (g_toolboxWindow) {
if (g_toolboxWindow->m_bShow)
g_toolboxWindow->hide();
else
g_toolboxWindow->show();
}
}
int start(){
@@ -33,17 +34,24 @@ int start(){
HICON hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1));
struct tray_menu tray_menu_items[] = {
{"<EFBFBD>ffnen", 0, 0, NULL, on_click, 0},
{"-", 0, 0, NULL, nullptr, 0},
{"Beenden", 0, 0, NULL, on_quit, 0},
{nullptr, 0, 0, NULL, nullptr, 0}
// Tray-Men<65> definieren
tray_menu tray_menu_items[] = {
{"<EFBFBD>ffnen", 0, 0, 0, on_click, nullptr},
{"-", 0, 0, 0, nullptr, nullptr}, // Separator
{"Beenden", 0, 0, 0, on_quit, nullptr},
{nullptr, 0, 0, 0, nullptr, nullptr} // Ende des Men<65>s
};
struct tray tray = {
.icon = (char*)"toolbox.ico",
.menu = tray_menu_items
};
// ToolboxTray erstellen
toolboxTray tray("toolbox.ico", "Toolbox Application Tray");
// Linksklick-Aktion registrieren
tray.setLeftClickAction([&]() {
on_click(nullptr); // Ruft die Funktion ohne Men<65>eintrag auf
});
// Tray-Men<65> registrieren
tray.setTrayMenu(tray_menu_items);
if (tray_init(&tray) != 0) {
fprintf(stderr, "Fehler beim Initialisieren des Tray-Icons\n");

View File

@@ -548,6 +548,7 @@
#include "highlight/styles/xt256.css.hpp"
#include "highlight/styles/xt256.min.css.hpp"
#include "html/card.html.hpp"
#include "html/einstellungen.html.hpp"
#include "html/index.html.hpp"
#include "ico/toolbox.ico.hpp"
#include "ico/toolbox.png.hpp"
@@ -1101,6 +1102,7 @@ namespace saucer::embedded
rtn.emplace("highlight/styles/xt256.css", embedded_file{saucer::stash<>::view(fUWoQiic40oj5L8WEC0J0jDKrtdvLGPz55zyhk7LANYvPT5eDQFdJ2vrLGOC5RKN), "text/css"});
rtn.emplace("highlight/styles/xt256.min.css", embedded_file{saucer::stash<>::view(f2J7n4DMan7D1rUB7RCLarIP9jvSTrI3Dg4IbJEiAP4b1hm5BW1MsjoXnhX1DGgEscptw3), "text/css"});
rtn.emplace("html/card.html", embedded_file{saucer::stash<>::view(fIMvMxLtCtgaCyOWT9Sq2cpZQFAUlr60fpjd781IKV2QwoDk), "text/html"});
rtn.emplace("html/einstellungen.html", embedded_file{saucer::stash<>::view(fQt4XIqDkpTIgFZJ9KikZeaUdc9ZBOG3PdMTC9xmECkDkS82l8YcpHknBBMq), "text/html"});
rtn.emplace("html/index.html", embedded_file{saucer::stash<>::view(f1Dqesn4NxFvpVZNG4N54sqKwGMdL3bEomjcPeIDDbCgBnsxvo), "text/html"});
rtn.emplace("ico/toolbox.ico", embedded_file{saucer::stash<>::view(f1Dqesn4NxFvpVZNG4N54sqKwGMdL3bfGtRIoHuavdKqwZ8lSx), "image/vnd.microsoft.icon"});
rtn.emplace("ico/toolbox.png", embedded_file{saucer::stash<>::view(f1Dqesn4NxFvpVZNG4N54sqKwGMdL3bfGtRIoHuavdKqwZAhXT), "image/png"});

File diff suppressed because one or more lines are too long

215
res/html/einstellungen.html Normal file
View File

@@ -0,0 +1,215 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Toolbox</title>
<link rel="stylesheet" href="../highlight/styles/github-dark.css">
<style>
body {
font-family: Arial, sans-serif;
background: linear-gradient(to bottom, #1e1e2e, #28293d);
color: white;
margin: 0;
padding: 0;
display: flex;
height: 100vh;
}
/* Linke Sidebar */
.sidebar {
width: 200px;
background-color: #2b2c3b;
padding: 15px;
box-shadow: 2px 0 5px rgba(0, 0, 0, 0.3);
overflow-y: auto;
}
.sidebar h2 {
color: #ff79c6;
font-size: 16px;
margin: 0 0 15px 0;
}
.sidebar ul {
list-style: none;
padding: 0;
margin: 0;
}
.sidebar ul li {
margin-bottom: 10px;
}
.sidebar ul li a {
text-decoration: none;
padding: 10px;
display: block;
border-radius: 4px;
background: #32334a;
color: #fff;
transition: background 0.3s;
}
.sidebar ul li a:hover {
background: #ff79c6;
color: #000;
}
/* Hauptbereich mit flexibler Anzeige */
.main-container {
flex: 1;
display: flex;
flex-direction: column;
}
.header {
background: #1b1b2b;
padding: 15px 20px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
display: flex;
align-items: center;
justify-content: space-between;
}
.header h1 {
margin: 0;
font-size: 18px;
color: #ff79c6;
}
.back-button {
background: #2b2c3b;
border: none;
color: #ff79c6;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
transition: background 0.3s;
}
.back-button:hover {
background: #32334a;
}
.editor {
flex: 1;
background: #1e1e2e;
padding: 15px;
display: none; /* Standardmäßig ausgeblendet */
flex-direction: column;
align-items: center;
justify-content: center;
}
.editor textarea {
width: 80%;
height: 80%;
background: #2b2c3b;
color: #fff;
border: 1px solid #ff79c6;
border-radius: 5px;
font-size: 14px;
padding: 10px;
font-family: monospace;
}
.editor pre {
width: 80%;
margin-top: 10px;
background: #2b2c3b;
color: #fff;
border: 1px solid #32334a;
border-radius: 5px;
padding: 10px;
overflow-x: auto;
}
.footer {
background: #1b1b2b;
padding: 10px 20px;
text-align: center;
font-size: 12px;
color: #aaa;
}
</style>
</head>
<body>
<!-- Sidebar für Optionen -->
<div class="sidebar">
<h2>Einstellungen</h2>
<ul>
<li><a href="#" onclick="showContent('none')">Einstellungen</a></li>
<li><a href="#" onclick="showContent('editor')">Skript</a></li>
<li><a href="#" onclick="showContent('none')">Option 3</a></li>
<li><a href="#" onclick="showContent('none')">Option 4</a></li>
</ul>
</div>
<!-- Hauptcontainer -->
<div class="main-container">
<!-- Header mit Zurück-Button -->
<div class="header">
<h1>Einstellungen</h1>
<button class="back-button" onclick="goBack()">Zurück</button>
</div>
<!-- Zentraler Editor (Standardmäßig versteckt) -->
<div class="editor" id="editor">
<textarea id="code-editor" placeholder="Write Lua code here..."></textarea>
<pre><code id="highlightedOutput" class="language-lua"></code></pre>
</div>
<!-- Footer -->
<div class="footer">
<!--Schmidti.Digital &copy; 2024-->
</div>
</div>
<script src="../highlight/highlight.min.js"></script>
<script src="../highlight/languages/lua.min.js"></script>
<script>hljs.highlightAll();</script>
<script>
function goBack() {
saucer.exposed.openIndex();
}
function showContent(option) {
const editor = document.getElementById('editor');
// Editor anzeigen, wenn "Option 2" ausgewählt wird
if (option === 'editor') {
editor.style.display = 'flex';
} else {
editor.style.display = 'none';
}
}
document.addEventListener('DOMContentLoaded', (event) => {
const editor = document.getElementById('code-editor');
const output = document.getElementById('highlightedOutput');
editor.addEventListener('input', () => {
// Update the code block with the content of the textarea
output.textContent = editor.value;
// Apply syntax highlighting
hljs.highlightElement(output);
});
// Optional: Adjust the height of the textarea to match the content
editor.addEventListener('input', () => {
// Update the code block with the content of the textarea
output.textContent = editor.value;
// Apply syntax highlighting
hljs.highlightElement(output);
});
function adjustTextareaHeight() {
editor.style.height = 'auto';
editor.style.height = editor.scrollHeight + 'px';
}
});
</script>
</body>
</html>

View File

@@ -156,6 +156,10 @@
<!--Schmidti.Digital &copy; 2024-->
</div><script>
function runLuaWithId(event) {
if (event.target.tagName === 'BUTTON') {
// Falls der Button gedrückt wurde, brich die Funktion ab
return false;
}
const button = event.target;
const toolCard = button.closest('.tool-card');
@@ -248,6 +252,12 @@
}
}
function openEinst(){
event.stopPropagation();
console.log('Einst Button geklickt!');
saucer.exposed.openEinst();
}
document.addEventListener('DOMContentLoaded', () => {
const toolbox = document.getElementById('toolbox');
@@ -260,18 +270,18 @@
: `data:image/png;base64,${item.icon}`;
const toolCardHTML = `
<a href="${item.url}" class="tool-card"
data-tool-id="${item.id}"
onclick="runLuaWithId(event)">
<img src="${iconSrc}" alt="${item.name}">
<div class="tool-info">
<h3>${item.name}</h3>
<p>${item.description}</p>
</div>
<div class="tool-action">
<button>Einst</button>
</div>
</a>
<a href="${item.url}" class="tool-card"
data-tool-id="${item.id}"
onclick="runLuaWithId(event)">
<img src="${iconSrc}" alt="${item.name}">
<div class="tool-info">
<h3>${item.name}</h3>
<p>${item.description}</p>
</div>
<div class="tool-action">
<button onclick="openEinst(event)">Einst</button>
</div>
</a>
`;
toolbox.innerHTML += toolCardHTML;

View File

@@ -1 +1,2 @@
#include "toolboxTray.h"
#include <Windows.h>
#include "toolboxTray.h"

View File

@@ -107,6 +107,14 @@ void ToolboxWindow::ExposeToJs() {
m_webview.expose("open_file_system", [&]() {
open_file_system();
},saucer::launch::async);
m_webview.expose("openEinst", [&]() {
openEinst();
},saucer::launch::async);
m_webview.expose("openIndex", [&]() {
openIndex();
},saucer::launch::async);
}
void ToolboxWindow::SetJsonItems() {// Konvertierung des Vektors in JSON
@@ -243,29 +251,44 @@ void ToolboxWindow::fillToolboxMenu() {
void ToolboxWindow::run_lua(int id) {
// Öffnet ein CMD-Fenster, falls noch keins offen ist
static bool console_opened = false;
if (!console_opened) {
AllocConsole();
freopen("CONOUT$", "w", stdout); // stdout auf die Konsole umleiten
freopen("CONOUT$", "w", stderr); // stderr auf die Konsole umleiten
console_opened = true;
}
// Lambda-Funktion, um das Lua-Skript auszuführen
auto lua_task = [this, id]() {
sol::state lua;
lua.open_libraries(sol::lib::base,
sol::lib::os,
sol::lib::string,
sol::lib::string,
sol::lib::coroutine,
sol::lib::package,
sol::lib::table,
sol::lib::math,
sol::lib::utf8,
sol::lib::coroutine,
sol::lib::io);
try {
std::string scriptPath = m_toolboxItems[id].lua_script;
std::cout << "Running Lua script: " << scriptPath << std::endl;
// Lua-Skript ausführen
lua.script_file(scriptPath);
m_webview.execute("enableButtonByToolId({})",saucer::make_args(id));
// Nach erfolgreichem Ausführen UI aktualisieren
m_webview.execute("enableButtonByToolId({})", saucer::make_args(id));
m_webview.reload();
} catch (const sol::error& e) {
// Lua-Fehler in der Konsole ausgeben
std::cerr << "Lua error: " << e.what() << std::endl;
m_webview.execute("enableButtonByToolId({})",saucer::make_args(id));
// Nach Fehler UI aktualisieren
m_webview.execute("enableButtonByToolId({})", saucer::make_args(id));
m_webview.reload();
}
};
@@ -273,8 +296,8 @@ void ToolboxWindow::run_lua(int id) {
// Erstellen und starten des Threads
std::thread lua_thread(lua_task);
// Optional: Warten auf den Abschluss des Threads
lua_thread.detach(); // Falls Sie den Thread nicht blockieren wollen
// Thread lösen, um die Anwendung nicht zu blockieren
lua_thread.detach();
std::cout << "Lua-Skript wurde gestartet." << std::endl;
}
@@ -330,3 +353,29 @@ void ToolboxWindow::open_file_system() {
m_webview.execute("reloadContent({})",saucer::make_args());
}
void ToolboxWindow::openEinst() {
auto resources = saucer::embedded::all();
auto it = resources.find("html/einstellungen.html");
if (it == resources.end()) {
std::cerr << "Fehler: 'einstellungen.html' wurde nicht gefunden!" << std::endl;
return;
}
m_webview.serve("html/einstellungen.html");
m_webview.set_decorations(true);
//m_webview.reload();
}
void ToolboxWindow::openIndex() {
m_webview.set_decorations(false);
configureWindow();
fillToolboxMenu();
auto resources = saucer::embedded::all();
auto it = resources.find("html/index.html");
if (it == resources.end()) {
std::cerr << "Fehler: 'einstellungen.html' wurde nicht gefunden!" << std::endl;
return;
}
m_webview.serve("html/index.html");
//m_webview.reload();
}

View File

@@ -2,4 +2,4 @@
// Created by slave on 06.12.2024.
//
#include "toolbox_tray.h"
#include "toolboxTray.h"