222 lines
7.7 KiB
PHP
222 lines
7.7 KiB
PHP
<?php
|
|
|
|
require_once __DIR__ . '/../vendor/autoload.php';
|
|
|
|
use PHPNative\Framework\Application;
|
|
use PHPNative\Framework\IconFontRegistry;
|
|
use PHPNative\Tailwind\Data\Icon as IconName;
|
|
use PHPNative\Ui\Widget\Button;
|
|
use PHPNative\Ui\Widget\Container;
|
|
use PHPNative\Ui\Widget\Icon;
|
|
use PHPNative\Ui\Widget\Label;
|
|
use PHPNative\Ui\Widget\Menu;
|
|
use PHPNative\Ui\Widget\MenuBar;
|
|
use PHPNative\Ui\Widget\Modal;
|
|
use PHPNative\Ui\Widget\StatusBar;
|
|
use PHPNative\Ui\Widget\TabContainer;
|
|
use PHPNative\Ui\Widget\Table;
|
|
use PHPNative\Ui\Widget\TextInput;
|
|
use PHPNative\Ui\Window;
|
|
|
|
$iconFontCandidates = [
|
|
__DIR__ . '/../assets/fonts/fa-solid-900.ttf',
|
|
__DIR__ . '/../assets/fonts/fontawesome/fa7_freesolid_900.otf',
|
|
'/usr/share/fonts/truetype/fontawesome-webfont.ttf',
|
|
'/usr/share/fonts/truetype/fontawesome/fa-solid-900.ttf',
|
|
'/usr/share/fonts/truetype/fa-solid-900.ttf',
|
|
];
|
|
|
|
$iconFontPath = null;
|
|
foreach ($iconFontCandidates as $candidate) {
|
|
if (is_file($candidate)) {
|
|
$iconFontPath = $candidate;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ($iconFontPath !== null) {
|
|
IconFontRegistry::setDefaultFontPath($iconFontPath);
|
|
} else {
|
|
echo "Hinweis: FontAwesome Font nicht gefunden. Icons werden ohne Symbol dargestellt.\n";
|
|
}
|
|
|
|
$app = new Application();
|
|
$window = new Window('Windows Application Example', 800, 600);
|
|
$currentApiKey = '';
|
|
|
|
/** @var Label|null $statusLabel */
|
|
$statusLabel = null;
|
|
|
|
// Main container (flex-col: menu, content, status)
|
|
$mainContainer = new Container('flex flex-col bg-gray-100');
|
|
|
|
// Modal dialog setup (hidden by default)
|
|
$apiKeyInput = new TextInput('API Key', 'w-full border border-gray-300 rounded px-3 py-2 bg-white text-black');
|
|
|
|
$modalDialog = new Container('bg-white border border-gray-300 rounded p-6 flex flex-col w-96 gap-3 shadow-lg');
|
|
$modalDialog->addComponent(new Label('API Einstellungen', 'text-xl font-bold text-black'));
|
|
$modalDialog->addComponent(new Label(
|
|
'Bitte gib deinen API Key ein, um externe Dienste zu verbinden.',
|
|
'text-sm text-gray-700',
|
|
));
|
|
|
|
$fieldContainer = new Container('flex flex-col gap-1');
|
|
$fieldContainer->addComponent(new Label('API Key', 'text-sm text-gray-600'));
|
|
$fieldContainer->addComponent($apiKeyInput);
|
|
$modalDialog->addComponent($fieldContainer);
|
|
|
|
$buttonRow = new Container('flex flex-row justify-end gap-2');
|
|
$cancelButton = new Button('Abbrechen', 'px-4 py-2 bg-gray-200 text-black rounded hover:bg-gray-300');
|
|
$saveButton = new Button('Speichern', 'px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 flex items-center');
|
|
$saveIcon = new Icon(IconName::save, 18, 'text-white');
|
|
$saveButton->setIcon($saveIcon);
|
|
$buttonRow->addComponent($cancelButton);
|
|
$buttonRow->addComponent($saveButton);
|
|
$modalDialog->addComponent($buttonRow);
|
|
|
|
$modal = new Modal($modalDialog);
|
|
$modal->setBackdropAlpha(180);
|
|
|
|
// === 1. MenuBar ===
|
|
$menuBar = new MenuBar();
|
|
|
|
// File Menu
|
|
$fileMenu = new Menu(title: 'Datei');
|
|
$fileMenu->addItem('Neu', function () {
|
|
echo "Neu clicked\n";
|
|
});
|
|
$fileMenu->addItem('Öffnen', function () {
|
|
echo "Öffnen clicked\n";
|
|
});
|
|
$fileMenu->addSeparator();
|
|
$fileMenu->addItem('Beenden', function () use ($app) {
|
|
echo "Beenden clicked\n";
|
|
exit(0);
|
|
});
|
|
|
|
// Settings Menu
|
|
$settingsMenu = new Menu(title: 'Einstellungen');
|
|
$settingsMenu->addItem('Optionen', function () use ($menuBar, $modal, $apiKeyInput, &$currentApiKey) {
|
|
$menuBar->closeAllMenus();
|
|
$apiKeyInput->setValue($currentApiKey);
|
|
$modal->setVisible(true);
|
|
});
|
|
$settingsMenu->addItem('Sprache', function () {
|
|
echo "Sprache clicked\n";
|
|
});
|
|
$menuBar->addMenu($fileMenu);
|
|
$menuBar->addMenu($settingsMenu);
|
|
$mainContainer->addComponent($menuBar);
|
|
|
|
// === 2. Tab Container (flex-1) ===
|
|
$tabContainer = new TabContainer('flex-1');
|
|
|
|
// Tab 1: Table with data
|
|
$tab1 = new Container('flex flex-col p-4');
|
|
$table = new Table(style: 'bg-lime-200');
|
|
|
|
$table->setColumns([
|
|
['key' => 'id', 'title' => 'ID', 'width' => 80],
|
|
['key' => 'name', 'title' => 'Name'],
|
|
['key' => 'email', 'title' => 'E-Mail'],
|
|
['key' => 'status', 'title' => 'Status', 'width' => 120],
|
|
]);
|
|
|
|
$table->setData([
|
|
['id' => 1, 'name' => 'Max Mustermann', 'email' => 'max@example.com', 'status' => 'Aktiv'],
|
|
['id' => 2, 'name' => 'Anna Schmidt', 'email' => 'anna@example.com', 'status' => 'Aktiv'],
|
|
['id' => 3, 'name' => 'Peter Weber', 'email' => 'peter@example.com', 'status' => 'Inaktiv'],
|
|
['id' => 4, 'name' => 'Lisa Müller', 'email' => 'lisa@example.com', 'status' => 'Aktiv'],
|
|
['id' => 5, 'name' => 'Tom Klein', 'email' => 'tom@example.com', 'status' => 'Aktiv'],
|
|
['id' => 6, 'name' => 'Sarah Wagner', 'email' => 'sarah@example.com', 'status' => 'Inaktiv'],
|
|
['id' => 7, 'name' => 'Michael Becker', 'email' => 'michael@example.com', 'status' => 'Aktiv'],
|
|
['id' => 8, 'name' => 'Julia Fischer', 'email' => 'julia@example.com', 'status' => 'Aktiv'],
|
|
['id' => 9, 'name' => 'Daniel Schneider', 'email' => 'daniel@example.com', 'status' => 'Inaktiv'],
|
|
['id' => 10, 'name' => 'Laura Hoffmann', 'email' => 'laura@example.com', 'status' => 'Aktiv'],
|
|
]);
|
|
|
|
// Row selection handler
|
|
$statusLabel = new Label(
|
|
text: 'Fenster: ' . $window->getViewport()->windowWidth . 'x' . $window->getViewport()->windowHeight,
|
|
style: 'basis-4/8 text-black',
|
|
);
|
|
$table->setOnRowSelect(function ($index, $row) use (&$statusLabel) {
|
|
if ($row) {
|
|
$statusLabel->setText("Selected: {$row['name']} ({$row['email']})");
|
|
}
|
|
});
|
|
|
|
$tab1->addComponent($table);
|
|
$tabContainer->addTab('Daten', $tab1);
|
|
|
|
// Tab 2: Some info
|
|
$tab2 = new Container('flex flex-col p-4');
|
|
$tab2->addComponent(new Label('Dies ist Tab 2', 'text-xl font-bold mb-4'));
|
|
$tab2->addComponent(new Label('Hier könnte weiterer Inhalt stehen...', ''));
|
|
$tabContainer->addTab('Info', $tab2);
|
|
|
|
// Tab 3: Settings
|
|
$tab3 = new Container('flex flex-col p-4');
|
|
$tab3->addComponent(new Label('Einstellungen', 'text-xl font-bold mb-4'));
|
|
$tab3->addComponent(new Label('Konfigurationsoptionen...', ''));
|
|
$tabContainer->addTab('Einstellungen', $tab3);
|
|
|
|
$mainContainer->addComponent($tabContainer);
|
|
|
|
// === 3. StatusBar ===
|
|
$statusBar = new StatusBar();
|
|
$statusBar->addSegment($statusLabel);
|
|
$fpsLabel = new Label(
|
|
text: 'FPS: --',
|
|
style: 'basis-1/8 text-black border-l',
|
|
);
|
|
$statusBar->addSegment(new Label(
|
|
text: 'Zeilen: 10',
|
|
style: 'basis-2/8 text-black border-l',
|
|
)); // Fixed width
|
|
$statusBar->addSegment($fpsLabel);
|
|
$statusBar->addSegment(new Label(
|
|
text: 'Version 1.0',
|
|
style: 'border-l text-black basis-2/8',
|
|
));
|
|
$mainContainer->addComponent($statusBar);
|
|
|
|
$cancelButton->setOnClick(function () use ($menuBar, $modal) {
|
|
$menuBar->closeAllMenus();
|
|
$modal->setVisible(false);
|
|
});
|
|
|
|
$saveButton->setOnClick(function () use (&$currentApiKey, $apiKeyInput, $menuBar, $modal, &$statusLabel) {
|
|
$currentApiKey = trim($apiKeyInput->getValue());
|
|
if ($statusLabel !== null) {
|
|
$masked = strlen($currentApiKey) > 4
|
|
? (str_repeat('*', max(0, strlen($currentApiKey) - 4)) . substr($currentApiKey, -4))
|
|
: $currentApiKey;
|
|
$statusLabel->setText('API-Key gespeichert: ' . $masked);
|
|
}
|
|
$menuBar->closeAllMenus();
|
|
$modal->setVisible(false);
|
|
});
|
|
|
|
$mainContainer->addComponent($modal);
|
|
$window->setOnResize(function (Window $window) use (&$statusLabel) {
|
|
$statusLabel->setText(
|
|
'Fenster: ' . $window->getViewport()->windowWidth . 'x' . $window->getViewport()->windowHeight,
|
|
);
|
|
});
|
|
$window->setOnFpsChange(function (float $fps) use ($fpsLabel) {
|
|
$fpsLabel->setText(sprintf('FPS: %d', max(0, (int) round($fps))));
|
|
});
|
|
// Set root and run
|
|
$window->setRoot($mainContainer);
|
|
$app->addWindow($window);
|
|
|
|
echo "Windows Application Example started!\n";
|
|
echo "Features:\n";
|
|
echo "- MenuBar with 'Datei' and 'Einstellungen'\n";
|
|
echo "- Tab Container with 3 tabs\n";
|
|
echo "- Scrollable Table in first tab\n";
|
|
echo "- StatusBar at the bottom\n\n";
|
|
|
|
$app->run();
|