Giter Site home page Giter Site logo

microui's Introduction

microui

A tiny, portable, immediate-mode UI library written in ANSI C

Features

  • Tiny: around 1100 sloc of ANSI C
  • Works within a fixed-sized memory region: no additional memory is allocated
  • Built-in controls: window, scrollable panel, button, slider, textbox, label, checkbox, wordwrapped text
  • Works with any rendering system that can draw rectangles and text
  • Designed to allow the user to easily add custom controls
  • Simple layout system

Example

example

if (mu_begin_window(ctx, "My Window", mu_rect(10, 10, 140, 86))) {
  mu_layout_row(ctx, 2, (int[]) { 60, -1 }, 0);

  mu_label(ctx, "First:");
  if (mu_button(ctx, "Button1")) {
    printf("Button1 pressed\n");
  }

  mu_label(ctx, "Second:");
  if (mu_button(ctx, "Button2")) {
    mu_open_popup(ctx, "My Popup");
  }

  if (mu_begin_popup(ctx, "My Popup")) {
    mu_label(ctx, "Hello world!");
    mu_end_popup(ctx);
  }

  mu_end_window(ctx);
}

Screenshot

screenshot

Browser Demo

Usage

  • See doc/usage.md for usage instructions
  • See the demo directory for a usage example

Notes

The library expects the user to provide input and handle the resultant drawing commands, it does not do any drawing itself.

Contributing

The library is designed to be lightweight, providing a foundation to which you can easily add custom controls and UI elements; pull requests adding additional features will likely not be merged. Bug reports are welcome.

License

This library is free software; you can redistribute it and/or modify it under the terms of the MIT license. See LICENSE for details.

microui's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

microui's Issues

RAM Footprint

Being a minimalistic immediate mode UI, I can't understand why 30 Mb of Private RAM usage is being measured on windows with ProcessHacker.
I noted that SDL2 calls opengl, but I don't think that this is the reason here.
The editor "exi/lite" is about 8 Mb under the same conditions.
I would expect a footprint if the range of some kb.

image
image

Can you layout from minimum required sizes by child widgets?

I don't quite understand the meaning of zero and negative values for the widths and height in a row (yes, I read the Usage doc, but even with that I don't understand what these values actually do).

What I need is to never hardcode any size at all, and just pack the widgets respecting the minimum size they need to be drawn without clipping the text. Sure, some widgets do need a size (a slider for example), but in those cases I'd be fine if such a widget takes all the space which is not requested by the rest of widgets in the row.

Can this be done with the current layout system, or would I need to modify it?

Also, do widgets say what's the minimum size they need? Or maybe that's not implemented?

Thanks!

Unicode support?

Looking at @floooh's browser demo https://floooh.github.io/sokol-html5/wasm/sgl-microui-sapp.html, when I type eg. the ยง character into the input for the log window and click the submit button, what looks like a deformed copy of the sprite sheet for the font appears.

Not sure if this is just because the demo isn't written to support unicode, or a bug? Feel free to close this issue if the former is the case.

Missing texture generator

First thanks for microui, I am using it as debugging interface for my little app. I noticed that it's missing a way to generate the texutre used for the demo. I believe you have used the atlas code to do that, but the steps needed are missing. Could you please add them in the READM.md file ?

On a side note, is there a reason for choosing the supply Id based on hashed pointers rather than simple id increments ? This forces the pointers to reference memory allocated on heap, and would break the logic if they are allocated on stack.

Hash function "Cannot convert from 'const void *' to 'const unsigned char *'"

I'm running into an issue when building microui in a C++ project in visual studio 2019.

The two errors that show are one in the hash() function: "Cannot convert from 'const void *' to 'const unsigned char *'"

And another in the mu_next_command() function: "Cannot convert from 'void *' to 'mu_Command *'"

Any idea what might be going wrong?

'step' does not work with mu_slider_ex

It appears that the 'step' argument does not work with sliders. No matter which value I use the value is not rounded to multiple of 'step'. I briefly looked at the code and it seems cast to int or floor call is missing from microui.c line 873:

if (step) { v = (((v + step / 2) / step)) * step; }

C string gets corrupted when passed to the TextCommand handler

I'm playing around with the demo program, and am noticing that the text rendering function receives a corrupt copy of the text to print. I've also noticed that the source it receives each time is different, meaning it's being corrupted along the way. It's received correctly in the text_width function, but I can't find where it could possibly become changed.

In short, my code is this:

