Add Cython setup and enhance installer functionality
Introduced a Cython-based setup to compile Python files for performance improvements. Updated installer scripts with customtkinter modifications for better UI, added support for additional content loading, and enhanced project structure. Adjusted build commands, streamlined file paths, and integrated new UI elements in the HTML resources.
This commit is contained in:
@@ -82,4 +82,5 @@ private:
|
|||||||
void openEinst();
|
void openEinst();
|
||||||
|
|
||||||
void openIndex();
|
void openIndex();
|
||||||
|
void getNewContent();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ def encode_file_to_base64(file_path):
|
|||||||
|
|
||||||
|
|
||||||
# Base64-kodierte Strings generieren
|
# Base64-kodierte Strings generieren
|
||||||
exe_base64 = encode_file_to_base64("D:/Repos/toolbox/cmake-build-minsizerel-visual-studio/Toolbox.exe")
|
exe_base64 = encode_file_to_base64("../cmake-build-minsizerel-visual-studio/Toolbox.exe")
|
||||||
icon_base64 = encode_file_to_base64("D:/Repos/toolbox/cmake-build-MinSizeRel-visual-studio/toolbox.ico")
|
icon_base64 = encode_file_to_base64("../res/ico/Toolbox.ico")
|
||||||
|
|
||||||
# Base64-Strings in eine Python-Datei schreiben
|
# Base64-Strings in eine Python-Datei schreiben
|
||||||
with open("base64_strings.py", 'w') as py_file:
|
with open("base64_strings.py", 'w') as py_file:
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
|
|
||||||
|
|
||||||
saucer embed res out_embed
|
saucer embed res out_embed
|
||||||
pyinstaller --onefile --icon=..\res\ico\toolbox.ico --name=toolbox_installer --uac-admin main.py
|
pyinstaller --onefile -key "secretkey" --icon=..\res\ico\toolbox.ico --name=toolbox_installer --add-data "../res/ico/toolbox.ico:." --noconsole --uac-admin main-loader.py
|
||||||
|
python setup.py build_ext --inplace
|
||||||
|
upx --force --best --lzma dist/toolbox_installer.exe
|
||||||
15
installer/main-loader.py
Normal file
15
installer/main-loader.py
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
# Pfad zu deinem `cython`-Ordner
|
||||||
|
cython_dir = os.path.abspath("./cython")
|
||||||
|
|
||||||
|
# Ordner zum Python-Suchpfad hinzufügen
|
||||||
|
if cython_dir not in sys.path:
|
||||||
|
sys.path.insert(0, cython_dir)
|
||||||
|
|
||||||
|
# Importiere die `main.pyd`-Datei
|
||||||
|
import main
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main.run() # Beispiel: Funktion `run()` aufrufen
|
||||||
@@ -1,14 +1,30 @@
|
|||||||
import base64
|
import sys
|
||||||
|
|
||||||
|
import customtkinter as ctk
|
||||||
|
from tkinter import filedialog, StringVar, DoubleVar, messagebox
|
||||||
import os
|
import os
|
||||||
from tkinter import Tk, Button, Label, Entry, filedialog, messagebox, StringVar, DoubleVar, Frame, Text
|
import base64
|
||||||
from tkinter.ttk import Progressbar, Style
|
|
||||||
import base64_strings
|
import base64_strings
|
||||||
|
|
||||||
# Base64-Strings für die Dateien
|
# Base64-Strings für die Dateien
|
||||||
exe_base64 = base64_strings.exe_base64
|
exe_base64 = base64_strings.exe_base64
|
||||||
icon_base64 = base64_strings.icon_base64
|
icon_base64 = base64_strings.icon_base64
|
||||||
|
|
||||||
|
# Setup für Stil und Farben
|
||||||
|
def apply_custom_styles():
|
||||||
|
ctk.set_appearance_mode("dark") # Dark Mode
|
||||||
|
ctk.set_default_color_theme("blue")
|
||||||
|
|
||||||
|
global style_options
|
||||||
|
style_options = {
|
||||||
|
"bg_color": "#1e1e2e",
|
||||||
|
"text_color": "#ff79c6",
|
||||||
|
"button_hover_color": "#ff47b4",
|
||||||
|
"inactive_button_color": "#777",
|
||||||
|
"progress_color": "#ff79c6",
|
||||||
|
}
|
||||||
|
|
||||||
|
# Funktionen für die Installation
|
||||||
def decode_base64_to_file(base64_str, output_path, progress_callback=None):
|
def decode_base64_to_file(base64_str, output_path, progress_callback=None):
|
||||||
"""Decodes a Base64 string and writes it to a file."""
|
"""Decodes a Base64 string and writes it to a file."""
|
||||||
data = base64.b64decode(base64_str)
|
data = base64.b64decode(base64_str)
|
||||||
@@ -20,168 +36,196 @@ def decode_base64_to_file(base64_str, output_path, progress_callback=None):
|
|||||||
if progress_callback:
|
if progress_callback:
|
||||||
progress_callback(min((i + chunk_size) / total_bytes * 100, 100))
|
progress_callback(min((i + chunk_size) / total_bytes * 100, 100))
|
||||||
|
|
||||||
|
|
||||||
def update_progress(value):
|
def update_progress(value):
|
||||||
"""Updates the progress bar."""
|
"""Updates the progress bar."""
|
||||||
progress_var.set(value)
|
progress_var.set(value)
|
||||||
root.update_idletasks()
|
root.update_idletasks()
|
||||||
|
|
||||||
|
|
||||||
def select_directory():
|
def select_directory():
|
||||||
"""Opens a directory selection dialog."""
|
"""Opens a directory selection dialog."""
|
||||||
directory = filedialog.askdirectory(
|
directory = filedialog.askdirectory(
|
||||||
title="Select Output Directory",
|
title="Installationsordner auswählen"
|
||||||
initialdir=output_dir_var.get() or os.path.expandvars('%PROGRAMFILES(X86)%')
|
|
||||||
)
|
)
|
||||||
if directory:
|
if directory:
|
||||||
os.makedirs(directory, exist_ok=True) # Create the folder if it doesn't exist
|
|
||||||
output_dir_var.set(directory)
|
output_dir_var.set(directory)
|
||||||
|
|
||||||
|
|
||||||
def create_shortcut(target, shortcut_name, icon_path):
|
|
||||||
"""Creates shortcuts on Desktop and Startup folder."""
|
|
||||||
desktop = os.path.join(os.environ['USERPROFILE'], 'Desktop')
|
|
||||||
path = os.path.join(desktop, shortcut_name + ".lnk")
|
|
||||||
|
|
||||||
startup = os.path.join(os.getenv('APPDATA'), r'Microsoft\Windows\Start Menu\Programs\Startup')
|
|
||||||
startup_shortcut = os.path.join(startup, shortcut_name + ".lnk")
|
|
||||||
|
|
||||||
vbs_script = f'''
|
|
||||||
Set oWS = WScript.CreateObject("WScript.Shell")
|
|
||||||
sLinkFile = "{path}"
|
|
||||||
Set oLink = oWS.CreateShortcut(sLinkFile)
|
|
||||||
oLink.TargetPath = "{target}"
|
|
||||||
oLink.IconLocation = "{icon_path}"
|
|
||||||
oLink.Save
|
|
||||||
'''
|
|
||||||
startup_vbs_script = f'''
|
|
||||||
Set oWS = WScript.CreateObject("WScript.Shell")
|
|
||||||
sLinkFile = "{startup_shortcut}"
|
|
||||||
Set oLink = oWS.CreateShortcut(sLinkFile)
|
|
||||||
oLink.TargetPath = "{target}"
|
|
||||||
oLink.IconLocation = "{icon_path}"
|
|
||||||
oLink.Save
|
|
||||||
'''
|
|
||||||
|
|
||||||
for script, output in [(vbs_script, "create_shortcut.vbs"), (startup_vbs_script, "create_startup_shortcut.vbs")]:
|
|
||||||
with open(output, "w") as file:
|
|
||||||
file.write(script)
|
|
||||||
os.system(f"wscript {output}")
|
|
||||||
os.remove(output)
|
|
||||||
|
|
||||||
|
|
||||||
def extract_files():
|
def extract_files():
|
||||||
"""Extracts the files to the selected directory and creates shortcuts."""
|
"""Extracts the files to the selected directory and creates shortcuts."""
|
||||||
output_directory = output_dir_var.get()
|
output_directory = output_dir_var.get()
|
||||||
if not output_directory:
|
if not output_directory:
|
||||||
messagebox.showerror("Error", "Please select a valid output directory.")
|
messagebox.showerror("Fehler", "Bitte wählen Sie einen gültigen Installationsordner.")
|
||||||
return
|
return
|
||||||
|
|
||||||
exe_path = os.path.join(output_directory, "application.exe")
|
exe_path = os.path.join(output_directory, "application.exe")
|
||||||
icon_path = os.path.join(output_directory, "toolbox.ico")
|
icon_path = os.path.join(output_directory, "toolbox.ico")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Ensure the output directory exists
|
# Sicherstellen, dass der Ordner existiert
|
||||||
os.makedirs(output_directory, exist_ok=True)
|
os.makedirs(output_directory, exist_ok=True)
|
||||||
|
|
||||||
# Decode and save files
|
# Dateien decodieren und speichern
|
||||||
decode_base64_to_file(exe_base64, exe_path, update_progress)
|
decode_base64_to_file(exe_base64, exe_path, update_progress)
|
||||||
decode_base64_to_file(icon_base64, icon_path, update_progress)
|
decode_base64_to_file(icon_base64, icon_path, update_progress)
|
||||||
|
|
||||||
# Create shortcuts
|
messagebox.showinfo("Erfolg", "Installation abgeschlossen!")
|
||||||
create_shortcut(exe_path, "Toolbox", icon_path)
|
|
||||||
|
|
||||||
messagebox.showinfo("Success", "Installation abgeschlossen!")
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
messagebox.showerror("Error", f"Failed to extract files: {e}")
|
messagebox.showerror("Fehler", f"Fehler beim Extrahieren der Dateien: {e}")
|
||||||
|
|
||||||
|
|
||||||
def show_readme():
|
|
||||||
"""Displays the final README page."""
|
|
||||||
readme_window = Frame(root, bg='#2e2e2e')
|
|
||||||
readme_window.pack(fill='both', expand=True)
|
|
||||||
Label(readme_window, text="Installation abgeschlossen!", bg="#2e2e2e", fg="white", font=("Helvetica", 16)).pack(
|
|
||||||
pady=20)
|
|
||||||
readme_text = Text(readme_window, bg="#444", fg="white", wrap='word', height=10, width=50)
|
|
||||||
readme_text.insert('1.0',
|
|
||||||
"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 = Button(readme_window, text="Beenden", command=root.quit)
|
|
||||||
button.place(relx=0.9, rely=0.9, anchor='se')
|
|
||||||
|
|
||||||
|
|
||||||
def next_page():
|
|
||||||
"""Handles the navigation between pages."""
|
|
||||||
global current_page
|
|
||||||
if current_page == 1:
|
|
||||||
setup_page_2()
|
|
||||||
elif current_page == 2:
|
|
||||||
extract_files()
|
|
||||||
setup_page_3()
|
|
||||||
|
|
||||||
|
|
||||||
|
# Seiten-Setup
|
||||||
def setup_page_1():
|
def setup_page_1():
|
||||||
"""Sets up the welcome page."""
|
for widget in root.winfo_children():
|
||||||
global current_page
|
widget.destroy()
|
||||||
current_page = 1
|
|
||||||
welcome_page = Frame(root, bg='#2e2e2e')
|
|
||||||
welcome_page.pack(fill='both', expand=True)
|
|
||||||
|
|
||||||
Label(welcome_page, text="Willkommen beim Installer!", bg="#2e2e2e", fg="white", font=("Helvetica", 16)).pack(
|
welcome_label = ctk.CTkLabel(
|
||||||
pady=20)
|
root,
|
||||||
Label(welcome_page, text="Klicken Sie auf 'Weiter', um fortzufahren.", bg="#2e2e2e", fg="white").pack(pady=10)
|
text="Willkommen bei der Installation!",
|
||||||
|
font=("Arial", 16),
|
||||||
|
text_color=style_options["text_color"],
|
||||||
|
)
|
||||||
|
welcome_label.pack(pady=20)
|
||||||
|
|
||||||
# Button unten rechts positionieren
|
description_label = ctk.CTkLabel(
|
||||||
button = Button(welcome_page, text="Weiter", command=lambda: (welcome_page.pack_forget(), next_page()))
|
root, text="Klicken Sie auf 'Weiter', um fortzufahren.", text_color="#bbb"
|
||||||
button.place(relx=0.9, rely=0.9, anchor='se') # Position relativ, unten rechts ankern
|
)
|
||||||
|
description_label.pack(pady=10)
|
||||||
|
|
||||||
|
next_button = ctk.CTkButton(
|
||||||
|
root,
|
||||||
|
text="Weiter",
|
||||||
|
fg_color=style_options["text_color"],
|
||||||
|
hover_color=style_options["button_hover_color"],
|
||||||
|
text_color="white",
|
||||||
|
command=setup_page_2,
|
||||||
|
)
|
||||||
|
next_button.place(relx=1.0, rely=1.0, anchor="se", x=-20, y=-20)
|
||||||
|
|
||||||
def setup_page_2():
|
def setup_page_2():
|
||||||
"""Sets up the installation folder selection page."""
|
for widget in root.winfo_children():
|
||||||
global current_page
|
widget.destroy()
|
||||||
current_page = 2
|
|
||||||
folder_page = Frame(root, bg='#2e2e2e')
|
|
||||||
folder_page.pack(fill='both', expand=True)
|
|
||||||
|
|
||||||
Label(folder_page, text="Installationsordner wählen:", bg="#2e2e2e", fg="white").pack(pady=5)
|
folder_label = ctk.CTkLabel(
|
||||||
Entry(folder_page, textvariable=output_dir_var, width=50).pack(pady=5)
|
root,
|
||||||
Button(folder_page, text="Durchsuchen...", command=select_directory).pack(pady=5)
|
text="Installationsordner wählen:",
|
||||||
button = Button(folder_page, text="Weiter", command=lambda: (folder_page.pack_forget(), next_page()))
|
font=("Arial", 14),
|
||||||
button.place(relx=0.9, rely=0.9, anchor='se')
|
text_color=style_options["text_color"],
|
||||||
|
)
|
||||||
|
folder_label.pack(pady=10)
|
||||||
|
|
||||||
|
folder_entry = ctk.CTkEntry(
|
||||||
|
root,
|
||||||
|
textvariable=output_dir_var,
|
||||||
|
placeholder_text="Pfad auswählen",
|
||||||
|
fg_color=style_options["bg_color"],
|
||||||
|
text_color="white",
|
||||||
|
)
|
||||||
|
folder_entry.pack(pady=10)
|
||||||
|
|
||||||
|
browse_button = ctk.CTkButton(
|
||||||
|
root,
|
||||||
|
text="Durchsuchen",
|
||||||
|
fg_color=style_options["text_color"],
|
||||||
|
hover_color=style_options["button_hover_color"],
|
||||||
|
text_color="white",
|
||||||
|
command=select_directory,
|
||||||
|
)
|
||||||
|
browse_button.pack(pady=10)
|
||||||
|
|
||||||
|
next_button = ctk.CTkButton(
|
||||||
|
root,
|
||||||
|
text="Weiter",
|
||||||
|
fg_color=style_options["progress_color"],
|
||||||
|
hover_color=style_options["button_hover_color"],
|
||||||
|
text_color="white",
|
||||||
|
command=setup_page_3,
|
||||||
|
)
|
||||||
|
next_button.place(relx=1.0, rely=1.0, anchor="se", x=-20, y=-20)
|
||||||
|
|
||||||
def setup_page_3():
|
def setup_page_3():
|
||||||
"""Sets up the installation progress page."""
|
for widget in root.winfo_children():
|
||||||
global current_page
|
widget.destroy()
|
||||||
current_page = 3
|
|
||||||
progress_page = Frame(root, bg='#2e2e2e')
|
|
||||||
progress_page.pack(fill='both', expand=True)
|
|
||||||
|
|
||||||
Label(progress_page, text="Installation läuft...", bg="#2e2e2e", fg="white").pack(pady=20)
|
progress_label = ctk.CTkLabel(
|
||||||
progress_bar = Progressbar(progress_page, orient='horizontal', length=400, variable=progress_var,
|
root,
|
||||||
style='Horizontal.TProgressbar')
|
text="Installation läuft...",
|
||||||
progress_bar.pack(pady=10)
|
font=("Arial", 14),
|
||||||
button = Button(progress_page, text="Weiter", command=lambda: (progress_page.pack_forget(), show_readme()))
|
text_color=style_options["text_color"],
|
||||||
button.place(relx=0.9, rely=0.9, anchor='se')
|
)
|
||||||
|
progress_label.pack(pady=20)
|
||||||
|
|
||||||
|
progressbar = ctk.CTkProgressBar(
|
||||||
|
root,
|
||||||
|
variable=progress_var,
|
||||||
|
fg_color=style_options["progress_color"],
|
||||||
|
progress_color=style_options["text_color"],
|
||||||
|
)
|
||||||
|
progressbar.set(0) # Anfang des Fortschritts
|
||||||
|
progressbar.pack(pady=20)
|
||||||
|
|
||||||
|
finish_button = ctk.CTkButton(
|
||||||
|
root,
|
||||||
|
text="Installieren",
|
||||||
|
fg_color=style_options["text_color"],
|
||||||
|
hover_color=style_options["button_hover_color"],
|
||||||
|
text_color="white",
|
||||||
|
command=lambda: [extract_files(), setup_page_4()],
|
||||||
|
)
|
||||||
|
finish_button.place(relx=1.0, rely=1.0, anchor="se", x=-20, y=-20)
|
||||||
|
|
||||||
|
def setup_page_4():
|
||||||
|
for widget in root.winfo_children():
|
||||||
|
widget.destroy()
|
||||||
|
|
||||||
|
complete_label = ctk.CTkLabel(
|
||||||
|
root,
|
||||||
|
text="Installation abgeschlossen!",
|
||||||
|
font=("Arial", 16),
|
||||||
|
text_color=style_options["text_color"],
|
||||||
|
)
|
||||||
|
complete_label.pack(pady=20)
|
||||||
|
|
||||||
|
finish_button = ctk.CTkButton(
|
||||||
|
root,
|
||||||
|
text="Beenden",
|
||||||
|
fg_color=style_options["progress_color"],
|
||||||
|
hover_color=style_options["button_hover_color"],
|
||||||
|
text_color="white",
|
||||||
|
command=root.quit,
|
||||||
|
)
|
||||||
|
finish_button.place(relx=1.0, rely=1.0, anchor="se", x=-20, y=-20)
|
||||||
|
|
||||||
|
def resource_path(relative_path):
|
||||||
|
"""Ermittelt den absoluten Pfad, um Ressourcen im PyInstaller-Build zu finden."""
|
||||||
|
base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
return os.path.join(base_path, relative_path)
|
||||||
|
|
||||||
|
|
||||||
# Tkinter Setup
|
def run():
|
||||||
root = Tk()
|
# Hauptprogramm
|
||||||
root.title("Installer")
|
|
||||||
root.geometry("500x350")
|
|
||||||
|
|
||||||
# Darkmode Style
|
root.title("Toolbox Installer")
|
||||||
style = Style(root)
|
|
||||||
style.theme_use('clam')
|
|
||||||
style.configure('TLabel', background='#2e2e2e', foreground='white', font=('Helvetica', 12))
|
|
||||||
style.configure('TButton', background='#444', foreground='white', font=('Helvetica', 10))
|
|
||||||
style.configure('Horizontal.TProgressbar', troughcolor='#444', background='#5a9')
|
|
||||||
root.configure(background='#2e2e2e')
|
|
||||||
|
|
||||||
output_dir_var = StringVar(value=os.path.join(os.environ['PROGRAMFILES(X86)'], "Toolbox"))
|
# Icon setzen
|
||||||
progress_var = DoubleVar()
|
icon_path = resource_path("toolbox.ico") # Stelle sicher, dass toolbox.ico vorhanden ist
|
||||||
current_page = 0
|
root.iconbitmap(icon_path)
|
||||||
|
root.geometry("500x350")
|
||||||
|
|
||||||
setup_page_1()
|
# Globale Variablen
|
||||||
root.mainloop()
|
global output_dir_var, progress_var
|
||||||
|
output_dir_var = StringVar()
|
||||||
|
progress_var = DoubleVar()
|
||||||
|
|
||||||
|
# Stile anwenden und Startseite laden
|
||||||
|
apply_custom_styles()
|
||||||
|
setup_page_1()
|
||||||
|
|
||||||
|
# Haupt-Loop
|
||||||
|
root.mainloop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
root = ctk.CTk()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
run() # Führt die Methode 'run()' aus, wenn die Datei direkt ausgeführt wird
|
||||||
3
installer/requirements.txt
Normal file
3
installer/requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
customtkinter~=5.2.2
|
||||||
|
setuptools~=75.6.0
|
||||||
|
Cython~=3.0.11
|
||||||
11
installer/setup.py
Normal file
11
installer/setup.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
from setuptools import setup
|
||||||
|
from Cython.Build import cythonize
|
||||||
|
import os
|
||||||
|
|
||||||
|
# Zielordner für kompilierten Code
|
||||||
|
build_dir = os.path.join(os.getcwd(), "cython")
|
||||||
|
|
||||||
|
setup(
|
||||||
|
ext_modules=cythonize("main.py", compiler_directives={'language_level': "3"}),
|
||||||
|
script_args=["build_ext", "--build-lib", build_dir]
|
||||||
|
)
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Toolbox</title>
|
<title>Toolbox</title>
|
||||||
<link rel="stylesheet" href="../highlight/styles/github-dark.css">
|
<link rel="stylesheet" href="../highlight/styles/dark.css" media="all" title="dark">
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
font-family: Arial, sans-serif;
|
font-family: Arial, sans-serif;
|
||||||
@@ -125,6 +125,16 @@
|
|||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.general {
|
||||||
|
flex: 1;
|
||||||
|
background: #1e1e2e;
|
||||||
|
padding: 15px;
|
||||||
|
display: none; /* Standardmäßig ausgeblendet */
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
.footer {
|
.footer {
|
||||||
background: #1b1b2b;
|
background: #1b1b2b;
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
@@ -140,7 +150,7 @@
|
|||||||
<div class="sidebar">
|
<div class="sidebar">
|
||||||
<h2>Einstellungen</h2>
|
<h2>Einstellungen</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#" onclick="showContent('none')">Einstellungen</a></li>
|
<li><a href="#" onclick="showContent('general')">Einstellungen</a></li>
|
||||||
<li><a href="#" onclick="showContent('editor')">Skript</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 3</a></li>
|
||||||
<li><a href="#" onclick="showContent('none')">Option 4</a></li>
|
<li><a href="#" onclick="showContent('none')">Option 4</a></li>
|
||||||
@@ -153,15 +163,18 @@
|
|||||||
<!-- Header mit Zurück-Button -->
|
<!-- Header mit Zurück-Button -->
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<h1>Einstellungen</h1>
|
<h1>Einstellungen</h1>
|
||||||
<button class="back-button" onclick="goBack()">Zurück</button>
|
<button class="back-button" onclick="goBack()">←</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Zentraler Editor (Standardmäßig versteckt) -->
|
<!-- Zentraler Editor (Standardmäßig versteckt) -->
|
||||||
<div class="editor" id="editor">
|
<div class="editor" id="editor">
|
||||||
|
<label for="code-editor"></label>
|
||||||
<textarea id="code-editor" placeholder="Write Lua code here..."></textarea>
|
<textarea id="code-editor" placeholder="Write Lua code here..."></textarea>
|
||||||
<pre><code id="highlightedOutput" class="language-lua"></code></pre>
|
<pre><code id="highlightedOutput" class="language-lua"></code></pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="general" id="general"></div>
|
||||||
|
|
||||||
<!-- Footer -->
|
<!-- Footer -->
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<!--Schmidti.Digital © 2024-->
|
<!--Schmidti.Digital © 2024-->
|
||||||
@@ -169,46 +182,39 @@
|
|||||||
</div>
|
</div>
|
||||||
<script src="../highlight/highlight.min.js"></script>
|
<script src="../highlight/highlight.min.js"></script>
|
||||||
<script src="../highlight/languages/lua.min.js"></script>
|
<script src="../highlight/languages/lua.min.js"></script>
|
||||||
<script>hljs.highlightAll();</script>
|
|
||||||
<script>
|
<script>
|
||||||
function goBack() {
|
function goBack() {
|
||||||
saucer.exposed.openIndex();
|
saucer.exposed.openIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
function showContent(option) {
|
function showContent(option) {
|
||||||
|
const general = document.getElementById('general');
|
||||||
const editor = document.getElementById('editor');
|
const editor = document.getElementById('editor');
|
||||||
|
|
||||||
// Editor anzeigen, wenn "Option 2" ausgewählt wird
|
|
||||||
if (option === 'editor') {
|
if (option === 'editor') {
|
||||||
editor.style.display = 'flex';
|
editor.style.display = 'flex';
|
||||||
|
general.style.display = 'none';
|
||||||
|
} else if (option === 'general') {
|
||||||
|
general.style.display = 'flex';
|
||||||
|
editor.style.display = 'none';
|
||||||
} else {
|
} else {
|
||||||
editor.style.display = 'none';
|
editor.style.display = 'none';
|
||||||
|
general.style.display = 'none';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', (event) => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
const editor = document.getElementById('code-editor');
|
const editor = document.getElementById('code-editor');
|
||||||
const output = document.getElementById('highlightedOutput');
|
const output = document.getElementById('highlightedOutput');
|
||||||
|
|
||||||
editor.addEventListener('input', () => {
|
// Synchronisiere den Inhalt von textarea mit dem Codeblock
|
||||||
// Update the code block with the content of the textarea
|
editor.addEventListener('input', () => {
|
||||||
output.textContent = editor.value;
|
output.innerHTML = ''; // Vorheriges Highlighting entfernen
|
||||||
// Apply syntax highlighting
|
output.textContent = editor.value; // Aktuellen Text setzen
|
||||||
hljs.highlightElement(output);
|
hljs.highlightAll();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// 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>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -23,21 +23,41 @@
|
|||||||
position: relative; /* Für absolute Positionierung des Buttons */
|
position: relative; /* Für absolute Positionierung des Buttons */
|
||||||
}
|
}
|
||||||
|
|
||||||
.options-button {
|
.button {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
|
||||||
right: 20px;
|
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
background: #2b2c3b;
|
background: #2b2c3b;
|
||||||
border: none;
|
border: none;
|
||||||
color: #ff79c6;
|
color: #ff79c6;
|
||||||
padding: 8px 16px;
|
|
||||||
border-radius: 4px;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background 0.3s;
|
transition: background 0.3s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.options-button:hover {
|
#file-system-button {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
right: 20px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#reload-button{
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 20px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#option-button {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
right: 80px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:hover {
|
||||||
background: #32334a;
|
background: #32334a;
|
||||||
}
|
}
|
||||||
.header h1 {
|
.header h1 {
|
||||||
@@ -146,15 +166,22 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="header">
|
<div class="header">
|
||||||
|
<button onclick="getNewContent()" class="button" id="reload-button">↻</button>
|
||||||
|
<button onclick="openEinst()" class="button" id="option-button">⚙️</button>
|
||||||
<h1>Toolbox</h1>
|
<h1>Toolbox</h1>
|
||||||
<button onclick="openFileSystem()" id="options-button" class="options-button">Ordner</button>
|
<button onclick="openFileSystem()" id="file-system-button" class="button">📁</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="main" id="toolbox">
|
<div class="main" id="toolbox">
|
||||||
<!-- Tool Cards werden hier dynamisch geladen -->
|
<!-- Tool Cards werden hier dynamisch geladen -->
|
||||||
</div>
|
</div>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<!--Schmidti.Digital © 2024-->
|
<!--Schmidti.Digital © 2024-->
|
||||||
</div><script>
|
</div>
|
||||||
|
<script>
|
||||||
|
function getNewContent(){
|
||||||
|
saucer.exposed.getNewContent();
|
||||||
|
}
|
||||||
|
|
||||||
function runLuaWithId(event) {
|
function runLuaWithId(event) {
|
||||||
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
|
||||||
|
|||||||
@@ -135,6 +135,11 @@ void ToolboxWindow::ExposeToJs() {
|
|||||||
m_webview.expose("openIndex", [&]() {
|
m_webview.expose("openIndex", [&]() {
|
||||||
openIndex();
|
openIndex();
|
||||||
},saucer::launch::async);
|
},saucer::launch::async);
|
||||||
|
|
||||||
|
m_webview.expose("getNewContent", [&]()
|
||||||
|
{
|
||||||
|
getNewContent();
|
||||||
|
},saucer::launch::async);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToolboxWindow::SetJsonItems() {// Konvertierung des Vektors in JSON
|
void ToolboxWindow::SetJsonItems() {// Konvertierung des Vektors in JSON
|
||||||
@@ -367,6 +372,11 @@ void ToolboxWindow::openIndex() {
|
|||||||
if (!serveHtmlFile("html/index.html", false)) {
|
if (!serveHtmlFile("html/index.html", false)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
getNewContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToolboxWindow::getNewContent()
|
||||||
|
{
|
||||||
configureWindow();
|
configureWindow();
|
||||||
fillToolboxMenu();
|
fillToolboxMenu();
|
||||||
SetJsonItems();
|
SetJsonItems();
|
||||||
|
|||||||
Reference in New Issue
Block a user