This commit is contained in:
Thomas Peterson 2025-11-14 16:37:59 +01:00
parent eced006d55
commit cf9ee67f67
6 changed files with 68 additions and 136 deletions

View File

@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use PHPNative\Framework\Application;
use PHPNative\Ui\Widget\Container;
use PHPNative\Ui\Widget\Label;
use PHPNative\Ui\Window;
$app = new Application();
$window = new Window('Container Label Debug', 600, 400);
// Root with neutral background
$root = new Container('flex items-center justify-center bg-gray-100');
// Simple box with border and a single label
$box = new Container('bg-white border border-black rounded-lg p-4');
$box->addComponent(new Label('DEBUG: Label im Container', 'text-lg text-black'));
$root->addComponent($box);
$window->setRoot($root);
$app->addWindow($window);
$app->run();

View File

@ -27,7 +27,6 @@ final class KanbanTaskCard extends Container
}
}
#[\Override]
public function handleMouseClick(float $mouseX, float $mouseY, int $button): bool
{
if ($button !== 1) {
@ -42,22 +41,18 @@ final class KanbanTaskCard extends Container
final class KanbanBoardView extends Container
{
private array $boards;
private Container $columnsContainer;
private array $boardViews = [];
private ?array $dragState = null;
private ?string $hoverBoardId = null;
private null|array $dragState = null;
private null|string $hoverBoardId = null;
public function __construct(
private readonly string $storagePath,
array $initialBoards,
private readonly Label $statusLabel,
) {
parent::__construct('flex flex-col flex-1 overflow-hidden');
parent::__construct('flex flex-row gap-4 flex-1');
$this->boards = $initialBoards;
$this->columnsContainer = new Container('flex flex-row gap-4 overflow-auto flex-1 pb-3');
$this->addComponent($this->columnsContainer);
$this->renderBoards();
}
@ -115,7 +110,6 @@ final class KanbanBoardView extends Container
$this->statusLabel->setText('Verschiebe: ' . $task['title']);
}
#[\Override]
public function handleMouseMove(float $mouseX, float $mouseY): void
{
parent::handleMouseMove($mouseX, $mouseY);
@ -136,7 +130,6 @@ final class KanbanBoardView extends Container
}
}
#[\Override]
public function handleMouseRelease(float $mouseX, float $mouseY, int $button): void
{
parent::handleMouseRelease($mouseX, $mouseY, $button);
@ -151,55 +144,39 @@ final class KanbanBoardView extends Container
private function renderBoards(): void
{
$this->columnsContainer->clearChildren();
$this->clearChildren();
$this->boardViews = [];
foreach ($this->boards as $board) {
$colorHex = substr(md5($board['id']), 0, 6);
$defaultStyle = 'flex flex-col w-[260] flex-none border border-gray-400 rounded-lg p-3 gap-3 shadow-sm bg-[#' . $colorHex . ']';
$highlightStyle = 'flex flex-col w-[260] flex-none bg-blue-50 border-2 border-blue-500 rounded-lg p-3 gap-3 shadow';
$style = 'flex flex-col w-[260] flex-none bg-white border border-black rounded-lg p-3 gap-2';
$debugInfo = new Label(sprintf(
"Board %s\nID: %s\nTasks: %d",
$board['title'],
$board['id'],
count($board['tasks']),
), 'text-xs text-black whitespace-pre-wrap');
$column = new Container($style);
$column->addComponent(new Label('Board: ' . $board['title'], 'text-lg font-bold text-black'));
$column = new Container($defaultStyle);
$header = new Container('flex flex-col gap-1 bg-white/80 rounded p-2 shadow-inner');
$header->addComponent(new Label($board['title'], 'text-lg font-semibold text-black'));
$header->addComponent(new Label(count($board['tasks']) . ' Aufgaben', 'text-xs text-gray-500'));
$header->addComponent($debugInfo);
$column->addComponent($header);
$taskTitles = array_map(static fn($t) => $t['title'], $board['tasks']);
$tasksText = empty($taskTitles) ? '(keine Aufgaben)' : implode(', ', $taskTitles);
$column->addComponent(new Label('Tasks: ' . $tasksText, 'text-xs text-black'));
$taskList = new Container('flex flex-col gap-2');
if (!empty($board['tasks'])) {
$taskList = new Container('flex flex-col gap-2 mt-2');
foreach ($board['tasks'] as $task) {
$taskList->addComponent(new KanbanTaskCard($board['id'], $task, $this));
$card = new Container('bg-white border-2 border-gray-400 rounded px-2 py-1 shadow-md');
$card->addComponent(new Label($task['title'], 'text-sm text-black'));
$taskList->addComponent($card);
}
$column->addComponent($taskList);
}
$addInput = new TextInput('Neue Aufgabe', 'flex-1 border border-gray-300 rounded px-2 py-1 bg-white text-black text-sm');
$addButton = new Button('Hinzufügen', 'px-2 py-1 bg-emerald-500 text-white rounded hover:bg-emerald-600 text-sm');
$addButton->setOnClick(function () use ($board, $addInput): void {
$this->addTask($board['id'], $addInput->getValue());
$addInput->setValue('');
});
$addRow = new Container('flex flex-row gap-2');
$addRow->addComponent($addInput);
$addRow->addComponent($addButton);
$column->addComponent($addRow);
$this->columnsContainer->addComponent($column);
$this->addComponent($column);
$this->boardViews[$board['id']] = [
'column' => $column,
'defaultStyle' => $defaultStyle,
'highlightStyle' => $highlightStyle,
'defaultStyle' => $style,
'highlightStyle' => $style,
];
}
}
private function findBoardAt(float $mouseX, float $mouseY): ?string
private function findBoardAt(float $mouseX, float $mouseY): null|string
{
foreach ($this->boardViews as $boardId => $info) {
$viewport = $info['column']->getViewport();
@ -227,7 +204,7 @@ final class KanbanBoardView extends Container
$column->setStyle($style);
}
private function completeDrag(?string $targetBoardId): void
private function completeDrag(null|string $targetBoardId): void
{
$state = $this->dragState;
$this->dragState = null;
@ -279,7 +256,11 @@ final class KanbanBoardView extends Container
$this->saveBoards();
$this->renderBoards();
$this->statusLabel->setText(sprintf('"%s" nach "%s" verschoben.', $movedTask['title'], $this->getBoardTitle($targetBoardId)));
$this->statusLabel->setText(sprintf(
'"%s" nach "%s" verschoben.',
$movedTask['title'],
$this->getBoardTitle($targetBoardId),
));
}
private function getBoardTitle(string $boardId): string
@ -339,11 +320,7 @@ if (empty($boards)) {
],
],
];
file_put_contents(
$storagePath,
json_encode($boards, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE),
LOCK_EX,
);
file_put_contents($storagePath, json_encode($boards, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX);
}
$app = new Application();
@ -352,7 +329,10 @@ $window = new Window('Kanban Beispiel', 1200, 800);
$root = new Container('flex flex-col h-full w-full bg-gray-100 gap-4 p-4');
$title = new Label('Kanban Board', 'text-3xl font-bold text-black');
$subTitle = new Label('Boards hinzufügen, Aufgaben erstellen und per Drag & Drop verschieben.', 'text-base text-gray-700');
$subTitle = new Label(
'Boards hinzufügen, Aufgaben erstellen und per Drag & Drop verschieben.',
'text-base text-gray-700',
);
$root->addComponent($title);
$root->addComponent($subTitle);

View File

@ -36,5 +36,10 @@
"note": ""
}
]
},
{
"id": "board_69170bcc2be8c6.34720864",
"title": "asd",
"tasks": []
}
]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 218 KiB

