Skip to content
/ leif Public
forked from cococry/leif

Minimal, configurable & GPU accelerated Immediate Mode UI Library written with modern OpenGL

Notifications You must be signed in to change notification settings

savaughn/leif

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

99 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

leif

Overview

Leif is a minimal and powerful immediate UI library/framework written in pure C. The library uses OpenGL for rendering interfaces. The focus of this library is to be performant, easy to use and suckless. Leif uses batch rendering for displaying GPU accelerated user interfaces.

stb-like library

The Leif UI library is contained in only one C Source- and one C Header-file. This is done for providing the easiest possible way to work with Leif. But because the library has a few dependencies, it is prepackaged into a static library that the user can then link to.

Features

Leif comes with a ton of customizablity options and theming. The Element Property System in Leif allows the user to create any UI that comes to mind. The library provides lots of UI elements like input fields, buttons text labels, images etc.

The library provides a complete Div Container System out of the box with which the user can seperate different parts of the UI into contained fields. The user can scroll inside every div which creates lots of possiblities to create UI systems.

In the backend, Leif uses a highly efficient batch renderer that can render textures, text and colored geometry in one batch. The rendering backend that the library ueses is OpenGL.

Dependencies

Dependency Reason of Usage
glad Loading OpenGL functions
stb_image Loading image files into memory
stb_image_resize2 Resizing images
stb_truetype Loading font glyphs from font files
cglm Linear Algebra Math
*GLFW Handling windowing, input etc.

*: This library is an optional library and will be replacable with other libraries

Building

Building the static library should be as easy as installing the dependencies and executing the Makefile.

Aur (paru/yay)

paru -S libleif

Install the dependencies (Arch)

sudo pacman -S gcc make glfw cglm

Install the dependencies (Debian)

sudo apt install gcc make libglfw3 libglfw3-dev libcglm-dev

Building the library

Generate static library

make

Install the library

sudo make install 

Usage

Initialize Leif before using and after creating a window with your windowing backend:

lf_init_glfw(displayWidth, displayHeight, glfwWindow);

Within the main loop of your program, call the lf_begin() and lf_end() functions within which you can render UI elements.

A simple example of some UI elements:

lf_begin();
lf_text("Hello Leif!");

lf_next_line();

if(lf_button("Close") == LF_CLICKED) {
  glfwSetWindowShouldClose(window, true);
}
if(lf_button("Show Text") == LF_CLICKED) {
  showText = !showText;
}
if(showText) {
  lf_next_line();
  lf_text_wide(L"Привет");
}
lf_end();

Styling & Positioning Elements

lf_begin();
for(uint32_t i = 0; i < 4; i  ) {
  const char* buttonText = "Start App";

  LfUIElementProps props = lf_theme()->button_props;
  props.margin_left = 0;
  props.margin_top = 20;
  props.color = RGB_COLOR(220, 220, 220);
  props.text_color = LF_BLACK;
  props.corner_radius = 3.5f;
  props.border_width = 0.0f;

  lf_push_style_props(props);

  lf_set_ptr_x_absolute((displayWidth - lf_button_dimension(buttonText).x) / 2.0f);
  lf_button(buttonText);

  lf_pop_style_props();

  lf_next_line();
}
lf_end();

Working with Div Containers

static LfTexture appleTexture = lf_load_texture("apple.png", false, LF_TEX_FILTER_LINEAR);

lf_begin();

LfUIElementProps div_props = lf_theme()->div_props;
div_props.border_width = 3;
div_props.border_color = LF_BLUE;
div_props.corner_radius = 6;
lf_push_style_props(div_props);

lf_div_begin((vec2s){10, 150}, (vec2s){300, 300}, true);

lf_pop_style_props();

for(uint32_t i = 0; i < 10; i  ) {
  if(i % 2 == 0) {
    LfUIElementProps props = lf_theme()->button_props;
    props.border_width = 0;
    props.color = LF_WHITE;
    props.text_color = LF_BLACK;
    props.corner_radius = 3;

    lf_push_style_props(props);

    lf_push_element_id(i);
    lf_button("Button");
    lf_pop_element_id();

    lf_pop_style_props();
  } else {
    lf_image((LfTexture){.id = appleTexture.id, .width = 64, .height = 64});
  }
  lf_next_line();
}
lf_div_end();

div_props.border_color = LF_RED;
lf_push_style_props(div_props)  ;

lf_div_begin((vec2s){350, 150}, (vec2s){200, 200}, true);

lf_pop_style_props();

for(uint32_t i = 0; i < 20; i  ) {
  lf_text("Div Test");
  lf_next_line();
}

lf_div_end();

lf_end();

Real world usage

But how does the leif library perform in real applications? I am currently working on a music player called lyssa. The frontend of the player is written entirely with leif. You can see a brief look at of the application below.

A task management app that i also wrote with the leif library:

Contributing

You can contribute to Leif by:

About

Minimal, configurable & GPU accelerated Immediate Mode UI Library written with modern OpenGL

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C 97.3%
  • Shell 1.7%
  • Makefile 1.0%