gempyre
1.7.1
|
Gempyre is a UI multiplatform framework. Supporting Windows, Mac OSX, Linux, Raspberry OS and Android. Gempyre is minimalistic and simple; It is a UI framework without widgets - instead, the UI is composed using common web tools and frameworks. Therefore Gempyre is small, easy to learn and quick to take in use.
For the application, Gempyre let engine to be implemented using C++ (or Python), the UI can be constructed using CSS and HTML like any front end. All common tools from the web technologies are be available. Gempyre library provides a simple and easy C++ API for a application development and the whole API is only a few dozen calls.
Gempyre is intended for applications that has a solid C++ core (or C), and allows rapid UI development without extra hassle with platform specific UI development.
Gempyre is multiplatform, its core is built using C++20 (tested on OSX (CLang), Ubuntu (gcc), Raspberry OS (gcc) and Windows 10 (MSVC and MinGW) ). The Gempyre framework can be downloaded at Github under MIT license.
Gempyre itself does not contain an application window. The UI is drawn using external application. Some OSes defaults to system browser, some Python webview. However that is fully configurable per application.
Gempyre is a library that is linked with the application, except for Android, see Gempyre-Android. For Python, install Gempyre-Python on top of Gempyre library.
I have changed default Web socket library and that may arise build issues. If there are issues you may try to set USE_LIBWEBSOCKETS
to OFF. (e.g. cmake -DUSE_LIBWEBSOCKETS=OFF ...). (I will remove this note later)
Gempyre uses CMake. Therefore in general installing is just calling
However there are some install scripts to help installing debug and release builds.
pacman -S base-devel gcc vim cmake ninja
Q: After installation you get: "WARNING: webview is not installed -> verification is not completed!", what is that?
A: Most likely python3 webview is not installed. See installation from pywebview. Please also make sure websockets python library is installed.
The error is not fatal, but as a consequence the default UI is not drawn on its own window and it fallbacks to the default browser.
Q: How to use some HTML/JS/CSS feature for GUI from C++ that does not have a API?
A: Try Ui::eval()
, it let you execute javascript in the gui context: e.g. Here I change a checkbox element so it fires a change event.
Q: Why Canvas drawings seems to happen in random order?
A: Canvas drawing is highly asynchronous operation and subsequent CanvasElement::draw()
operations may not get updated in the order you have called them. The solution is either make a single draw call where all items are updated once, or use CanvasElement::draw_completed()
to wait until each draw has happen. CanvasElement::draw_completed()
should be used for animations (or game like frequent updates) instead of timers for updating the graphics. Like this example
Q: Why Gempyre::Bitmap
merge is not working?
A: You are likely merge an uninitialized bitmap. Gempyre::Bitmap(width, height)
or Gempyre::Bitmap::create(width, height)
does not initialize bitmap data, therefore it's alpha channel can be zero and bitmap is not drawn. To initialize the bitmap, use Gempyre::Bitmap::Bitmap(0, 0, width, height, Gempyre::Color::White)
, or draw a rectangle to fill the Bitmap, after the construction.
Q: How to scale Gempyre::Bitmap
?
A: You can use browser's bitmap scaling by applying the bitmap as image and then using Gempyre::FrameComposer
for draw. Look the following snippet:
Q: How to do multiple Gempyre::FrameComposer
in a single draw? My second draw is not visible
A: Do you call erase? See CanvasElement::draw_completed above. You may also try to call your drawn in a
Ui::after` timer with 0ms delay, that should ensure the correct drawing order.
Q: Why my dynamic HTML <select>
does not work with numbers?
A: The UI select uses strings, and hence the values has to be quoted strings.
Q: I want to use Python window to have nice window and get file dialogs. But I do not get working in MacOS. A: The latest MacOS wish your run your Python in virtual environment. Look venv. As in any environment you may need to install pywebview and websockets. For example in venv shell call:
$ pip install pywebview websockets
However I noted that pywebview may not get successfully installed, and hence a link must be called, for example (please verify your python and pywebview versions):
$ ln -s ./venv/lib/python3.12/site-packages/pywebview-5.1.dist-info ./venv/lib/python3.12/site-packages/pywebview
Q: How to handle remove UI elements? A: There is Element::remove() that removes an element from UI and cleans up associated element handlers. However the element can be removed other ways, e.g. removing parent item or parent element calling Element::set_html that effectively wipes all child elements. You can detect that using Element::subscribe(Event::REMOVED). Please note that if element has any subscribed events, and if the element is expected to be remove othwerwise than Element::remove(); Event::REMOVED should be subscribed and call Element::remove() to explicit clean up.
As an example, here is a simple Gempyre application with a single button. The UI is written using HTML; please note the <script type="text/javascript" src="gempyre.js"> </script>
line is required for every Gempyre application. The HTML widgets are accessed by their HTML element ids from the C++.
And then we have a main.cpp. I discuss here every line by line. At first, gempyre.h is included so it can be used.
Within Gempyre you normally build in the HTML and other resources, to compose a single file executable. It is preferred that Gempyre is statically linked in, thus the application is just a single file. Therefore distributing and executing Gempyre applications shall be very easy: just run it! There are no runtimes to install nor DLLs to be dependent on; just a single binary executable.
The resource composing is done in CMakeLists.txt (single line), yet here the generated header is included, it contains a Hellohtml
, a std::string
object that will be passed then to the Gempyre::Ui
constructor.
In the constructor, you provide a mapping between file names and generated data and the HTML page that will be shown.
HTML elements are represented by Gempyre::Element
. The element constructor takes a HTML id to refer to the corresponding element in the UI. Here we refer to the text area and button as defined in the HTML code above. The Gempyre::Element
represents any of the HTML elements. It's only inherited class is Gempyre::CanvasElement
that implements specific graphics functionalities.
The Gempyre API provides a set of methods to get and set HTML content, values, and attributes. Here we just use setHTML to apply a given string as an element HTML content.
The subscribe method listens for element events, and when the button is "clicked" a given function is executed.
The Gempyre::Ui::run()
starts an event loop. In this example, the system default web browser is opened, and the UI is executed on tab (there are more alternatives to have a system looking application) and the application is waiting for the button to be pressed or the browser window to be closed.
Dynamic selection list (or combo box) is as easy as adding an empty select element in the Ui HTML code:
and then fill it in cpp side:
to read a value upon change you subscribe it's change:
Applying an initial value is trivial:
Please note that as each event has a lot of properties, you have to list what you need. For a selection change (as well as most of the inputs) a value is used.
WebP is a image format that can be used to replace PNG and GIF (animations). There is an external project WebP-Gempyre that will help using WebP images with Gempyre.
maybe not
Copyright Markus Mertama 2020, 2021, 2022, 2023, 2024