View File

@ -1,36 +0,0 @@
<?php
require_once __DIR__ . '/vendor/autoload.php';
use PHPNative\Framework\Application;
use PHPNative\Ui\Widget\Container;
use PHPNative\Ui\Widget\Label;
use PHPNative\Ui\Window;
$app = new Application();
$window = new Window('Scroll Test', 400, 300);
// Main container
$mainContainer = new Container('flex flex-col bg-white');
// Create a scrollable container with fixed height
$scrollContainer = new Container('flex flex-col w-full h-48 overflow-auto bg-gray-100 border-2 border-red-500');
// Add many labels to force scrolling
for ($i = 1; $i <= 30; $i++) {
$label = new Label("Item $i", 'px-4 py-2 border-b border-gray-300 text-black bg-white');
$scrollContainer->addComponent($label);
}
$mainContainer->addComponent(new Label('Scroll Test (red box should be scrollable)', 'text-xl font-bold p-4 text-black'));
$mainContainer->addComponent($scrollContainer);
$mainContainer->addComponent(new Label('Try scrolling with mouse wheel over the red box', 'p-4 text-black'));
$window->setRoot($mainContainer);
$app->addWindow($window);
echo "Scroll Test started!\n";
echo "- Red box should show scrollbar\n";
echo "- Try scrolling with mouse wheel\n\n";
$app->run();

View File

@ -1,44 +0,0 @@
<?php
require_once __DIR__ . '/vendor/autoload.php';
use PHPNative\Framework\Application;
use PHPNative\Ui\Widget\Container;
use PHPNative\Ui\Widget\Table;
use PHPNative\Ui\Window;
$app = new Application();
$window = new Window('Table Scroll Test', 800, 600);
// Simple container with limited height
$mainContainer = new Container('flex flex-col bg-gray-100 p-4');
// Table with max height
$table = new Table('h-96'); // 384px max height
$table->setColumns([
['key' => 'id', 'title' => 'ID', 'width' => 100],
['key' => 'name', 'title' => 'Name', 'width' => 400],
['key' => 'status', 'title' => 'Status', 'width' => 120],
]);
// Test data with 63 entries (same as your example)
$testData = [];
for ($i = 1; $i <= 63; $i++) {
$testData[] = [
'id' => $i,
'name' => "Server-{$i}",
'status' => ($i % 3 === 0) ? 'stopped' : 'running',
];
}
$table->setData($testData);
$mainContainer->addComponent($table);
$window->setRoot($mainContainer);
$app->addWindow($window);
echo "Table Scroll Test started!\n";
echo "- Table should show scrollbar\n";
echo "- Try scrolling with mouse wheel over the table\n\n";
$app->run();