GUI Platform

It's time to make Argentum programs work on:

  • desktop
  • mobile
  • and web

To do so it needs a graphical user interface library:

  • portable
  • fast
  • simple
  • and independent from host platforms (and screen sizes).

But this GUI library itself needs a foundation:

  • an integration layer to the operating system, windows, input events and application lifecycle
  • a canvas to draw on, with full set of modern features and a full GPU support.

So meet an experimental "GuiPlatform" module:

  • It uses SDL to interact with operating system. It handles:
    • application lifecycle
    • window, focus
    • input events from keyboard, touch screen, mouse,
    • and other aspects, which gives Argentum applications maximum possible level of portability:
      • so far I'm testing it on Windows,
      • in the future it'll support Linux, MacOS, IOS, Android, WASM in browsers and multiple other platforms, such as game consoles; all the needed code is already there, so all we need to do is to check and maybe fix couple of lines of code.
  • It uses OpenGL to interact with GPU, which gives good balance of utilization of hardware and good portability (unfortunately Vulkan is not supported everywhere yet).
  • It uses SKIA as a canvas library, thus giving us the full set of 2D drawing APIs existing in Chrome-based web browsers, Android OS and multiple other modern application frameworks and platforms.

Example

using sys { Blob, log }
using guiPlatform { Canvas, Paint, Rect, Font, Image }
using string;

class MyApp {
    +guiPlatform_App {
        onStart() {
            font.fromName("Arial Bold");
            img.fromBlob(Blob.{ _.loadFile("sd.png") : log("Img sd.png not loaded") });
        }
        onPaint(c Canvas) {
            phase += 1s;
            c.clear(0xff_ffffffs);
            p = Paint;
            (x + dx) -> (_ < 0f || _ > w ? dx *= -1f : x := _);
            (y + dy) -> (_ < 0f || _ > h ? dy *= -1f : y := _);
            c.drawRect(Rect.setXYWH(x-50f, y-50f, 100f, 100f), p.color(0xff_ff0000s));
            forRangeFStep(0f, 700f, 4f)`i {
                p.color(0xff_008800s | (short(i) + phase));
                c.drawLine(    i, 0f, 0f,     700f - i, p);
                c.drawLine(w - i, 0f,  w,     700f - i, p);
                c.drawLine(    i,  h, 0f, h - 700f + i, p);
                c.drawLine(w - i,  h,  w, h - 700f + i, p);
            };
            c.drawSimpleText((w - 48f) / 2f, (h - 16f) / 2f, "Hello", font, 16f, p.color(0xff_004400s));
            c.drawImage((w - 108f) / 2f, (h - 100f) / 2f - 100f, img);
        }
        onKey(pressed bool, key short, shifts short) {
            log("key{pressed?"down":"up"}-{key}-{shifts} ");
            pressed && key == 20s ? sys_setMainObject(?MyApp)
        }
   }
   phase = 0s;
   x = 100f;
   y = 100f;
   dx = 1f;
   dy = 1f;
   font = Font;
   img = Image;
}
MyApp.run("Hello AG", 120) // Start GUI app with windows title and given FPS

So far this example is tested on Windows using Argentum built from sources on experimental branch gui_platform.

Next steps:

  • Launch on Linux, Android and other platforms
  • Extend Window API to introduce named constants for key codes, shifts etc.
  • Extend Canvas API to support more Skia drawing.
  • Develop a GUI framework with:
    • focus handling
    • controls
    • animations
    • layouts
    • accessibility

Leave a Reply

Your email address will not be published. Required fields are marked *