Add tool configuration management and enhance UI functionality
Introduce `ToolConfigStore` for managing tool configuration files, enabling retrieval and updates. Refactor window handling to support Lua timeout settings and dynamic tool-specific configurations. Improve HTML UI with Lua timeout adjustments and centralized styling updates.
This commit is contained in:
@@ -42,7 +42,8 @@ elseif (UNIX)
|
|||||||
set(LIBS ${APPINDICATOR_LIBRARIES})
|
set(LIBS ${APPINDICATOR_LIBRARIES})
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
file(GLOB_RECURSE SOURCES "src/*.cpp" "inc/*.h") # Nur für .cpp und .h
|
file(GLOB_RECURSE SOURCES "src/*.cpp" "inc/*.h")
|
||||||
|
list(APPEND SOURCES "src/toolConfig.cpp") # Nur für .cpp und .h
|
||||||
file(GLOB_RECURSE MODULE_SOURCES "module/*.ixx") # Separates GLOB für Module
|
file(GLOB_RECURSE MODULE_SOURCES "module/*.ixx") # Separates GLOB für Module
|
||||||
|
|
||||||
add_executable(Toolbox main.cpp
|
add_executable(Toolbox main.cpp
|
||||||
@@ -72,7 +73,7 @@ if (WIN32)
|
|||||||
endif ()
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
saucer_embed("res")
|
saucer_embed("res" TARGET ${PROJECT_NAME})
|
||||||
|
|
||||||
CPMFindPackage(
|
CPMFindPackage(
|
||||||
NAME saucer-desktop
|
NAME saucer-desktop
|
||||||
@@ -85,7 +86,7 @@ target_link_libraries(
|
|||||||
PRIVATE
|
PRIVATE
|
||||||
saucer::saucer
|
saucer::saucer
|
||||||
sol2::sol2
|
sol2::sol2
|
||||||
lua
|
lua::lib
|
||||||
tray
|
tray
|
||||||
nlohmann_json
|
nlohmann_json
|
||||||
cppcodec
|
cppcodec
|
||||||
|
|||||||
@@ -5,12 +5,20 @@
|
|||||||
#include <saucer/embedded/all.hpp>
|
#include <saucer/embedded/all.hpp>
|
||||||
#include <sol/sol.hpp>
|
#include <sol/sol.hpp>
|
||||||
#include <saucer/webview.hpp>
|
#include <saucer/webview.hpp>
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
class optionWindow {
|
class optionWindow {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Konstruktor erhält das Application-Objekt als Parameter
|
// Konstruktor erhält das Application-Objekt als Parameter
|
||||||
explicit optionWindow(std::shared_ptr<saucer::application>& app);
|
optionWindow(std::shared_ptr<saucer::application>& app,
|
||||||
|
std::function<int()> getLuaTimeoutSeconds,
|
||||||
|
std::function<void(int)> setLuaTimeoutSeconds,
|
||||||
|
std::function<std::string()> getActiveToolName,
|
||||||
|
std::function<std::string()> getToolConfigIni,
|
||||||
|
std::function<void(const std::string &)> setToolConfigIni,
|
||||||
|
std::function<void()> openIndex);
|
||||||
|
|
||||||
// Methode zum Anzeigen des Fensters
|
// Methode zum Anzeigen des Fensters
|
||||||
void show();
|
void show();
|
||||||
@@ -18,13 +26,22 @@ public:
|
|||||||
// Für die Fensterinitialisierung
|
// Für die Fensterinitialisierung
|
||||||
void initialize();
|
void initialize();
|
||||||
void setHWND(HWND hwnd);
|
void setHWND(HWND hwnd);
|
||||||
|
void toggleDevTools();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<saucer::application> m_app;
|
std::shared_ptr<saucer::application> m_app;
|
||||||
saucer::smartview<saucer::default_serializer> m_webview;
|
saucer::smartview m_webview;
|
||||||
|
std::unique_ptr<hwnd_module> m_hwnd_module;
|
||||||
HWND m_hwnd;
|
HWND m_hwnd;
|
||||||
|
std::function<int()> m_getLuaTimeoutSeconds;
|
||||||
|
std::function<void(int)> m_setLuaTimeoutSeconds;
|
||||||
|
std::function<std::string()> m_getActiveToolName;
|
||||||
|
std::function<std::string()> m_getToolConfigIni;
|
||||||
|
std::function<void(const std::string &)> m_setToolConfigIni;
|
||||||
|
std::function<void()> m_openIndex;
|
||||||
|
|
||||||
void configureWindow();
|
void configureWindow();
|
||||||
void loadResources();
|
void loadResources();
|
||||||
void runLuaScript();
|
void runLuaScript();
|
||||||
|
void exposeToJs();
|
||||||
};
|
};
|
||||||
|
|||||||
13
inc/toolConfig.h
Normal file
13
inc/toolConfig.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class ToolConfigStore {
|
||||||
|
public:
|
||||||
|
bool ensureExists(const std::filesystem::path &path) const;
|
||||||
|
int getInt(const std::filesystem::path &path, const std::string &key, int fallback) const;
|
||||||
|
void setInt(const std::filesystem::path &path, const std::string &key, int value) const;
|
||||||
|
std::string readAll(const std::filesystem::path &path) const;
|
||||||
|
void writeAll(const std::filesystem::path &path, const std::string &content) const;
|
||||||
|
};
|
||||||
Submodule lib/saucer updated: 392ee02623...9f83e27d55
4
main.cpp
4
main.cpp
@@ -32,9 +32,9 @@ coco::stray start(saucer::application *app){
|
|||||||
|
|
||||||
// Tray-Menü definieren
|
// Tray-Menü definieren
|
||||||
tray_menu tray_menu_items[] = {
|
tray_menu tray_menu_items[] = {
|
||||||
{reinterpret_cast<const char*>(u8"Öffnen"), 0, 0, 0, on_click, nullptr},
|
{"Oeffnen", 0, 0, 0, on_click, nullptr},
|
||||||
{"-", 0, 0, 0, nullptr, nullptr}, // Separator
|
{"-", 0, 0, 0, nullptr, nullptr}, // Separator
|
||||||
{reinterpret_cast<const char*>(u8"Beenden"), 0, 0, 0, on_quit, nullptr},
|
{"Beenden", 0, 0, 0, on_quit, nullptr},
|
||||||
{nullptr, 0, 0, 0, nullptr, nullptr} // Ende des Menüs
|
{nullptr, 0, 0, 0, nullptr, nullptr} // Ende des Menüs
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
export module toolboxTray;
|
module;
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include "tray.h"
|
#include "tray.h"
|
||||||
|
|
||||||
|
export module toolboxTray;
|
||||||
|
|
||||||
|
|
||||||
export
|
export
|
||||||
class toolboxTray : public tray {
|
class toolboxTray : public tray {
|
||||||
|
|||||||
@@ -167,7 +167,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<button onclick="getNewContent()" class="button" id="reload-button">↻</button>
|
<button onclick="getNewContent()" class="button" id="reload-button">↻</button>
|
||||||
<button onclick="openEinst()" class="button" id="option-button">⚙️</button>
|
<button onclick="openEinstFirst()" class="button" id="option-button" style="display: none;">⚙️</button>
|
||||||
<h1>Toolbox</h1>
|
<h1>Toolbox</h1>
|
||||||
<button onclick="openFileSystem()" id="file-system-button" class="button">📁</button>
|
<button onclick="openFileSystem()" id="file-system-button" class="button">📁</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -183,6 +183,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function runLuaWithId(event) {
|
function runLuaWithId(event) {
|
||||||
|
event.preventDefault();
|
||||||
if (event.target.tagName === 'BUTTON') {
|
if (event.target.tagName === 'BUTTON') {
|
||||||
// Falls der Button gedrückt wurde, brich die Funktion ab
|
// Falls der Button gedrückt wurde, brich die Funktion ab
|
||||||
return false;
|
return false;
|
||||||
@@ -234,7 +235,7 @@
|
|||||||
: `data:image/png;base64,${item.icon}`;
|
: `data:image/png;base64,${item.icon}`;
|
||||||
|
|
||||||
const toolCardHTML = `
|
const toolCardHTML = `
|
||||||
<a href="${item.url}" class="tool-card"
|
<div class="tool-card" data-url="${item.url}"
|
||||||
data-tool-id="${item.id}"
|
data-tool-id="${item.id}"
|
||||||
onclick="runLuaWithId(event)">
|
onclick="runLuaWithId(event)">
|
||||||
<img src="${iconSrc}" alt="${item.name}">
|
<img src="${iconSrc}" alt="${item.name}">
|
||||||
@@ -243,9 +244,9 @@
|
|||||||
<p>${item.description}</p>
|
<p>${item.description}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="tool-action">
|
<div class="tool-action">
|
||||||
<button>Einst</button>
|
<button onclick="openEinst(event, ${item.id})">Einst</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
toolbox.innerHTML += toolCardHTML;
|
toolbox.innerHTML += toolCardHTML;
|
||||||
@@ -279,13 +280,32 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function openEinst(){
|
function openEinst(event, toolId){
|
||||||
|
if (event) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
console.log('Einst Button geklickt!');
|
console.log('Einst Button geklickt!');
|
||||||
saucer.exposed.openEinst();
|
saucer.exposed.openEinst(toolId);
|
||||||
|
}
|
||||||
|
|
||||||
|
function openEinstFirst(){
|
||||||
|
const firstCard = document.querySelector('.tool-card');
|
||||||
|
if (!firstCard) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const toolId = firstCard.getAttribute('data-tool-id');
|
||||||
|
saucer.exposed.openEinst(parseInt(toolId));
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
document.addEventListener('click', (e) => {
|
||||||
|
const link = e.target.closest('a');
|
||||||
|
if (link) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
const toolbox = document.getElementById('toolbox');
|
const toolbox = document.getElementById('toolbox');
|
||||||
|
|
||||||
saucer.exposed.getToolboxItems().then(jsonString => {
|
saucer.exposed.getToolboxItems().then(jsonString => {
|
||||||
@@ -297,7 +317,7 @@
|
|||||||
: `data:image/png;base64,${item.icon}`;
|
: `data:image/png;base64,${item.icon}`;
|
||||||
|
|
||||||
const toolCardHTML = `
|
const toolCardHTML = `
|
||||||
<a href="${item.url}" class="tool-card"
|
<div class="tool-card" data-url="${item.url}"
|
||||||
data-tool-id="${item.id}"
|
data-tool-id="${item.id}"
|
||||||
onclick="runLuaWithId(event)">
|
onclick="runLuaWithId(event)">
|
||||||
<img src="${iconSrc}" alt="${item.name}">
|
<img src="${iconSrc}" alt="${item.name}">
|
||||||
@@ -306,9 +326,9 @@
|
|||||||
<p>${item.description}</p>
|
<p>${item.description}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="tool-action">
|
<div class="tool-action">
|
||||||
<button onclick="openEinst(event)">Einst</button>
|
<button onclick="openEinst(event, ${item.id})">Einst</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
toolbox.innerHTML += toolCardHTML;
|
toolbox.innerHTML += toolCardHTML;
|
||||||
|
|||||||
100
src/toolConfig.cpp
Normal file
100
src/toolConfig.cpp
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
#include "toolConfig.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
bool ToolConfigStore::ensureExists(const std::filesystem::path &path) const {
|
||||||
|
if (path.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (std::filesystem::exists(path)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
std::ofstream out(path);
|
||||||
|
if (!out) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out << "lua_timeout_seconds=30\n";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool parse_key_value(const std::string &line, std::string &key, std::string &value) {
|
||||||
|
const auto pos = line.find('=');
|
||||||
|
if (pos == std::string::npos) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
key = line.substr(0, pos);
|
||||||
|
value = line.substr(pos + 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ToolConfigStore::getInt(const std::filesystem::path &path, const std::string &key, int fallback) const {
|
||||||
|
if (!std::filesystem::exists(path)) {
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
std::ifstream in(path);
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(in, line)) {
|
||||||
|
std::string k, v;
|
||||||
|
if (!parse_key_value(line, k, v)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (k == key) {
|
||||||
|
try {
|
||||||
|
return std::max(0, std::stoi(v));
|
||||||
|
} catch (...) {
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToolConfigStore::setInt(const std::filesystem::path &path, const std::string &key, int value) const {
|
||||||
|
std::vector<std::string> lines;
|
||||||
|
if (std::filesystem::exists(path)) {
|
||||||
|
std::ifstream in(path);
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(in, line)) {
|
||||||
|
lines.push_back(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool updated = false;
|
||||||
|
for (auto &line : lines) {
|
||||||
|
std::string k, v;
|
||||||
|
if (parse_key_value(line, k, v) && k == key) {
|
||||||
|
line = k + "=" + std::to_string(std::max(0, value));
|
||||||
|
updated = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!updated) {
|
||||||
|
lines.push_back(key + "=" + std::to_string(std::max(0, value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ofstream out(path);
|
||||||
|
for (const auto &line : lines) {
|
||||||
|
out << line << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ToolConfigStore::readAll(const std::filesystem::path &path) const {
|
||||||
|
if (path.empty() || !std::filesystem::exists(path)) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
std::ifstream in(path);
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << in.rdbuf();
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToolConfigStore::writeAll(const std::filesystem::path &path, const std::string &content) const {
|
||||||
|
if (path.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::ofstream out(path);
|
||||||
|
out << content;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user