User Interface

This component is responsible for creating and interacting with the user interface.


Requirements

  • PHP ^8.1

Installation

Library is available as composer repository and can be installed using the following command in a root of your project.

  • composer require bic-engine/ui

Usage

Please note that this is a base library that provides cross-platform user interface interaction and does not include a driver that provides the main functionality of the application.

In order to ensure the work you will need to install one of the available drivers and the main entry point to the component will be provided by the driver itself.

$factory = new Bic\UI\ExampleDriver\Factory();

Window Creating

The creation of a new window is done using the create([CreateInfo $info]) method, which accepts an optional DTO with options for creating a new window:

$window = $factory->create();

{info} Note that different drivers may accept specific DTOs, which may contain driver-specific advanced creation options. However, anyone is required to accept the following set of general options within the DTO.

$window = $factory->create(new \Bic\UI\Window\CreateInfo(
    // New window title in UTF-8.
    title: 'Window Title',
    // New window size in screen coordinates.
    // Note: Scaling can affect window sizes.
    size: new \Bic\UI\Size(
        width: 640,
        height: 480,
    ),
    // The position of the new window, in screen coordinates.
    // The NULL can be passed instead of a Position object. In this
    // case, the window will be created in the center of the
    // main display.
    position: new \Bic\UI\Position(
        x: 100,
        y: 100,
    ),
    // Sets the icon when the window is created.
    icon: new \Bic\UI\Window\Icon(
        // Note: Information about creating and reading icon
        // files is in the image documentation.
        big: new \Bic\Image\Image(...),
        small: new \Bic\Image\Image(...),
    ]),
    // Sets the cursor for the new window.
    cursor: new \Bic\UI\Window\Cursor(
        icon: new \Bic\Image\Image(...),
        x: 2,
        y: 2
    ),
    // New window creation mode:
    // - NORMAL - Standard format (window mode).
    // - HIDDEN - The window will be hidden (minimized).
    // - FULLSCREEN - The window is expanded to fullscreen.
    //                Priority mode with graphics acceleration.
    mode: \Bic\UI\Window\Mode::NORMAL,
    // Allows you to resize window using drag-n-drop.
    resizable: false,
    // Allows you to close windows when you click on the
    // close window button.
    closable: true,
));

Running

After the window is created, the application should be launched. This can be done in blocking and asynchronous modes.

{info} Please note that some drivers may provide a separate runner from the factory to implement the event loop.

// 1) Blocking mode
$factory->run();

// 2) Asynchronous mode
$fiber = new \Fiber($factory->run(...));
$fiber->start();

Management

To interact with a window, you can change its properties or use methods. For example, to read and change the title of a window, you can use the following code:

echo $window->title;
$window->title = 'New Title';

// OR

echo $window->getTitle();
$window->setTitle('New Title');

The options are completely similar, however, in the future, examples will be given that use window properties:

// Update Title
$window->title = 'Window Title';

// Window Icon
$window->icon = null;                               // Remove icon (use default)
$window->icon = new \Bic\UI\Window\Icon(...);       // Set new icon
$window->icon->big = new \Bic\Image\Image(...);     // Update big window icon
$window->icon->small = new \Bic\Image\Image(...);   // Update small window icon

// Window Cursor
$window->cursor = null;                             // Remove cursor (use default)
$window->cursor = new \Bic\UI\Window\Cursor(...);   // Set new cursor

// Window Size
$window->size = new \Bic\UI\Window\Size(...);       // Set new window size
$window->size->width = ...;                         // Update window width
$window->size->height = ...;                        // Update window height

// Window Position
$window->position = new \Bic\UI\Window\Position(...);   // Set new window pos
$window->position->x = ...;                             // Update window X
$window->position->y = ...;                             // Update window Y

Events

In asynchronous mode, you can receive events from the fiber associated with user actions inside the created windows.

while (!$fiber->isTerminated()) {
    if ($event = $fiber->resume()) {
        // ... window events ...
    }
}

Window events are categorized:

  • Common Window Events
  • Keyboard Events
  • Mouse Events

For example, this way you can receive all common window events:

while (!$fiber->isTerminated()) {
    $event = $fiber->resume();

    if ($event instanceof \Bic\UI\Window\WindowEvent) {
        var_dump($event);
    }
}

Each event contains a ->target field, which contains a reference to the object that the event belongs to:

if ($event instanceof \Bic\UI\Window\WindowEvent) {
    echo '#' . \spl_object_id($event->target) . " window event\n";
}

Window Events

  • Bic\UI\Window\Event\WindowBlurWindowEvent - Fires when the window loses focus.
  • Bic\UI\Window\Event\WindowFocusWindowEvent - Fires when the window receives focus.
  • Bic\UI\Window\Event\WindowCloseWindowEvent - Fires when the window is closed.
  • Bic\UI\Window\Event\WindowHideWindowEvent - Fires when the window is hidden (minimized).
  • Bic\UI\Window\Event\WindowHideWindowEvent - Fires when the window is displayed (restored from minimized state).

For example:

use Bic\UI\Window\CreateInfo;
use Bic\UI\Window\Event\WindowCloseWindowEvent;

$factory = new Bic\UI\ExampleDriver\Factory();

$factory->create(new CreateInfo(title: 'Window #1', closable: true));
$factory->create(new CreateInfo(title: 'Window #2', closable: true));

$fiber = new \Fiber($factory->run(...));
$fiber->start();

while (!$fiber->isTerminated()) {
    $event = $fiber->resume();

    if ($event instanceof WindowCloseWindowEvent) {
        echo '#' . \spl_object_id($event->target) . " has been closed\n";
    }
}

Keyboard Events

// TODO

Mouse Events

// TODO