| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
- <head>
- <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
- <meta http-equiv="X-UA-Compatible" content="IE=11"/>
- <meta name="generator" content="Doxygen 1.9.8"/>
- <meta name="viewport" content="width=device-width, initial-scale=1"/>
- <title>Nuklear: Layouting</title>
- <link href="tabs.css" rel="stylesheet" type="text/css"/>
- <script type="text/javascript" src="jquery.js"></script>
- <script type="text/javascript" src="dynsections.js"></script>
- <link href="navtree.css" rel="stylesheet" type="text/css"/>
- <script type="text/javascript" src="resize.js"></script>
- <script type="text/javascript" src="navtreedata.js"></script>
- <script type="text/javascript" src="navtree.js"></script>
- <link href="search/search.css" rel="stylesheet" type="text/css"/>
- <script type="text/javascript" src="search/searchdata.js"></script>
- <script type="text/javascript" src="search/search.js"></script>
- <script type="text/javascript">
- /* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */
- $(document).ready(function() { init_search(); });
- /* @license-end */
- </script>
- <link href="doxygen.css" rel="stylesheet" type="text/css" />
- <link href="doxygen-awesome.css" rel="stylesheet" type="text/css"/>
- </head>
- <body>
- <div id="top"><!-- do not remove this div, it is closed by doxygen! -->
- <div id="titlearea">
- <table cellspacing="0" cellpadding="0">
- <tbody>
- <tr id="projectrow">
- <td id="projectalign">
- <div id="projectname">Nuklear
- </div>
- <div id="projectbrief">This is a minimal-state, immediate-mode graphical user interface toolkit written in ANSI C and licensed under public domain. It was designed as a simple embeddable user interface for application and does not have any dependencies, a default render backend or OS window/input handling but instead provides a highly modular, library-based approach, with simple input state for input and draw commands describing primitive shapes as output. So instead of providing a layered library that tries to abstract over a number of platform and render backends, it focuses only on the actual UI.</div>
- </td>
- <td> <div id="MSearchBox" class="MSearchBoxInactive">
- <span class="left">
- <span id="MSearchSelect" onmouseover="return searchBox.OnSearchSelectShow()" onmouseout="return searchBox.OnSearchSelectHide()"> </span>
- <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
- onfocus="searchBox.OnSearchFieldFocus(true)"
- onblur="searchBox.OnSearchFieldFocus(false)"
- onkeyup="searchBox.OnSearchFieldChange(event)"/>
- </span><span class="right">
- <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
- </span>
- </div>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- <!-- end header part -->
- <!-- Generated by Doxygen 1.9.8 -->
- <script type="text/javascript">
- /* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */
- var searchBox = new SearchBox("searchBox", "search/",'.html');
- /* @license-end */
- </script>
- </div><!-- top -->
- <div id="side-nav" class="ui-resizable side-nav-resizable">
- <div id="nav-tree">
- <div id="nav-tree-contents">
- <div id="nav-sync" class="sync"></div>
- </div>
- </div>
- <div id="splitbar" style="-moz-user-select:none;"
- class="ui-resizable-handle">
- </div>
- </div>
- <script type="text/javascript">
- /* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */
- $(document).ready(function(){initNavTree('Layouting.html',''); initResizable(); });
- /* @license-end */
- </script>
- <div id="doc-content">
- <!-- window showing the filter options -->
- <div id="MSearchSelectWindow"
- onmouseover="return searchBox.OnSearchSelectShow()"
- onmouseout="return searchBox.OnSearchSelectHide()"
- onkeydown="return searchBox.OnSearchSelectKey(event)">
- </div>
- <!-- iframe showing the search results (closed by default) -->
- <div id="MSearchResultsWindow">
- <div id="MSearchResults">
- <div class="SRPage">
- <div id="SRIndex">
- <div id="SRResults"></div>
- <div class="SRStatus" id="Loading">Loading...</div>
- <div class="SRStatus" id="Searching">Searching...</div>
- <div class="SRStatus" id="NoMatches">No Matches</div>
- </div>
- </div>
- </div>
- </div>
- <div><div class="header">
- <div class="headertitle"><div class="title">Layouting</div></div>
- </div><!--header-->
- <div class="contents">
- <div class="textblock"><p>Layouting in general describes placing widget inside a window with position and size.</p>
- <p>While in this particular implementation there are five different APIs for layouting each with different trade offs between control and ease of use. <br />
- <br />
- </p>
- <p>All layouting methods in this library are based around the concept of a row. A row has a height the window content grows by and a number of columns and each layouting method specifies how each widget is placed inside the row. After a row has been allocated by calling a layouting functions and then filled with widgets will advance an internal pointer over the allocated row. <br />
- <br />
- </p>
- <p>To actually define a layout you just call the appropriate layouting function and each subsequent widget call will place the widget as specified. Important here is that if you define more widgets then columns defined inside the layout functions it will allocate the next row without you having to make another layouting <br />
- <br />
- call.</p>
- <p>Biggest limitation with using all these APIs outside the <code>nk_layout_space_xxx</code> API is that you have to define the row height for each. However the row height often depends on the height of the font. <br />
- <br />
- </p>
- <p>To fix that internally nuklear uses a minimum row height that is set to the height plus padding of currently active font and overwrites the row height value if zero. <br />
- <br />
- </p>
- <p>If you manually want to change the minimum row height then use nk_layout_set_min_row_height, and use nk_layout_reset_min_row_height to reset it back to be derived from font height. <br />
- <br />
- </p>
- <p>Also if you change the font in nuklear it will automatically change the minimum row height for you and. This means if you change the font but still want a minimum row height smaller than the font you have to repush your value. <br />
- <br />
- </p>
- <p>For actually more advanced UI I would even recommend using the <code>nk_layout_space_xxx</code> layouting method in combination with a cassowary constraint solver (there are some versions on github with permissive license model) to take over all control over widget layouting yourself. However for quick and dirty layouting using all the other layouting functions should be fine.</p>
- <h1><a class="anchor" id="autotoc_md57"></a>
- Usage</h1>
- <ol type="1">
- <li><p class="startli"><b>nk_layout_row_dynamic</b><br />
- <br />
- The easiest layouting function is <code>nk_layout_row_dynamic</code>. It provides each widgets with same horizontal space inside the row and dynamically grows if the owning window grows in width. So the number of columns dictates the size of each widget dynamically by formula:</p>
- <p class="startli"><code>c widget_width = (window_width - padding - spacing) * (1/column_count) </code></p>
- <p class="startli">Just like all other layouting APIs if you define more widget than columns this library will allocate a new row and keep all layouting parameters previously defined.</p>
- <p class="startli"><code>c if (nk_begin_xxx(...) { // first row with height: 30 composed of two widgets nk_layout_row_dynamic(&ctx, 30, 2); nk_widget(...); nk_widget(...); // // second row with same parameter as defined above nk_widget(...); nk_widget(...); // // third row uses 0 for height which will use auto layouting nk_layout_row_dynamic(&ctx, 0, 2); nk_widget(...); nk_widget(...); } nk_end(...); </code></p>
- </li>
- <li><p class="startli"><b>nk_layout_row_static</b><br />
- <br />
- Another easy layouting function is <code>nk_layout_row_static</code>. It provides each widget with same horizontal pixel width inside the row and does not grow if the owning window scales smaller or bigger.</p>
- <p class="startli"><code>c if (nk_begin_xxx(...) { // first row with height: 30 composed of two widgets with width: 80 nk_layout_row_static(&ctx, 30, 80, 2); nk_widget(...); nk_widget(...); // // second row with same parameter as defined above nk_widget(...); nk_widget(...); // // third row uses 0 for height which will use auto layouting nk_layout_row_static(&ctx, 0, 80, 2); nk_widget(...); nk_widget(...); } nk_end(...); </code></p>
- </li>
- <li><p class="startli"><b>nk_layout_row_xxx</b><br />
- <br />
- A little bit more advanced layouting API are functions <code>nk_layout_row_begin</code>, <code>nk_layout_row_push</code> and <code>nk_layout_row_end</code>. They allow to directly specify each column pixel or window ratio in a row. It supports either directly setting per column pixel width or widget window ratio but not both. Furthermore it is a immediate mode API so each value is directly pushed before calling a widget. Therefore the layout is not automatically repeating like the last two layouting functions.</p>
- <p class="startli"><code>c if (nk_begin_xxx(...) { // first row with height: 25 composed of two widgets with width 60 and 40 nk_layout_row_begin(ctx, NK_STATIC, 25, 2); nk_layout_row_push(ctx, 60); nk_widget(...); nk_layout_row_push(ctx, 40); nk_widget(...); nk_layout_row_end(ctx); // // second row with height: 25 composed of two widgets with window ratio 0.25 and 0.75 nk_layout_row_begin(ctx, NK_DYNAMIC, 25, 2); nk_layout_row_push(ctx, 0.25f); nk_widget(...); nk_layout_row_push(ctx, 0.75f); nk_widget(...); nk_layout_row_end(ctx); // // third row with auto generated height: composed of two widgets with window ratio 0.25 and 0.75 nk_layout_row_begin(ctx, NK_DYNAMIC, 0, 2); nk_layout_row_push(ctx, 0.25f); nk_widget(...); nk_layout_row_push(ctx, 0.75f); nk_widget(...); nk_layout_row_end(ctx); } nk_end(...); </code></p>
- </li>
- <li><p class="startli"><b>nk_layout_row</b><br />
- <br />
- The array counterpart to API nk_layout_row_xxx is the single nk_layout_row functions. Instead of pushing either pixel or window ratio for every widget it allows to define it by array. The trade of for less control is that <code>nk_layout_row</code> is automatically repeating. Otherwise the behavior is the same.</p>
- <p class="startli"><code>c if (nk_begin_xxx(...) { // two rows with height: 30 composed of two widgets with width 60 and 40 const float ratio[] = {60,40}; nk_layout_row(ctx, NK_STATIC, 30, 2, ratio); nk_widget(...); nk_widget(...); nk_widget(...); nk_widget(...); // // two rows with height: 30 composed of two widgets with window ratio 0.25 and 0.75 const float ratio[] = {0.25, 0.75}; nk_layout_row(ctx, NK_DYNAMIC, 30, 2, ratio); nk_widget(...); nk_widget(...); nk_widget(...); nk_widget(...); // // two rows with auto generated height composed of two widgets with window ratio 0.25 and 0.75 const float ratio[] = {0.25, 0.75}; nk_layout_row(ctx, NK_DYNAMIC, 30, 2, ratio); nk_widget(...); nk_widget(...); nk_widget(...); nk_widget(...); } nk_end(...); </code></p>
- </li>
- <li><p class="startli"><b>nk_layout_row_template_xxx</b><br />
- <br />
- The most complex and second most flexible API is a simplified flexbox version without line wrapping and weights for dynamic widgets. It is an immediate mode API but unlike <code>nk_layout_row_xxx</code> it has auto repeat behavior and needs to be called before calling the templated widgets. The row template layout has three different per widget size specifier. The first one is the <code>nk_layout_row_template_push_static</code> with fixed widget pixel width. They do not grow if the row grows and will always stay the same. The second size specifier is <code>nk_layout_row_template_push_variable</code> which defines a minimum widget size but it also can grow if more space is available not taken by other widgets. Finally there are dynamic widgets with <code>nk_layout_row_template_push_dynamic</code> which are completely flexible and unlike variable widgets can even shrink to zero if not enough space is provided.</p>
- <p class="startli"><code>c if (nk_begin_xxx(...) { // two rows with height: 30 composed of three widgets nk_layout_row_template_begin(ctx, 30); nk_layout_row_template_push_dynamic(ctx); nk_layout_row_template_push_variable(ctx, 80); nk_layout_row_template_push_static(ctx, 80); nk_layout_row_template_end(ctx); // // first row nk_widget(...); // dynamic widget can go to zero if not enough space nk_widget(...); // variable widget with min 80 pixel but can grow bigger if enough space nk_widget(...); // static widget with fixed 80 pixel width // // second row same layout nk_widget(...); nk_widget(...); nk_widget(...); } nk_end(...); </code></p>
- </li>
- <li><p class="startli"><b>nk_layout_space_xxx</b><br />
- <br />
- Finally the most flexible API directly allows you to place widgets inside the window. The space layout API is an immediate mode API which does not support row auto repeat and directly sets position and size of a widget. Position and size hereby can be either specified as ratio of allocated space or allocated space local position and pixel size. Since this API is quite powerful there are a number of utility functions to get the available space and convert between local allocated space and screen space.</p>
- <p class="startli"><code>c if (nk_begin_xxx(...) { // static row with height: 500 (you can set column count to INT_MAX if you don't want to be bothered) nk_layout_space_begin(ctx, NK_STATIC, 500, INT_MAX); nk_layout_space_push(ctx, nk_rect(0,0,150,200)); nk_widget(...); nk_layout_space_push(ctx, nk_rect(200,200,100,200)); nk_widget(...); nk_layout_space_end(ctx); // // dynamic row with height: 500 (you can set column count to INT_MAX if you don't want to be bothered) nk_layout_space_begin(ctx, NK_DYNAMIC, 500, INT_MAX); nk_layout_space_push(ctx, <a class="el" href="structnk__rect.html">nk_rect</a>(0.5,0.5,0.1,0.1)); nk_widget(...); nk_layout_space_push(ctx, <a class="el" href="structnk__rect.html">nk_rect</a>(0.7,0.6,0.1,0.1)); nk_widget(...); } nk_end(...); </code></p>
- </li>
- </ol>
- <h1><a class="anchor" id="autotoc_md58"></a>
- Reference</h1>
- <table class="markdownTable">
- <tr class="markdownTableHead">
- <th class="markdownTableHeadNone">Function </th><th class="markdownTableHeadNone">Description </th></tr>
- <tr class="markdownTableRowOdd">
- <td class="markdownTableBodyNone"><a class="el" href="nuklear_8h.html#aa0f2bd54b2ca26744dc1d019c10824c4">nk_layout_set_min_row_height</a> </td><td class="markdownTableBodyNone">Set the currently used minimum row height to a specified value </td></tr>
- <tr class="markdownTableRowEven">
- <td class="markdownTableBodyNone"><a class="el" href="nuklear_8h.html#a89484639fccf5ad9d7a3bd7a4c6f61c4">nk_layout_reset_min_row_height</a> </td><td class="markdownTableBodyNone">Resets the currently used minimum row height to font height </td></tr>
- <tr class="markdownTableRowOdd">
- <td class="markdownTableBodyNone"><a class="el" href="nuklear_8h.html#ab781f44009d6c85898ab8484a1d09797">nk_layout_widget_bounds</a> </td><td class="markdownTableBodyNone">Calculates current width a static layout row can fit inside a window </td></tr>
- <tr class="markdownTableRowEven">
- <td class="markdownTableBodyNone"><a class="el" href="nuklear_8h.html#ab638c3eb41863167e6d63782f1b03da5">nk_layout_ratio_from_pixel</a> </td><td class="markdownTableBodyNone">Utility functions to calculate window ratio from pixel size </td></tr>
- <tr class="markdownTableRowOdd">
- <td class="markdownTableBodyNone"><a class="el" href="nuklear_8h.html#a76e65dc775c0bd5efaa3c8f38f96823f">nk_layout_row_dynamic</a> </td><td class="markdownTableBodyNone">Current layout is divided into n same sized growing columns </td></tr>
- <tr class="markdownTableRowEven">
- <td class="markdownTableBodyNone"><a class="el" href="nuklear_8h.html#af8176018717fa81e62969ca5830414e3">nk_layout_row_static</a> </td><td class="markdownTableBodyNone">Current layout is divided into n same fixed sized columns </td></tr>
- <tr class="markdownTableRowOdd">
- <td class="markdownTableBodyNone"><a class="el" href="nuklear_8h.html#aa6fa7480529cb74d07dd28c9c26d6549">nk_layout_row_begin</a> </td><td class="markdownTableBodyNone">Starts a new row with given height and number of columns </td></tr>
- <tr class="markdownTableRowEven">
- <td class="markdownTableBodyNone"><a class="el" href="nuklear_8h.html#ab6fb149f7829d6c5f7361c93f26066aa">nk_layout_row_push</a> </td><td class="markdownTableBodyNone">Pushes another column with given size or window ratio </td></tr>
- <tr class="markdownTableRowOdd">
- <td class="markdownTableBodyNone"><a class="el" href="nuklear_8h.html#a14c7337d52877793ae04968e75f2c21f">nk_layout_row_end</a> </td><td class="markdownTableBodyNone">Finished previously started row </td></tr>
- <tr class="markdownTableRowEven">
- <td class="markdownTableBodyNone"><a class="el" href="nuklear_8h.html#a2cff6f5c2a9078eb768ac753b63a5c31">nk_layout_row</a> </td><td class="markdownTableBodyNone">Specifies row columns in array as either window ratio or size </td></tr>
- <tr class="markdownTableRowOdd">
- <td class="markdownTableBodyNone"><a class="el" href="nuklear_8h.html#ab4d9ca7699d2c14a607d743224519c09">nk_layout_row_template_begin</a> </td><td class="markdownTableBodyNone">Begins the row template declaration </td></tr>
- <tr class="markdownTableRowEven">
- <td class="markdownTableBodyNone"><a class="el" href="nuklear_8h.html#a47e464949ca9a44f483d327edb99e51b">nk_layout_row_template_push_dynamic</a> </td><td class="markdownTableBodyNone">Adds a dynamic column that dynamically grows and can go to zero if not enough space </td></tr>
- <tr class="markdownTableRowOdd">
- <td class="markdownTableBodyNone"><a class="el" href="nuklear_8h.html#ae89deb176b082dbbf6fec568bc21a860">nk_layout_row_template_push_variable</a> </td><td class="markdownTableBodyNone">Adds a variable column that dynamically grows but does not shrink below specified pixel width </td></tr>
- <tr class="markdownTableRowEven">
- <td class="markdownTableBodyNone"><a class="el" href="nuklear_8h.html#a6836529c6d66e638eee38ba3da0d4d56">nk_layout_row_template_push_static</a> </td><td class="markdownTableBodyNone">Adds a static column that does not grow and will always have the same size </td></tr>
- <tr class="markdownTableRowOdd">
- <td class="markdownTableBodyNone"><a class="el" href="nuklear_8h.html#a85583ce3aa0054fc050bb165fc580462">nk_layout_row_template_end</a> </td><td class="markdownTableBodyNone">Marks the end of the row template </td></tr>
- <tr class="markdownTableRowEven">
- <td class="markdownTableBodyNone"><a class="el" href="nuklear_8h.html#ace378fd581870e7045334ca5a7cd8f2e">nk_layout_space_begin</a> </td><td class="markdownTableBodyNone">Begins a new layouting space that allows to specify each widgets position and size </td></tr>
- <tr class="markdownTableRowOdd">
- <td class="markdownTableBodyNone"><a class="el" href="nuklear_8h.html#aafd65bb1d45bb98e147ec1d76173242e">nk_layout_space_push</a> </td><td class="markdownTableBodyNone">Pushes position and size of the next widget in own coordinate space either as pixel or ratio </td></tr>
- <tr class="markdownTableRowEven">
- <td class="markdownTableBodyNone"><a class="el" href="nuklear_8h.html#a2231e266013063456f3b20f882a9831e">nk_layout_space_end</a> </td><td class="markdownTableBodyNone">Marks the end of the layouting space </td></tr>
- <tr class="markdownTableRowOdd">
- <td class="markdownTableBodyNone"><a class="el" href="nuklear_8h.html#acf7221ac37ad8e7054a89b54f0278405">nk_layout_space_bounds</a> </td><td class="markdownTableBodyNone">Callable after nk_layout_space_begin and returns total space allocated </td></tr>
- <tr class="markdownTableRowEven">
- <td class="markdownTableBodyNone"><a class="el" href="nuklear_8h.html#a3bf8ed829f20eeee39b9fb6f734ff9ce">nk_layout_space_to_screen</a> </td><td class="markdownTableBodyNone">Converts vector from nk_layout_space coordinate space into screen space </td></tr>
- <tr class="markdownTableRowOdd">
- <td class="markdownTableBodyNone"><a class="el" href="nuklear_8h.html#a4f05d86822b6809dc276645517151895">nk_layout_space_to_local</a> </td><td class="markdownTableBodyNone">Converts vector from screen space into nk_layout_space coordinates </td></tr>
- <tr class="markdownTableRowEven">
- <td class="markdownTableBodyNone"><a class="el" href="nuklear_8h.html#ab7ed4576104cc5d0e2d3b91094772e86">nk_layout_space_rect_to_screen</a> </td><td class="markdownTableBodyNone">Converts rectangle from nk_layout_space coordinate space into screen space </td></tr>
- <tr class="markdownTableRowOdd">
- <td class="markdownTableBodyNone"><a class="el" href="nuklear_8h.html#a936ad1078428b94f079d22f7f6691950">nk_layout_space_rect_to_local</a> </td><td class="markdownTableBodyNone">Converts rectangle from screen space into nk_layout_space coordinates </td></tr>
- </table>
- </div></div><!-- contents -->
- </div><!-- PageDoc -->
- </div><!-- doc-content -->
- <!-- start footer part -->
- <div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
- <ul>
- <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.8 </li>
- </ul>
- </div>
- </body>
- </html>
|