IMGUI DEMONSTRATION -- Sean Barrett, Aug 5 2005 -- Public Domain


OVERVIEW

This is a very simple sample application built on top of
a "one-pass" IMGUI implementation, in which every frame
every widget is called exactly once. This is only appropriate
for "real time" programs, like games, or if you don't mind
your editor eating 100% of CPU even when idle.

The sample application is a "rectangle editor". You can
move rectangles by dragging them, resize them by dragging
their edges and corners, and change their color using the
provided RGB sliders. Deselect by clicking on the background.
Obvious this is not a very interesting program in practice,
but it offers a straightforward demonstration.

The application demonstrates various UI features to show 
that they can be easily implemented in IMGUI:

 * overlapping widgets ('hot_to_be' detects top-most widget)
 * dynamic widget presence (based on selecting rectangles)
 * dynamic widget sizing (rescale to 1/4 width of screen)
 * dynamic widget configuration ('show values' button)
 * custom widgets (the rectangle editor is effectively one)
 * widget animation (the fade-in/out when hovering over)


SOURCE MANIFEST 

app.c        --  the IMGUI client application

ui.c         --  the IMGUI library

ui_event.c   --  remap from an event-driven system to
                 one-set-of-inputs-per-frame

gui_graph.c  --  interface for ui graphics calls; this file
                 remaps to "gr" lib below, but could turn it
                 into native windows calls or OpenGL, etc.

gr.c         -\
gr_extra.c   --  portable 32-bit graphics library
font_0.c     -/

winmain.c    --  all Windows-specific code; windows events
                 are re-dispatched as platform-independent
                 events to ui_event.c

laggui.dsp   --  MSVC6 project and workspace
laggui.dsw

IMPLEMENTATION NOTES

uiButtonLogic() is the most important function in the
entire system. It is used by buttons, sliders, and drag-handles
because it implements the basic functionality of "take control
on mouse-down, give up control on mouse-up".

It also returns True on mouse-up, the preferred behavior
for buttons. Sliders can still use uiButtonLogic(), because
they ignore the return value and simply check if they're
active to decide to allow changes to the slider value.

uiButtonLogicRect() implements an undrawn rectangular button;
unlike uiButtonLogic(), it actually compares the mouse to a button
shape. (uiButtonLogic() does not, so it could still be used for
things like rounded buttons, or even arbitrary shapes.)

uiLayout() is responsible for computing the appropriate place to
put each widget. It simply places the widget at the current cursor
location, and advances the cursor vertically. To do this, it must
know the height of the widget. Some widgets can automatically
determine a good width and height (for example, text buttons
will scale to fit the text inside), but usually you want to
override this (so that, e.g., all the fields in a menu are the
same width). The uiWidth() function specifies a width to use for
all later widgets; uiWidth1() specifies a width for the next
widget only. uiLayout() examines the uiWidth() state settings and
overrides the widget width/height at the same time it's updating
the cursor, so that individual widgets don't have to.

I wrote this library from scratch for this demonstration, hoping
to keep it simple enough to be decipherable, and correcting some
mistakes I made in My First IMGUI System.

So, (1) There are numerous bugs and misfeatures. For example, if
you allow sliders to autoscale their width, they will try to fit
their label. But if you turn on numeric display, the label can
change widths depending on the value, causing the scrollbar to
change widths as the value changes (causing a feedback loop
since scrollbar changes widths out from under the mouse pointer!).

(2) There's a dearth of widgets. No radio buttons, no scrollbars
and scrollable regions, no combo boxes, no menus. None of these
are hard to implement--I implemented them all in My First IMGUI
System. Here's some general strategy:

  * radio buttons are a collection of buttons with a state invariant
  * menus are a series of specially-drawn buttons with 0 spacing
  * combo-boxes are a button which, when clicked, toggles the combo
     box to its "live" state where it creates a (scrollable) menu
  * context menus and combo boxes should draw "on top". the way to
     do this is to push the screen "bitmap" and begin rendering into
     a temporary one, then draw that on top at the end. Similary, these
     should be forced on top even if they're called in the middle of the
     app, so to-be-hot needs some kind of "ignore everything after this,
     I'm absolutely on top"
  * scrollbars need to define a virtual screen coordinate system and
     offset mouse and display based on this, with an appropriate cliprect.
     then the scrollbar itself is slider-like and is used to position
     the virtual screen rect (this won't make use of hardware blitting,
     as Window's scrollbars do, but if we're redrawing the frame anyway,
     no big deal)
  * once you support scrollbars you may have lots of widgets offscreen;
     widgets should cull themselves ASAP and not do any complex processing.
     This may require you to override the normal layout code and force
     an explicit layout (use uiPos() to set the cursor coordinates)