void text(mu_TextCommand cmd) {
    std::string str = std::string(cmd.str);

    std::cout << str << std::endl; // Prints mangled copy

    cairo_select_font_face(cr, "raleway", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
    cairo_set_font_size(cr, 12.);
    cairo_set_source_rgba(cr, (double)cmd.color.r / 255, (double)cmd.color.g / 255, (double)cmd.color.b / 255, (double)cmd.color.a / 255);
    cairo_move_to(cr, cmd.pos.x, cmd.pos.y + text_height(cmd.font));
    cairo_text_path(cr, cmd.str);

    cairo_fill(cr);
}

...

int text_width(mu_Font font, const char *str, int len) {
    if (len == -1) len = strlen(str);

    std::cout << str << std::endl; // Prints correctly

    cairo_select_font_face(cr, "raleway", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
    cairo_set_font_size(cr, 12.);

    cairo_text_extents_t extents;
    cairo_text_extents(cr, str, &extents);

    return extents.width;
}

...

while (getElapsedTime(start) < 10) { // has it been 10s since the program started?
    mu_begin(ctx);

    cairo_set_source_rgba(cr, 1., 1., 1., 1.);
    cairo_rectangle(cr, 0, 0, dev->width, dev->height);
    cairo_fill(cr);

    if (mu_begin_window(ctx, window_title, mu_rect(10, 10, 720, 480))) {
        mu_label(ctx, window_title);

        mu_end_window(ctx);
    }

    mu_end(ctx);

    flush(ctx, dev);
}

I can't seem to find the source of the issue. My guess was some sort of memory overwriting, but I removed all memory management calls, and still got the same result.

Some details:

  • I've compiled microui as a shared library
  • I'm using C++ 20 with G++
  • I'm using the cairo library as a drawing backend.

How to port to another low level access graphic control

Hello. This is not an issue. Just a question looking for a link or help:
How I do port this great project to another lower framebuffer layer? I see that it depends on SDL y GL it seems.
I have just a memory buffer for drawing pixeles (it is a little experiment on Xinu operating system using vga in protected mode x86).
So I do not have neither SDL nor GL. But I can draw pixels (or of course, copy a memory drawing buffer to screen for example).
Should I modify the renderer.* files? Others? Any help on how to modify the current demo for a new screen control would be appreciated.

Anti-Aliasing on Linux + i3-wm

Basically it seems like anti-aliasing doesn't work well. Both on the browser demo and real microgui apps (lite editor).
DeepinScreenshot_lite_20200417170250
DeepinScreenshot_Navigator_20200417170320

Font Question

Hi,

How can I use custom font ?
How can I create my atlas.inl ?

Thank you.

Question: Running demo on windows

Forgive as I am new to C and just messing around breaking things as I learn.

Is it possible to run the demo on windows? It seems the compiler does not like the SDL2 library.

./build.sh: line 13: sdl2-config: command not found
main.c:1:10: fatal error: SDL2/SDL.h: No such file or directory
    1 | #include <SDL2/SDL.h>
      |          ^~~~~~~~~~~~

I have tried downloading the SDL2 library and including but I cannot seem to get this to work. Would anyone be kind enough to instruct me how to get this to work?

Question: Microui extensions

Cool UI library!

Is there a list of useful extensions (new "widgets") that people have created
using microui?

How can you resize microui window dynamically?

Hi, I want to resize microui window when whole SDL2 window is resized.

basically I'd expect code below to work, but microui window size stays the same.
SDL_GetWindowSize(window, &width, &height);
if (mu_begin_window(mu, MAIN_WINDOW_NAME, mu_rect(0, 0, width, height)))

Am I doing it wrong? How can I resize microui window?

How do I know if microui consumed an event?

If the user drags a microui slider in a window, I don't want the drag to affect the content underneath the window. imgui has WantCaptureKeyboard, WantCaptureMouse, etc for this purpose but I can't find the corollary mechanism in microui.

By the way thanks for this library, it's truly beautiful.

Misaligned pointer access in the command list.

This is minor but it might be nice to fix the address sanitizer output that look like this:

runtime error: member access within misaligned address 0x000112e73f44 for type 'mu_Command', which requires 8 byte alignment

Thankfully this seems really to fix:

  1. Add an expect(size % 8 == 0) at the top of mu_push_command
  2. Add 4 bytes of padding to mu_RectCommand
  3. Change mu_draw_text to do:
    int aligned_size = len + 8 - (len % 8);
    cmd = mu_push_command(ctx, MU_COMMAND_TEXT, sizeof(mu_TextCommand) + aligned_size);

Why is black area covering gui appearing after resizing window?

Hello, I have changed the demo code so it allows window resizing, but when I'm resizing window part of the window contents is being covered by black rectangle.

Screenshots below show the problem:
first one is how it looks after program started
second and third are after resizing window to make it bigger.

Can you please help me understand why is that black rectangle appearing?

This is how I implemented resizing: https://github.com/tomaszte/microui/commit/d975c07eb59521ce692029387454a478969b7507

Image 1
Image 1
Image 1

NOT A BUG: Why not make this in Love2D?

I know this shouldn't be in the issue but I had no means of communicating you so ...! In any case I am very impressed by this neat library of yours and I think you would do the love2d world a favour by porting this to work with love2d!!
(for cross-platform compatibility it'd be awesome if you write in pure lua)
Regards!

Can I use it without SDL ?

All I want to know is if it is stand-alone or it needs SLD, OpenGL etc. Cause in example folder I saw SDL imports.

Keyboard controls?

It seems a pointer device is needed to use the microui interfaces.

I'd be interested in keyboard control, I suppose this would also mean tab order would be useful.

Thanks for all your work!

About GL_ALPHA

Hi , your deom very well running on my project.

However, I encounter some color format issure, GL_ALPHA always invalid, reported by 1281.
GL_RED is ok, but the visual effect not correct.

the context I used is GLFW not SDL.

Do you have any idea ? thanks.

glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, ATLAS_WIDTH, ATLAS_HEIGHT, 0, GL_ALPHA, GL_UNSIGNED_BYTE, atlas_texture);

Porting push_quad to DirectX

I almost ported all the functions to DirectX so basically i can draw basic window without icons , i'm trying to replicate what push_quad does but actually seems like i can't understand it

Not a bug: thanks for microui :)

Hi, just wanted to let you know that I've created a little microui sample on top of my cross-platform headers, here's the standard sample running in WebAssembly:

https://floooh.github.io/sokol-html5/wasm/sgl-microui-sapp.html

I need to improve a few input handling things (mobile touch input, and figuring out a better way to map my library's mouse-wheel input to yours), but these are minor things.

Also the default font atlas doesn't look too good on a high-dpi display when rendered at half resolution (I've had the same issues with Dear ImGui when using a TTF font, but Dear ImGui's default font looks fine in such situations, if a bit "low-tec": https://floooh.github.io/sokol-html5/wasm/imgui-sapp.html.

But anyway, these are minor issues, and not an issue with microui. Thanks for that neat little library :)

Textbox improvements!

Hi, thanks for this awesome lib!

One thing that i felt was missing was proper textbox navigation, being able to correct a character without having to delete the entire thing

So i spent some time and managed to come up with something:

Peek.2021-12-23.05-28.mp4

Please let me know if you want to see more improvement to the code, so i can submit a PR!

Changes:

struct mu_Context {
  //. ..
  /* input state */
  // ...
  char input_text[32];
+  int input_text_written;
};
 /* reset input state */
  ctx->key_pressed = 0;
  ctx->input_text[0] = '\0';
+  ctx->input_text_written = 0;
void mu_input_text(mu_Context *ctx, const char *text) {
  int len = strlen(ctx->input_text);
  int size = strlen(text) + 1;
  expect(len + size <= (int) sizeof(ctx->input_text));
  memcpy(ctx->input_text + len, text, size);
+  ctx.input_text_written += (size - 1);
}

And here is how the new function looks like:

We basically introduce a new argument to the textbox_raw function
A pointer to an int so we can track the index, and user can specific where the index should start

int mu_textbox_raw(mu_Context *ctx, char *buf, int bufsz, int *index, mu_Id id, mu_Rect r,
  int opt)
{
  int res = 0;
  mu_update_control(ctx, id, r, opt | MU_OPT_HOLDFOCUS);

  if (ctx->focus == id) {
    /* handle text input */
    int len = strlen(buf);
    int n = mu_min(bufsz - len - 1, (int) strlen(ctx->input_text));
    int i = *index;
    int needMove = len - i;
    if (n > 0) {
      if (needMove > 0) {
        memmove(buf + i + n, buf + i, needMove);
      }
      memcpy(buf + i, ctx->input_text, n);
      len += n;
      buf[len] = '\0';
      res |= MU_RES_CHANGE;
    }
    /* handle backspace */
    if (ctx->key_pressed & MU_KEY_BACKSPACE && len > 0) {
      /* skip utf-8 continuation bytes */
      while ((buf[--len] & 0xc0) == 0x80 && len > 0);
      
      (*index)--;
      memmove(buf + (*index), buf + (*index) + 1, len - (*index) + 1);
      buf[len] = '\0';
      res |= MU_RES_CHANGE;
    }
    /* handle return */
    if (ctx->key_pressed & MU_KEY_RETURN) {
      mu_set_focus(ctx, 0);
      res |= MU_RES_SUBMIT;
    }
    if (ctx.key_pressed & KEY_LEFT)
    {
      (*index)--;
    }
    else if (ctx.key_pressed & KEY_RIGHT)
    {
      (*index)++;
    }
    if ((*index) < 0) (*index) = 0;
    if (*index >= len) (*index) = len;
  } else {
    int len = strlen(buf);
    (*index) = len;
  }

  /* draw */
  mu_draw_control_frame(ctx, id, r, MU_COLOR_BASE, opt);
  if (ctx->focus == id) {
    mu_Color color = ctx->style->colors[MU_COLOR_TEXT];
    mu_Font font = ctx->style->font;
    int textw = ctx->text_width(font, buf, (*index));
    int texth = ctx->text_height(font);
    int ofx = r.w - ctx->style->padding - textw - 1;
    int textx = r.x + mu_min(ofx, ctx->style->padding);
    int texty = r.y + (r.h - texth) / 2;
    mu_push_clip_rect(ctx, r);
    mu_draw_text(ctx, font, buf, -1, mu_vec2(textx, texty), color);
    mu_draw_rect(ctx, mu_rect(textx + textw, texty, 1, texth), color);
    mu_pop_clip_rect(ctx);
  } else {
    mu_draw_control_text(ctx, buf, r, MU_COLOR_TEXT, opt);
  }
  
  (*index)+=ctx->input_text_written;
  return res;
}

glScissor must be disabled

Hi,

it seems I must disable glScissor to works properly on AMD Radeon HD 6450 card.
When I drag windows around glScissor fails:

glscissor

I've solved adding glEnable(GL_SCISSOR_TEST) to r_clear() func and glDisable(GL_SCISSOR_TEST) to r_present() func.
I understand this is a quick demo but a not OpenGL expert like me can need to fix this.

Maybe there's a better workaround ?

Thank you.

Trying to get a window container within another window

Right now, all I'm trying to do is get a parent window container from within a child window. I thought this was accomplished through the 'mu_get_container' function but it doesn't seem to be presenting me with a valid container. The code is as follows:

if(mu_begin_window(ctx, "Parent Window", mu_rect(200, 100, 300, 400)))
    {
        if(mu_begin_window(ctx, "Child Window1", mu_rect(0, 0, 200, 200)))
        {
            mu_Container* currentWin = mu_get_container(ctx, "Child Window1");//This does not work
            mu_Container* cnt = mu_get_current_container(ctx);//This works and returns Child Window1
            
            if(mu_begin_window(ctx, "Child Window2", mu_rect(0, 200, 200, 200)))
            {
                mu_Container* parentWin = mu_get_container(ctx, "Child Window1");//This does not work. Returns empty container
                
                mu_end_window(ctx);
            };
            
            mu_end_window(ctx);
        };
        
        mu_end_window(ctx);
    };

Am I doing something wrong? When is mu_get_container suppose to be used then?

atlas_texture

Hello rxi:
Does the content in this array have an image format?
How is this constructed?

Post a screenshot

It'd be interesting to see how microui is being used in projects and might work well as a demonstration for anyone interested in using the library. If you're using microui for anything, feel free to post a screenshot of your project here!

.gitignore

demo/a.out

And meybe add rake , makefile or ninja

msvc c++ build failing to compile

hey ive been looking into ui's and your library looks pretty nice. However im getting weird link errors and error: LNK2019 unresolved symbol ""void __cdecl mu_init(struct mu_Context *)" or when i inserted extern "C" myself in your files i got it to "mu_init" being unresolved.

my build.bat uses these libs gdi32.lib opengl32.lib winmm.lib

just wondering if anyone usese windows with msvc c++ here and got this figured out

Mouse down event not registered properly when there is no mouse motion

I recently ported the code to a project I am working on the nintendo switch. Since I am using touchscreen, there are no motion message being sent (unless when dragging). Motion occurs only when a touch is inputed.

Seems controls need to be hovered first thru motion before mouse down is processed properly.
I tried to debug it a little. I believe the problem occurs in mu_update_control when the context hover id is set.

To reproduce the issue just disable the processing of motion in the sdl message handler. You'll notice you need to click several time to get a proper mouse down.

I'll continue to investigate, let me know if you have some ideas.

Compile Error on Windows

When trying to compile this on Windows, I got a syntax error that seems to be due to the enum RELATIVE. I changed RELATIVE to LAYOUT_RELATIVE, and the error disappears.

Licensing

Would you consider releasing microui into the public domain? Or possibly dual licensing like nuklear? I'm looking to use microui for my next project but I prefer to release things into the public domain entirely, so I will have to use nuklear instead, unless the licensing could be changed.

Microui is a great little library, thanks for making it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.