ui.rst 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. .. _UI:
  2. User Interface
  3. --------------
  4. MuJoCo has a native UI framework. Its use is illustrated in the :ref:`simulate.cc <saSimulate>` viewer. It is
  5. designed to be fast in terms of updating and rendering, easy to use both for the developer and for the user,
  6. cross-platform, and integrated with the native MuJoCo renderer. In order to achieve these design goals, we have omitted
  7. many features and customization options that are available in other UI frameworks, and instead focused on efficiency and
  8. automation.
  9. .. _uiDesign:
  10. Design overview
  11. ~~~~~~~~~~~~~~~
  12. Native OpenGL rendering
  13. We do not use any helper tools or libraries. Instead we provide C code for rendering all UI elements directly in
  14. OpenGL. We support multiple UIs, each of which is a virtual rectangle that can be taller than the visible window. The
  15. elements of each UI are rendered offscreen in auxiliary OpenGL buffers, via minimal updates, only when changes are
  16. necessary. At each screen refresh we then copy the pixels from these auxiliary buffers to the window framebuffer, and
  17. also implement vertical scroll bars when the window is smaller than the UI. This copy operation is done on the GPU and
  18. is very fast.
  19. Platform abstraction
  20. The software design has 3 layers: OpenGL rendering of UI elements working in conjunction with the MuJoCo renderer
  21. (which is fully cross-platform); abstract functions for access to windows, keyboard and mouse, defined as pure virtual
  22. functions in the ``PlatformUIAdapter`` class; and an implementation of those functions in the derived class
  23. ``GlfwAdapter``. `GLFW <https://www.glfw.org/>`__ itself is cross-platform. Nevertheless, we have opted for this
  24. layered design in order to separate generic from platform-specific functionality. If GLFW needs to be replaced with
  25. another similar framework for some reason, only ``GlfwAdapter`` will need to be rewritten.
  26. Themes and appearance
  27. Individual UI elements do not allow customization in terms of appearance or layout. Instead, we use themes for colors
  28. and spacing, and arrange all UI elements automatically. Several built-in themes are provided and the user can design
  29. custom themes, however the entire UI uses a single theme for all elements. Appearance is minimalist: mostly colored
  30. rectangles with text. Bitmaps and other custom decorations are not supported. The UI element types are check boxes,
  31. radio button groups, selection lists, sliders, text edit boxes, static text, buttons, separators. These elements are
  32. grouped into sections which can be expanded and collapsed.
  33. Layout and rectangles
  34. Each UI is one virtual rectangle, whose width is determined by the theme and whose height is determined by the
  35. sections, items within each section, and also the expand/collapse state of each section. The sizes and auxiliary
  36. buffers for these virtual rectangles are handled automatically when the UI is updated. Each UI has a visible rectangle
  37. on the screen, and in addition there are other rectangles -- for 3D rendering, 2D figures, and possibly custom OpenGL
  38. rendering. All these visible rectangles are saved (in :ref:`mjuiState`) and are used to determine where mouse events
  39. should be directed. The rectangle layout is updated by a callback provided by the user.
  40. Static allocation and creation
  41. Rather than allocating and deallocating a large number of objects corresponding to UI elements and linking them
  42. together, we create a single C struct (type :ref:`mjUI`) with static allocation supporting some maximum number of
  43. sections and elements; and then keep a record of how many are in use. UI creation is simplified by helper functions
  44. whose input is a C struct (type :ref:`mjuiDef`) that is essentially a table where each row describes one UI element
  45. (see below). This makes it possible to construct elaborate user interfaces with surprisingly little C code.
  46. Programmatic UI creation is also possible, for example when populating a UI with sliders corresponding to MuJoCo model
  47. joints.
  48. Minimal state
  49. The UI is designed to be as stateless as possible, so as to simplify development. This has two aspects. First, instead
  50. of replicating user data within the UI elements, we store pointers to user data. For example, we might create a UI
  51. slider and set its data pointer to ``mjData* d->qpos+7``. This slider will visualize as well as control the 7th scalar
  52. component of the qpos vector of a MuJoCo model. Thus, when the simulation is updated, we have to remember to update
  53. the UI as well. And furthermore we have to disable UI editing when the simulation is being updated. But the advantage
  54. is that the UI becomes easier to construct, and there is no danger of discrepancies between user data and the UI.
  55. Second, the UI elements themselves are mostly stateless. Instead we keep track of a minimal set of global states, in
  56. particular mouse and keyboard state, section expand/collapse, contents of the text box being edited if any.
  57. Automated enable and disable
  58. While each UI item can be set in enabled or disabled state directly, we also provide automation as follows. Each UI
  59. item can be assigned an integer category. Then a :ref:`mjfItemEnable` callback determines whether each category should
  60. be enabled or disabled, based on some program-specific conditions. For example, sliders that can change the values of
  61. MuJoCo model joints should be disabled when the simulation state is being updated.
  62. .. _uiAPI:
  63. Main API
  64. ~~~~~~~~
  65. Click on the links below for detailed API reference of the main UI data structures and functions.
  66. **Main data structures:**
  67. - :ref:`mjUI<mjUI>`: An entire UI.
  68. - :ref:`mjuiState<mjuiState>`: Global UI state.
  69. - :ref:`mjuiDef<mjuiDef>`: One entry in the definition table used for UI construction.
  70. **Main functions:**
  71. - :ref:`mjui_update<mjui_update>`: Main UI update function.
  72. - :ref:`mjui_render<mjui_render>`: Renders the UI.
  73. - :ref:`mjui_event<mjui_event>`: Low-level event handler.
  74. - :ref:`mjui_add<mjui_add>`: Helper function used to construct a UI.