Frame Window is a C++ library that helps organize widgets in GLFW.
And it is much similar to the OpenWS
This library is heavily dependent on glfw, which means even you don't need glfw to compile this library, you still need it when compiling your program when using it.
cd
into the library's directorymkdir .build
to create a build directory, in order to separate the generated files and the sourcescd .build && cmake ..
to generate makefilemake
to make all the stuffs we need
There is a complete example located in example/test.cpp
if you need.
This library is organized as a tree structure, with frames stand for all the non-leaf nodes and user-defined widget for all the leaf nodes.
So in order to make it work, you need to:
- Implement a widget inheriting
fwLeafWidget
, with all the callbacks you need and a display function - Setup a glfw window
- Initialize Main Frame Window from glfwWindow by calling
fwInitFrameWindow
- Initialize each element inside by calling
fwInitWidgetAs*
, making sure every node is initialized - Run glfw-style mainloop, and call
fwUpdate
each time window repaint is needed
This library works in C++, so it is much easier to implement a widget than in C.
By implementing a class as a window class, you need to inherit it from fwLeafWidget
A simple window class is like this:
class Rect : public public fwLeafWidget {
public:
virtual void onRepaint() {
glColor3f(1.0f, 0.0f, 0.0f);
glRecti(0, 0, 64, 64);
}
}
For the purpose of representation, there is a fully implemented class with all
the available callbacks implemented in the example/test.cpp
As the Frame is based on glfw, it is of course the first thing to setup the glfw window.
In this instance, we created a non-resizable window whose width is 416px, height is 64px and title is "test".
glfwInit();
glfwWindowHint(GLFW_RESIZABLE, false);
GLFWwindow* window = glfwCreateWindow(128, 64, "test", nullptr, nullptr);
fwInitFrameWindow creates a MainFrame which binds to the glfwWindow, and the following parameters.
Here our MainFrame is a 1x3 form. The width of each column is 192px, 192px and 32px respectively, and the height is 64px.
fwMainFrame* mainFrame = new FrameWindow(window, 1, 3, { 192, 192, 32 }, { 64 });
By calling fwInitWidgetAs*, you can init each element as either a leaf or a subframe.
Attaintion: As by now I have no idea how to handle out-of-bound element access, the program will crash if you access an element outside the frame
Here we initialized the left two elements as leaves, and the rightside one as a 2x1 subform containing two leaves.
fwSetWidgetAs(mainFrame, 0, 0, &block[0]);
fwSetWidgetAs(mainFrame, 0, 1, &block[1]);
fwFrame* subFrame = fwInitWidgetAsFrame(mainFrame, 0, 2, 2, 1,
{ 32 }, { 32, 32 });
fwSetWidgetAs(subFrame, 0, 0, &block[2]);
fwSetWidgetAs(subFrame, 1, 0, &block[3]);
I implemented a function fwUpdate, so the mainloop is handed over to the user, rather than the library.
This mainloop is similar to the one we use in common glfw programs, although you need to call fwUpdate each time you want to repaint the window.
By the way, you don't need to call glfwMakeContextCurrent each time, as I will check the context in fwUpdate.
while(!glfwWindowShouldClose(window)) {
fwUpdate(mainFrame);
glfwPollEvents();
}