1 /*
2 Blendish - Blender 2.5 UI based theming functions for NanoVG
3 
4 Copyright (c) 2014 Leonard Ritter <leonard.ritter@duangle.com>
5 
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12 
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15 
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 THE SOFTWARE.
23 */
24 
25 #ifndef BLENDISH_H
26 #define BLENDISH_H
27 
28 #ifndef NANOVG_H
29 #error "nanovg.h must be included first."
30 #endif
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
36 /*
37 
38 Revision 6 (2014-09-21)
39 
40 Summary
41 -------
42 
43 Blendish is a small collection of drawing functions for NanoVG, designed to
44 replicate the look of the Blender 2.5+ User Interface. You can use these
45 functions to theme your UI library. Several metric constants for faithful
46 reproduction are also included.
47 
48 Blendish supports the original Blender icon sheet; As the licensing of Blenders
49 icons is unclear, they are not included in Blendishes repository, but a SVG
50 template, "icons_template.svg" is provided, which you can use to build your own
51 icon sheet.
52 
53 To use icons, you must first load the icon sheet using one of the
54 nvgCreateImage*() functions and then pass the image handle to bndSetIconImage();
55 otherwise, no icons will be drawn. See bndSetIconImage() for more information.
56 
57 Blendish will not render text until a suitable UI font has been passed to
58 bndSetFont() has been called. See bndSetFont() for more information.
59 
60 
61 Drawbacks
62 ---------
63 
64 There is no support for varying dpi resolutions yet. The library is hardcoded
65 to the equivalent of 72 dpi in the Blender system settings.
66 
67 Support for label truncation is missing. Text rendering breaks when widgets are
68 too short to contain their labels.
69 
70 Usage
71 -----
72 
73 To use this header file in implementation mode, define BLENDISH_IMPLEMENTATION
74 before including blendish.h, otherwise the file will be in header-only mode.
75 
76 */
77 
78 // you can override this from the outside to pick
79 // the export level you need
80 #ifndef BND_EXPORT
81 #define BND_EXPORT
82 #endif
83 
84 // if that typedef is provided elsewhere, you may define
85 // BLENDISH_NO_NVG_TYPEDEFS before including the header.
86 #ifndef BLENDISH_NO_NVG_TYPEDEFS
87 typedef struct NVGcontext NVGcontext;
88 typedef struct NVGcolor NVGcolor;
89 typedef struct NVGglyphPosition NVGglyphPosition;
90 #endif
91 
92 // describes the theme used to draw a single widget or widget box;
93 // these values correspond to the same values that can be retrieved from
94 // the Theme panel in the Blender preferences
95 typedef struct BNDwidgetTheme {
96     // color of widget box outline
97     NVGcolor outlineColor;
98     // color of widget item (meaning changes depending on class)
99     NVGcolor itemColor;
100     // fill color of widget box
101     NVGcolor innerColor;
102     // fill color of widget box when active
103     NVGcolor innerSelectedColor;
104     // color of text label
105     NVGcolor textColor;
106     // color of text label when active
107     NVGcolor textSelectedColor;
108     // delta modifier for upper part of gradient (-100 to 100)
109     int shadeTop;
110     // delta modifier for lower part of gradient (-100 to 100)
111     int shadeDown;
112 } BNDwidgetTheme;
113 
114 // describes the theme used to draw nodes
115 typedef struct BNDnodeTheme {
116     // inner color of selected node (and downarrow)
117     NVGcolor nodeSelectedColor;
118     // outline of wires
119     NVGcolor wiresColor;
120     // color of text label when active
121     NVGcolor textSelectedColor;
122 
123     // inner color of active node (and dragged wire)
124     NVGcolor activeNodeColor;
125     // color of selected wire
126     NVGcolor wireSelectColor;
127     // color of background of node
128     NVGcolor nodeBackdropColor;
129 
130     // how much a noodle curves (0 to 10)
131     int noodleCurving;
132 } BNDnodeTheme;
133 
134 // describes the theme used to draw widgets
135 typedef struct BNDtheme {
136     // the background color of panels and windows
137     NVGcolor backgroundColor;
138     // theme for labels
139     BNDwidgetTheme regularTheme;
140     // theme for tool buttons
141     BNDwidgetTheme toolTheme;
142     // theme for radio buttons
143     BNDwidgetTheme radioTheme;
144     // theme for text fields
145     BNDwidgetTheme textFieldTheme;
146     // theme for option buttons (checkboxes)
147     BNDwidgetTheme optionTheme;
148     // theme for choice buttons (comboboxes)
149     // Blender calls them "menu buttons"
150     BNDwidgetTheme choiceTheme;
151     // theme for number fields
152     BNDwidgetTheme numberFieldTheme;
153     // theme for slider controls
154     BNDwidgetTheme sliderTheme;
155     // theme for scrollbars
156     BNDwidgetTheme scrollBarTheme;
157     // theme for tooltips
158     BNDwidgetTheme tooltipTheme;
159     // theme for menu backgrounds
160     BNDwidgetTheme menuTheme;
161     // theme for menu items
162     BNDwidgetTheme menuItemTheme;
163     // theme for nodes
164     BNDnodeTheme nodeTheme;
165 } BNDtheme;
166 
167 // how text on a control is aligned
168 typedef enum BNDtextAlignment {
169     BND_LEFT = 0,
170     BND_CENTER,
171 } BNDtextAlignment;
172 
173 // states altering the styling of a widget
174 typedef enum BNDwidgetState {
175     // not interacting
176     BND_DEFAULT = 0,
177     // the mouse is hovering over the control
178     BND_HOVER,
179     // the widget is activated (pressed) or in an active state (toggled)
180     BND_ACTIVE
181 } BNDwidgetState;
182 
183 // flags indicating which corners are sharp (for grouping widgets)
184 typedef enum BNDcornerFlags {
185     // all corners are round
186     BND_CORNER_NONE = 0,
187     // sharp top left corner
188     BND_CORNER_TOP_LEFT = 1,
189     // sharp top right corner
190     BND_CORNER_TOP_RIGHT = 2,
191     // sharp bottom right corner
192     BND_CORNER_DOWN_RIGHT = 4,
193     // sharp bottom left corner
194     BND_CORNER_DOWN_LEFT = 8,
195     // all corners are sharp;
196     // you can invert a set of flags using ^= BND_CORNER_ALL
197     BND_CORNER_ALL = 0xF,
198     // top border is sharp
199     BND_CORNER_TOP = 3,
200     // bottom border is sharp
201     BND_CORNER_DOWN = 0xC,
202     // left border is sharp
203     BND_CORNER_LEFT = 9,
204     // right border is sharp
205     BND_CORNER_RIGHT = 6
206 } BNDcornerFlags;
207 
208 // build an icon ID from two coordinates into the icon sheet, where
209 // (0,0) designates the upper-leftmost icon, (1,0) the one right next to it,
210 // and so on.
211 #define BND_ICONID(x,y) ((x)|((y)<<8))
212 // alpha of disabled widget groups
213 // can be used in conjunction with nvgGlobalAlpha()
214 #define BND_DISABLED_ALPHA 0.5
215 
216 enum {
217 	// default widget height
218 	BND_WIDGET_HEIGHT = 21,
219 	// default toolbutton width (if icon only)
220 	BND_TOOL_WIDTH = 20,
221 
222 	// default radius of node ports
223 	BND_NODE_PORT_RADIUS = 5,
224 	// top margin of node content
225 	BND_NODE_MARGIN_TOP = 25,
226 	// bottom margin of node content
227 	BND_NODE_MARGIN_DOWN = 5,
228 	// left and right margin of node content
229 	BND_NODE_MARGIN_SIDE = 10,
230 	// height of node title bar
231 	BND_NODE_TITLE_HEIGHT = 20,
232 	// width of node title arrow click area
233 	BND_NODE_ARROW_AREA_WIDTH = 20,
234 
235 	// size of splitter corner click area
236 	BND_SPLITTER_AREA_SIZE = 12,
237 
238 	// width of vertical scrollbar
239 	BND_SCROLLBAR_WIDTH = 13,
240 	// height of horizontal scrollbar
241 	BND_SCROLLBAR_HEIGHT = 14,
242 
243 	// default vertical spacing
244 	BND_VSPACING = 1,
245 	// default vertical spacing between groups
246 	BND_VSPACING_GROUP = 8,
247 	// default horizontal spacing
248 	BND_HSPACING = 8,
249 };
250 
251 typedef enum BNDicon {
252 	BND_ICON_NONE = BND_ICONID(0,29),
253 	BND_ICON_QUESTION = BND_ICONID(1,29),
254 	BND_ICON_ERROR = BND_ICONID(2,29),
255 	BND_ICON_CANCEL = BND_ICONID(3,29),
256 	BND_ICON_TRIA_RIGHT = BND_ICONID(4,29),
257 	BND_ICON_TRIA_DOWN = BND_ICONID(5,29),
258 	BND_ICON_TRIA_LEFT = BND_ICONID(6,29),
259 	BND_ICON_TRIA_UP = BND_ICONID(7,29),
260 	BND_ICON_ARROW_LEFTRIGHT = BND_ICONID(8,29),
261 	BND_ICON_PLUS = BND_ICONID(9,29),
262 	BND_ICON_DISCLOSURE_TRI_DOWN = BND_ICONID(10,29),
263 	BND_ICON_DISCLOSURE_TRI_RIGHT = BND_ICONID(11,29),
264 	BND_ICON_RADIOBUT_OFF = BND_ICONID(12,29),
265 	BND_ICON_RADIOBUT_ON = BND_ICONID(13,29),
266 	BND_ICON_MENU_PANEL = BND_ICONID(14,29),
267 	BND_ICON_BLENDER = BND_ICONID(15,29),
268 	BND_ICON_GRIP = BND_ICONID(16,29),
269 	BND_ICON_DOT = BND_ICONID(17,29),
270 	BND_ICON_COLLAPSEMENU = BND_ICONID(18,29),
271 	BND_ICON_X = BND_ICONID(19,29),
272 	BND_ICON_GO_LEFT = BND_ICONID(21,29),
273 	BND_ICON_PLUG = BND_ICONID(22,29),
274 	BND_ICON_UI = BND_ICONID(23,29),
275 	BND_ICON_NODE = BND_ICONID(24,29),
276 	BND_ICON_NODE_SEL = BND_ICONID(25,29),
277 
278 	BND_ICON_FULLSCREEN = BND_ICONID(0,28),
279 	BND_ICON_SPLITSCREEN = BND_ICONID(1,28),
280 	BND_ICON_RIGHTARROW_THIN = BND_ICONID(2,28),
281 	BND_ICON_BORDERMOVE = BND_ICONID(3,28),
282 	BND_ICON_VIEWZOOM = BND_ICONID(4,28),
283 	BND_ICON_ZOOMIN = BND_ICONID(5,28),
284 	BND_ICON_ZOOMOUT = BND_ICONID(6,28),
285 	BND_ICON_PANEL_CLOSE = BND_ICONID(7,28),
286 	BND_ICON_COPY_ID = BND_ICONID(8,28),
287 	BND_ICON_EYEDROPPER = BND_ICONID(9,28),
288 	BND_ICON_LINK_AREA = BND_ICONID(10,28),
289 	BND_ICON_AUTO = BND_ICONID(11,28),
290 	BND_ICON_CHECKBOX_DEHLT = BND_ICONID(12,28),
291 	BND_ICON_CHECKBOX_HLT = BND_ICONID(13,28),
292 	BND_ICON_UNLOCKED = BND_ICONID(14,28),
293 	BND_ICON_LOCKED = BND_ICONID(15,28),
294 	BND_ICON_UNPINNED = BND_ICONID(16,28),
295 	BND_ICON_PINNED = BND_ICONID(17,28),
296 	BND_ICON_SCREEN_BACK = BND_ICONID(18,28),
297 	BND_ICON_RIGHTARROW = BND_ICONID(19,28),
298 	BND_ICON_DOWNARROW_HLT = BND_ICONID(20,28),
299 	BND_ICON_DOTSUP = BND_ICONID(21,28),
300 	BND_ICON_DOTSDOWN = BND_ICONID(22,28),
301 	BND_ICON_LINK = BND_ICONID(23,28),
302 	BND_ICON_INLINK = BND_ICONID(24,28),
303 	BND_ICON_PLUGIN = BND_ICONID(25,28),
304 
305 	BND_ICON_HELP = BND_ICONID(0,27),
306 	BND_ICON_GHOST_ENABLED = BND_ICONID(1,27),
307 	BND_ICON_COLOR = BND_ICONID(2,27),
308 	BND_ICON_LINKED = BND_ICONID(3,27),
309 	BND_ICON_UNLINKED = BND_ICONID(4,27),
310 	BND_ICON_HAND = BND_ICONID(5,27),
311 	BND_ICON_ZOOM_ALL = BND_ICONID(6,27),
312 	BND_ICON_ZOOM_SELECTED = BND_ICONID(7,27),
313 	BND_ICON_ZOOM_PREVIOUS = BND_ICONID(8,27),
314 	BND_ICON_ZOOM_IN = BND_ICONID(9,27),
315 	BND_ICON_ZOOM_OUT = BND_ICONID(10,27),
316 	BND_ICON_RENDER_REGION = BND_ICONID(11,27),
317 	BND_ICON_BORDER_RECT = BND_ICONID(12,27),
318 	BND_ICON_BORDER_LASSO = BND_ICONID(13,27),
319 	BND_ICON_FREEZE = BND_ICONID(14,27),
320 	BND_ICON_STYLUS_PRESSURE = BND_ICONID(15,27),
321 	BND_ICON_GHOST_DISABLED = BND_ICONID(16,27),
322 	BND_ICON_NEW = BND_ICONID(17,27),
323 	BND_ICON_FILE_TICK = BND_ICONID(18,27),
324 	BND_ICON_QUIT = BND_ICONID(19,27),
325 	BND_ICON_URL = BND_ICONID(20,27),
326 	BND_ICON_RECOVER_LAST = BND_ICONID(21,27),
327 	BND_ICON_FULLSCREEN_ENTER = BND_ICONID(23,27),
328 	BND_ICON_FULLSCREEN_EXIT = BND_ICONID(24,27),
329 	BND_ICON_BLANK1 = BND_ICONID(25,27),
330 
331 	BND_ICON_LAMP = BND_ICONID(0,26),
332 	BND_ICON_MATERIAL = BND_ICONID(1,26),
333 	BND_ICON_TEXTURE = BND_ICONID(2,26),
334 	BND_ICON_ANIM = BND_ICONID(3,26),
335 	BND_ICON_WORLD = BND_ICONID(4,26),
336 	BND_ICON_SCENE = BND_ICONID(5,26),
337 	BND_ICON_EDIT = BND_ICONID(6,26),
338 	BND_ICON_GAME = BND_ICONID(7,26),
339 	BND_ICON_RADIO = BND_ICONID(8,26),
340 	BND_ICON_SCRIPT = BND_ICONID(9,26),
341 	BND_ICON_PARTICLES = BND_ICONID(10,26),
342 	BND_ICON_PHYSICS = BND_ICONID(11,26),
343 	BND_ICON_SPEAKER = BND_ICONID(12,26),
344 	BND_ICON_TEXTURE_SHADED = BND_ICONID(13,26),
345 
346 	BND_ICON_VIEW3D = BND_ICONID(0,25),
347 	BND_ICON_IPO = BND_ICONID(1,25),
348 	BND_ICON_OOPS = BND_ICONID(2,25),
349 	BND_ICON_BUTS = BND_ICONID(3,25),
350 	BND_ICON_FILESEL = BND_ICONID(4,25),
351 	BND_ICON_IMAGE_COL = BND_ICONID(5,25),
352 	BND_ICON_INFO = BND_ICONID(6,25),
353 	BND_ICON_SEQUENCE = BND_ICONID(7,25),
354 	BND_ICON_TEXT = BND_ICONID(8,25),
355 	BND_ICON_IMASEL = BND_ICONID(9,25),
356 	BND_ICON_SOUND = BND_ICONID(10,25),
357 	BND_ICON_ACTION = BND_ICONID(11,25),
358 	BND_ICON_NLA = BND_ICONID(12,25),
359 	BND_ICON_SCRIPTWIN = BND_ICONID(13,25),
360 	BND_ICON_TIME = BND_ICONID(14,25),
361 	BND_ICON_NODETREE = BND_ICONID(15,25),
362 	BND_ICON_LOGIC = BND_ICONID(16,25),
363 	BND_ICON_CONSOLE = BND_ICONID(17,25),
364 	BND_ICON_PREFERENCES = BND_ICONID(18,25),
365 	BND_ICON_CLIP = BND_ICONID(19,25),
366 	BND_ICON_ASSET_MANAGER = BND_ICONID(20,25),
367 
368 	BND_ICON_OBJECT_DATAMODE = BND_ICONID(0,24),
369 	BND_ICON_EDITMODE_HLT = BND_ICONID(1,24),
370 	BND_ICON_FACESEL_HLT = BND_ICONID(2,24),
371 	BND_ICON_VPAINT_HLT = BND_ICONID(3,24),
372 	BND_ICON_TPAINT_HLT = BND_ICONID(4,24),
373 	BND_ICON_WPAINT_HLT = BND_ICONID(5,24),
374 	BND_ICON_SCULPTMODE_HLT = BND_ICONID(6,24),
375 	BND_ICON_POSE_HLT = BND_ICONID(7,24),
376 	BND_ICON_PARTICLEMODE = BND_ICONID(8,24),
377 	BND_ICON_LIGHTPAINT = BND_ICONID(9,24),
378 
379 	BND_ICON_SCENE_DATA = BND_ICONID(0,23),
380 	BND_ICON_RENDERLAYERS = BND_ICONID(1,23),
381 	BND_ICON_WORLD_DATA = BND_ICONID(2,23),
382 	BND_ICON_OBJECT_DATA = BND_ICONID(3,23),
383 	BND_ICON_MESH_DATA = BND_ICONID(4,23),
384 	BND_ICON_CURVE_DATA = BND_ICONID(5,23),
385 	BND_ICON_META_DATA = BND_ICONID(6,23),
386 	BND_ICON_LATTICE_DATA = BND_ICONID(7,23),
387 	BND_ICON_LAMP_DATA = BND_ICONID(8,23),
388 	BND_ICON_MATERIAL_DATA = BND_ICONID(9,23),
389 	BND_ICON_TEXTURE_DATA = BND_ICONID(10,23),
390 	BND_ICON_ANIM_DATA = BND_ICONID(11,23),
391 	BND_ICON_CAMERA_DATA = BND_ICONID(12,23),
392 	BND_ICON_PARTICLE_DATA = BND_ICONID(13,23),
393 	BND_ICON_LIBRARY_DATA_DIRECT = BND_ICONID(14,23),
394 	BND_ICON_GROUP = BND_ICONID(15,23),
395 	BND_ICON_ARMATURE_DATA = BND_ICONID(16,23),
396 	BND_ICON_POSE_DATA = BND_ICONID(17,23),
397 	BND_ICON_BONE_DATA = BND_ICONID(18,23),
398 	BND_ICON_CONSTRAINT = BND_ICONID(19,23),
399 	BND_ICON_SHAPEKEY_DATA = BND_ICONID(20,23),
400 	BND_ICON_CONSTRAINT_BONE = BND_ICONID(21,23),
401 	BND_ICON_CAMERA_STEREO = BND_ICONID(22,23),
402 	BND_ICON_PACKAGE = BND_ICONID(23,23),
403 	BND_ICON_UGLYPACKAGE = BND_ICONID(24,23),
404 
405 	BND_ICON_BRUSH_DATA = BND_ICONID(0,22),
406 	BND_ICON_IMAGE_DATA = BND_ICONID(1,22),
407 	BND_ICON_FILE = BND_ICONID(2,22),
408 	BND_ICON_FCURVE = BND_ICONID(3,22),
409 	BND_ICON_FONT_DATA = BND_ICONID(4,22),
410 	BND_ICON_RENDER_RESULT = BND_ICONID(5,22),
411 	BND_ICON_SURFACE_DATA = BND_ICONID(6,22),
412 	BND_ICON_EMPTY_DATA = BND_ICONID(7,22),
413 	BND_ICON_SETTINGS = BND_ICONID(8,22),
414 	BND_ICON_RENDER_ANIMATION = BND_ICONID(9,22),
415 	BND_ICON_RENDER_STILL = BND_ICONID(10,22),
416 	BND_ICON_BOIDS = BND_ICONID(12,22),
417 	BND_ICON_STRANDS = BND_ICONID(13,22),
418 	BND_ICON_LIBRARY_DATA_INDIRECT = BND_ICONID(14,22),
419 	BND_ICON_GREASEPENCIL = BND_ICONID(15,22),
420 	BND_ICON_LINE_DATA = BND_ICONID(16,22),
421 	BND_ICON_GROUP_BONE = BND_ICONID(18,22),
422 	BND_ICON_GROUP_VERTEX = BND_ICONID(19,22),
423 	BND_ICON_GROUP_VCOL = BND_ICONID(20,22),
424 	BND_ICON_GROUP_UVS = BND_ICONID(21,22),
425 	BND_ICON_RNA = BND_ICONID(24,22),
426 	BND_ICON_RNA_ADD = BND_ICONID(25,22),
427 
428 	BND_ICON_OUTLINER_OB_EMPTY = BND_ICONID(0,20),
429 	BND_ICON_OUTLINER_OB_MESH = BND_ICONID(1,20),
430 	BND_ICON_OUTLINER_OB_CURVE = BND_ICONID(2,20),
431 	BND_ICON_OUTLINER_OB_LATTICE = BND_ICONID(3,20),
432 	BND_ICON_OUTLINER_OB_META = BND_ICONID(4,20),
433 	BND_ICON_OUTLINER_OB_LAMP = BND_ICONID(5,20),
434 	BND_ICON_OUTLINER_OB_CAMERA = BND_ICONID(6,20),
435 	BND_ICON_OUTLINER_OB_ARMATURE = BND_ICONID(7,20),
436 	BND_ICON_OUTLINER_OB_FONT = BND_ICONID(8,20),
437 	BND_ICON_OUTLINER_OB_SURFACE = BND_ICONID(9,20),
438 	BND_ICON_OUTLINER_OB_SPEAKER = BND_ICONID(10,20),
439 	BND_ICON_RESTRICT_VIEW_OFF = BND_ICONID(19,20),
440 	BND_ICON_RESTRICT_VIEW_ON = BND_ICONID(20,20),
441 	BND_ICON_RESTRICT_SELECT_OFF = BND_ICONID(21,20),
442 	BND_ICON_RESTRICT_SELECT_ON = BND_ICONID(22,20),
443 	BND_ICON_RESTRICT_RENDER_OFF = BND_ICONID(23,20),
444 	BND_ICON_RESTRICT_RENDER_ON = BND_ICONID(24,20),
445 
446 	BND_ICON_OUTLINER_DATA_EMPTY = BND_ICONID(0,19),
447 	BND_ICON_OUTLINER_DATA_MESH = BND_ICONID(1,19),
448 	BND_ICON_OUTLINER_DATA_CURVE = BND_ICONID(2,19),
449 	BND_ICON_OUTLINER_DATA_LATTICE = BND_ICONID(3,19),
450 	BND_ICON_OUTLINER_DATA_META = BND_ICONID(4,19),
451 	BND_ICON_OUTLINER_DATA_LAMP = BND_ICONID(5,19),
452 	BND_ICON_OUTLINER_DATA_CAMERA = BND_ICONID(6,19),
453 	BND_ICON_OUTLINER_DATA_ARMATURE = BND_ICONID(7,19),
454 	BND_ICON_OUTLINER_DATA_FONT = BND_ICONID(8,19),
455 	BND_ICON_OUTLINER_DATA_SURFACE = BND_ICONID(9,19),
456 	BND_ICON_OUTLINER_DATA_SPEAKER = BND_ICONID(10,19),
457 	BND_ICON_OUTLINER_DATA_POSE = BND_ICONID(11,19),
458 
459 	BND_ICON_MESH_PLANE = BND_ICONID(0,18),
460 	BND_ICON_MESH_CUBE = BND_ICONID(1,18),
461 	BND_ICON_MESH_CIRCLE = BND_ICONID(2,18),
462 	BND_ICON_MESH_UVSPHERE = BND_ICONID(3,18),
463 	BND_ICON_MESH_ICOSPHERE = BND_ICONID(4,18),
464 	BND_ICON_MESH_GRID = BND_ICONID(5,18),
465 	BND_ICON_MESH_MONKEY = BND_ICONID(6,18),
466 	BND_ICON_MESH_CYLINDER = BND_ICONID(7,18),
467 	BND_ICON_MESH_TORUS = BND_ICONID(8,18),
468 	BND_ICON_MESH_CONE = BND_ICONID(9,18),
469 	BND_ICON_LAMP_POINT = BND_ICONID(12,18),
470 	BND_ICON_LAMP_SUN = BND_ICONID(13,18),
471 	BND_ICON_LAMP_SPOT = BND_ICONID(14,18),
472 	BND_ICON_LAMP_HEMI = BND_ICONID(15,18),
473 	BND_ICON_LAMP_AREA = BND_ICONID(16,18),
474 	BND_ICON_META_EMPTY = BND_ICONID(19,18),
475 	BND_ICON_META_PLANE = BND_ICONID(20,18),
476 	BND_ICON_META_CUBE = BND_ICONID(21,18),
477 	BND_ICON_META_BALL = BND_ICONID(22,18),
478 	BND_ICON_META_ELLIPSOID = BND_ICONID(23,18),
479 	BND_ICON_META_CAPSULE = BND_ICONID(24,18),
480 
481 	BND_ICON_SURFACE_NCURVE = BND_ICONID(0,17),
482 	BND_ICON_SURFACE_NCIRCLE = BND_ICONID(1,17),
483 	BND_ICON_SURFACE_NSURFACE = BND_ICONID(2,17),
484 	BND_ICON_SURFACE_NCYLINDER = BND_ICONID(3,17),
485 	BND_ICON_SURFACE_NSPHERE = BND_ICONID(4,17),
486 	BND_ICON_SURFACE_NTORUS = BND_ICONID(5,17),
487 	BND_ICON_CURVE_BEZCURVE = BND_ICONID(9,17),
488 	BND_ICON_CURVE_BEZCIRCLE = BND_ICONID(10,17),
489 	BND_ICON_CURVE_NCURVE = BND_ICONID(11,17),
490 	BND_ICON_CURVE_NCIRCLE = BND_ICONID(12,17),
491 	BND_ICON_CURVE_PATH = BND_ICONID(13,17),
492 	BND_ICON_COLOR_RED = BND_ICONID(19,17),
493 	BND_ICON_COLOR_GREEN = BND_ICONID(20,17),
494 	BND_ICON_COLOR_BLUE = BND_ICONID(21,17),
495 
496 	BND_ICON_FORCE_FORCE = BND_ICONID(0,16),
497 	BND_ICON_FORCE_WIND = BND_ICONID(1,16),
498 	BND_ICON_FORCE_VORTEX = BND_ICONID(2,16),
499 	BND_ICON_FORCE_MAGNETIC = BND_ICONID(3,16),
500 	BND_ICON_FORCE_HARMONIC = BND_ICONID(4,16),
501 	BND_ICON_FORCE_CHARGE = BND_ICONID(5,16),
502 	BND_ICON_FORCE_LENNARDJONES = BND_ICONID(6,16),
503 	BND_ICON_FORCE_TEXTURE = BND_ICONID(7,16),
504 	BND_ICON_FORCE_CURVE = BND_ICONID(8,16),
505 	BND_ICON_FORCE_BOID = BND_ICONID(9,16),
506 	BND_ICON_FORCE_TURBULENCE = BND_ICONID(10,16),
507 	BND_ICON_FORCE_DRAG = BND_ICONID(11,16),
508 	BND_ICON_FORCE_SMOKEFLOW = BND_ICONID(12,16),
509 
510 	BND_ICON_MODIFIER = BND_ICONID(0,12),
511 	BND_ICON_MOD_WAVE = BND_ICONID(1,12),
512 	BND_ICON_MOD_BUILD = BND_ICONID(2,12),
513 	BND_ICON_MOD_DECIM = BND_ICONID(3,12),
514 	BND_ICON_MOD_MIRROR = BND_ICONID(4,12),
515 	BND_ICON_MOD_SOFT = BND_ICONID(5,12),
516 	BND_ICON_MOD_SUBSURF = BND_ICONID(6,12),
517 	BND_ICON_HOOK = BND_ICONID(7,12),
518 	BND_ICON_MOD_PHYSICS = BND_ICONID(8,12),
519 	BND_ICON_MOD_PARTICLES = BND_ICONID(9,12),
520 	BND_ICON_MOD_BOOLEAN = BND_ICONID(10,12),
521 	BND_ICON_MOD_EDGESPLIT = BND_ICONID(11,12),
522 	BND_ICON_MOD_ARRAY = BND_ICONID(12,12),
523 	BND_ICON_MOD_UVPROJECT = BND_ICONID(13,12),
524 	BND_ICON_MOD_DISPLACE = BND_ICONID(14,12),
525 	BND_ICON_MOD_CURVE = BND_ICONID(15,12),
526 	BND_ICON_MOD_LATTICE = BND_ICONID(16,12),
527 	BND_ICON_CONSTRAINT_DATA = BND_ICONID(17,12),
528 	BND_ICON_MOD_ARMATURE = BND_ICONID(18,12),
529 	BND_ICON_MOD_SHRINKWRAP = BND_ICONID(19,12),
530 	BND_ICON_MOD_CAST = BND_ICONID(20,12),
531 	BND_ICON_MOD_MESHDEFORM = BND_ICONID(21,12),
532 	BND_ICON_MOD_BEVEL = BND_ICONID(22,12),
533 	BND_ICON_MOD_SMOOTH = BND_ICONID(23,12),
534 	BND_ICON_MOD_SIMPLEDEFORM = BND_ICONID(24,12),
535 	BND_ICON_MOD_MASK = BND_ICONID(25,12),
536 
537 	BND_ICON_MOD_CLOTH = BND_ICONID(0,11),
538 	BND_ICON_MOD_EXPLODE = BND_ICONID(1,11),
539 	BND_ICON_MOD_FLUIDSIM = BND_ICONID(2,11),
540 	BND_ICON_MOD_MULTIRES = BND_ICONID(3,11),
541 	BND_ICON_MOD_SMOKE = BND_ICONID(4,11),
542 	BND_ICON_MOD_SOLIDIFY = BND_ICONID(5,11),
543 	BND_ICON_MOD_SCREW = BND_ICONID(6,11),
544 	BND_ICON_MOD_VERTEX_WEIGHT = BND_ICONID(7,11),
545 	BND_ICON_MOD_DYNAMICPAINT = BND_ICONID(8,11),
546 	BND_ICON_MOD_REMESH = BND_ICONID(9,11),
547 	BND_ICON_MOD_OCEAN = BND_ICONID(10,11),
548 	BND_ICON_MOD_WARP = BND_ICONID(11,11),
549 	BND_ICON_MOD_SKIN = BND_ICONID(12,11),
550 	BND_ICON_MOD_TRIANGULATE = BND_ICONID(13,11),
551 	BND_ICON_MOD_WIREFRAME = BND_ICONID(14,11),
552 
553 	BND_ICON_REC = BND_ICONID(0,10),
554 	BND_ICON_PLAY = BND_ICONID(1,10),
555 	BND_ICON_FF = BND_ICONID(2,10),
556 	BND_ICON_REW = BND_ICONID(3,10),
557 	BND_ICON_PAUSE = BND_ICONID(4,10),
558 	BND_ICON_PREV_KEYFRAME = BND_ICONID(5,10),
559 	BND_ICON_NEXT_KEYFRAME = BND_ICONID(6,10),
560 	BND_ICON_PLAY_AUDIO = BND_ICONID(7,10),
561 	BND_ICON_PLAY_REVERSE = BND_ICONID(8,10),
562 	BND_ICON_PREVIEW_RANGE = BND_ICONID(9,10),
563 	BND_ICON_ACTION_TWEAK = BND_ICONID(10,10),
564 	BND_ICON_PMARKER_ACT = BND_ICONID(11,10),
565 	BND_ICON_PMARKER_SEL = BND_ICONID(12,10),
566 	BND_ICON_PMARKER = BND_ICONID(13,10),
567 	BND_ICON_MARKER_HLT = BND_ICONID(14,10),
568 	BND_ICON_MARKER = BND_ICONID(15,10),
569 	BND_ICON_SPACE2 = BND_ICONID(16,10),
570 	BND_ICON_SPACE3 = BND_ICONID(17,10),
571 	BND_ICON_KEYINGSET = BND_ICONID(18,10),
572 	BND_ICON_KEY_DEHLT = BND_ICONID(19,10),
573 	BND_ICON_KEY_HLT = BND_ICONID(20,10),
574 	BND_ICON_MUTE_IPO_OFF = BND_ICONID(21,10),
575 	BND_ICON_MUTE_IPO_ON = BND_ICONID(22,10),
576 	BND_ICON_VISIBLE_IPO_OFF = BND_ICONID(23,10),
577 	BND_ICON_VISIBLE_IPO_ON = BND_ICONID(24,10),
578 	BND_ICON_DRIVER = BND_ICONID(25,10),
579 
580 	BND_ICON_SOLO_OFF = BND_ICONID(0,9),
581 	BND_ICON_SOLO_ON = BND_ICONID(1,9),
582 	BND_ICON_FRAME_PREV = BND_ICONID(2,9),
583 	BND_ICON_FRAME_NEXT = BND_ICONID(3,9),
584 	BND_ICON_NLA_PUSHDOWN = BND_ICONID(4,9),
585 	BND_ICON_IPO_CONSTANT = BND_ICONID(5,9),
586 	BND_ICON_IPO_LINEAR = BND_ICONID(6,9),
587 	BND_ICON_IPO_BEZIER = BND_ICONID(7,9),
588 	BND_ICON_IPO_SINE = BND_ICONID(8,9),
589 	BND_ICON_IPO_QUAD = BND_ICONID(9,9),
590 	BND_ICON_IPO_CUBIC = BND_ICONID(10,9),
591 	BND_ICON_IPO_QUART = BND_ICONID(11,9),
592 	BND_ICON_IPO_QUINT = BND_ICONID(12,9),
593 	BND_ICON_IPO_EXPO = BND_ICONID(13,9),
594 	BND_ICON_IPO_CIRC = BND_ICONID(14,9),
595 	BND_ICON_IPO_BOUNCE = BND_ICONID(15,9),
596 	BND_ICON_IPO_ELASTIC = BND_ICONID(16,9),
597 	BND_ICON_IPO_BACK = BND_ICONID(17,9),
598 	BND_ICON_IPO_EASE_IN = BND_ICONID(18,9),
599 	BND_ICON_IPO_EASE_OUT = BND_ICONID(19,9),
600 	BND_ICON_IPO_EASE_IN_OUT = BND_ICONID(20,9),
601 
602 	BND_ICON_VERTEXSEL = BND_ICONID(0,8),
603 	BND_ICON_EDGESEL = BND_ICONID(1,8),
604 	BND_ICON_FACESEL = BND_ICONID(2,8),
605 	BND_ICON_LOOPSEL = BND_ICONID(3,8),
606 	BND_ICON_ROTATE = BND_ICONID(5,8),
607 	BND_ICON_CURSOR = BND_ICONID(6,8),
608 	BND_ICON_ROTATECOLLECTION = BND_ICONID(7,8),
609 	BND_ICON_ROTATECENTER = BND_ICONID(8,8),
610 	BND_ICON_ROTACTIVE = BND_ICONID(9,8),
611 	BND_ICON_ALIGN = BND_ICONID(10,8),
612 	BND_ICON_SMOOTHCURVE = BND_ICONID(12,8),
613 	BND_ICON_SPHERECURVE = BND_ICONID(13,8),
614 	BND_ICON_ROOTCURVE = BND_ICONID(14,8),
615 	BND_ICON_SHARPCURVE = BND_ICONID(15,8),
616 	BND_ICON_LINCURVE = BND_ICONID(16,8),
617 	BND_ICON_NOCURVE = BND_ICONID(17,8),
618 	BND_ICON_RNDCURVE = BND_ICONID(18,8),
619 	BND_ICON_PROP_OFF = BND_ICONID(19,8),
620 	BND_ICON_PROP_ON = BND_ICONID(20,8),
621 	BND_ICON_PROP_CON = BND_ICONID(21,8),
622 	BND_ICON_SCULPT_DYNTOPO = BND_ICONID(22,8),
623 	BND_ICON_PARTICLE_POINT = BND_ICONID(23,8),
624 	BND_ICON_PARTICLE_TIP = BND_ICONID(24,8),
625 	BND_ICON_PARTICLE_PATH = BND_ICONID(25,8),
626 
627 	BND_ICON_MAN_TRANS = BND_ICONID(0,7),
628 	BND_ICON_MAN_ROT = BND_ICONID(1,7),
629 	BND_ICON_MAN_SCALE = BND_ICONID(2,7),
630 	BND_ICON_MANIPUL = BND_ICONID(3,7),
631 	BND_ICON_SNAP_OFF = BND_ICONID(4,7),
632 	BND_ICON_SNAP_ON = BND_ICONID(5,7),
633 	BND_ICON_SNAP_NORMAL = BND_ICONID(6,7),
634 	BND_ICON_SNAP_INCREMENT = BND_ICONID(7,7),
635 	BND_ICON_SNAP_VERTEX = BND_ICONID(8,7),
636 	BND_ICON_SNAP_EDGE = BND_ICONID(9,7),
637 	BND_ICON_SNAP_FACE = BND_ICONID(10,7),
638 	BND_ICON_SNAP_VOLUME = BND_ICONID(11,7),
639 	BND_ICON_STICKY_UVS_LOC = BND_ICONID(13,7),
640 	BND_ICON_STICKY_UVS_DISABLE = BND_ICONID(14,7),
641 	BND_ICON_STICKY_UVS_VERT = BND_ICONID(15,7),
642 	BND_ICON_CLIPUV_DEHLT = BND_ICONID(16,7),
643 	BND_ICON_CLIPUV_HLT = BND_ICONID(17,7),
644 	BND_ICON_SNAP_PEEL_OBJECT = BND_ICONID(18,7),
645 	BND_ICON_GRID = BND_ICONID(19,7),
646 
647 	BND_ICON_PASTEDOWN = BND_ICONID(0,6),
648 	BND_ICON_COPYDOWN = BND_ICONID(1,6),
649 	BND_ICON_PASTEFLIPUP = BND_ICONID(2,6),
650 	BND_ICON_PASTEFLIPDOWN = BND_ICONID(3,6),
651 	BND_ICON_SNAP_SURFACE = BND_ICONID(8,6),
652 	BND_ICON_AUTOMERGE_ON = BND_ICONID(9,6),
653 	BND_ICON_AUTOMERGE_OFF = BND_ICONID(10,6),
654 	BND_ICON_RETOPO = BND_ICONID(11,6),
655 	BND_ICON_UV_VERTEXSEL = BND_ICONID(12,6),
656 	BND_ICON_UV_EDGESEL = BND_ICONID(13,6),
657 	BND_ICON_UV_FACESEL = BND_ICONID(14,6),
658 	BND_ICON_UV_ISLANDSEL = BND_ICONID(15,6),
659 	BND_ICON_UV_SYNC_SELECT = BND_ICONID(16,6),
660 
661 	BND_ICON_BBOX = BND_ICONID(0,5),
662 	BND_ICON_WIRE = BND_ICONID(1,5),
663 	BND_ICON_SOLID = BND_ICONID(2,5),
664 	BND_ICON_SMOOTH = BND_ICONID(3,5),
665 	BND_ICON_POTATO = BND_ICONID(4,5),
666 	BND_ICON_ORTHO = BND_ICONID(6,5),
667 	BND_ICON_LOCKVIEW_OFF = BND_ICONID(9,5),
668 	BND_ICON_LOCKVIEW_ON = BND_ICONID(10,5),
669 	BND_ICON_AXIS_SIDE = BND_ICONID(12,5),
670 	BND_ICON_AXIS_FRONT = BND_ICONID(13,5),
671 	BND_ICON_AXIS_TOP = BND_ICONID(14,5),
672 	BND_ICON_NDOF_DOM = BND_ICONID(15,5),
673 	BND_ICON_NDOF_TURN = BND_ICONID(16,5),
674 	BND_ICON_NDOF_FLY = BND_ICONID(17,5),
675 	BND_ICON_NDOF_TRANS = BND_ICONID(18,5),
676 	BND_ICON_LAYER_USED = BND_ICONID(19,5),
677 	BND_ICON_LAYER_ACTIVE = BND_ICONID(20,5),
678 
679 	BND_ICON_SORTALPHA = BND_ICONID(0,3),
680 	BND_ICON_SORTBYEXT = BND_ICONID(1,3),
681 	BND_ICON_SORTTIME = BND_ICONID(2,3),
682 	BND_ICON_SORTSIZE = BND_ICONID(3,3),
683 	BND_ICON_LONGDISPLAY = BND_ICONID(4,3),
684 	BND_ICON_SHORTDISPLAY = BND_ICONID(5,3),
685 	BND_ICON_GHOST = BND_ICONID(6,3),
686 	BND_ICON_IMGDISPLAY = BND_ICONID(7,3),
687 	BND_ICON_SAVE_AS = BND_ICONID(8,3),
688 	BND_ICON_SAVE_COPY = BND_ICONID(9,3),
689 	BND_ICON_BOOKMARKS = BND_ICONID(10,3),
690 	BND_ICON_FONTPREVIEW = BND_ICONID(11,3),
691 	BND_ICON_FILTER = BND_ICONID(12,3),
692 	BND_ICON_NEWFOLDER = BND_ICONID(13,3),
693 	BND_ICON_OPEN_RECENT = BND_ICONID(14,3),
694 	BND_ICON_FILE_PARENT = BND_ICONID(15,3),
695 	BND_ICON_FILE_REFRESH = BND_ICONID(16,3),
696 	BND_ICON_FILE_FOLDER = BND_ICONID(17,3),
697 	BND_ICON_FILE_BLANK = BND_ICONID(18,3),
698 	BND_ICON_FILE_BLEND = BND_ICONID(19,3),
699 	BND_ICON_FILE_IMAGE = BND_ICONID(20,3),
700 	BND_ICON_FILE_MOVIE = BND_ICONID(21,3),
701 	BND_ICON_FILE_SCRIPT = BND_ICONID(22,3),
702 	BND_ICON_FILE_SOUND = BND_ICONID(23,3),
703 	BND_ICON_FILE_FONT = BND_ICONID(24,3),
704 	BND_ICON_FILE_TEXT = BND_ICONID(25,3),
705 
706 	BND_ICON_RECOVER_AUTO = BND_ICONID(0,2),
707 	BND_ICON_SAVE_PREFS = BND_ICONID(1,2),
708 	BND_ICON_LINK_BLEND = BND_ICONID(2,2),
709 	BND_ICON_APPEND_BLEND = BND_ICONID(3,2),
710 	BND_ICON_IMPORT = BND_ICONID(4,2),
711 	BND_ICON_EXPORT = BND_ICONID(5,2),
712 	BND_ICON_EXTERNAL_DATA = BND_ICONID(6,2),
713 	BND_ICON_LOAD_FACTORY = BND_ICONID(7,2),
714 	BND_ICON_LOOP_BACK = BND_ICONID(13,2),
715 	BND_ICON_LOOP_FORWARDS = BND_ICONID(14,2),
716 	BND_ICON_BACK = BND_ICONID(15,2),
717 	BND_ICON_FORWARD = BND_ICONID(16,2),
718 	BND_ICON_FILE_BACKUP = BND_ICONID(24,2),
719 	BND_ICON_DISK_DRIVE = BND_ICONID(25,2),
720 
721 	BND_ICON_MATPLANE = BND_ICONID(0,1),
722 	BND_ICON_MATSPHERE = BND_ICONID(1,1),
723 	BND_ICON_MATCUBE = BND_ICONID(2,1),
724 	BND_ICON_MONKEY = BND_ICONID(3,1),
725 	BND_ICON_HAIR = BND_ICONID(4,1),
726 	BND_ICON_ALIASED = BND_ICONID(5,1),
727 	BND_ICON_ANTIALIASED = BND_ICONID(6,1),
728 	BND_ICON_MAT_SPHERE_SKY = BND_ICONID(7,1),
729 	BND_ICON_WORDWRAP_OFF = BND_ICONID(12,1),
730 	BND_ICON_WORDWRAP_ON = BND_ICONID(13,1),
731 	BND_ICON_SYNTAX_OFF = BND_ICONID(14,1),
732 	BND_ICON_SYNTAX_ON = BND_ICONID(15,1),
733 	BND_ICON_LINENUMBERS_OFF = BND_ICONID(16,1),
734 	BND_ICON_LINENUMBERS_ON = BND_ICONID(17,1),
735 	BND_ICON_SCRIPTPLUGINS = BND_ICONID(18,1),
736 
737 	BND_ICON_SEQ_SEQUENCER = BND_ICONID(0,0),
738 	BND_ICON_SEQ_PREVIEW = BND_ICONID(1,0),
739 	BND_ICON_SEQ_LUMA_WAVEFORM = BND_ICONID(2,0),
740 	BND_ICON_SEQ_CHROMA_SCOPE = BND_ICONID(3,0),
741 	BND_ICON_SEQ_HISTOGRAM = BND_ICONID(4,0),
742 	BND_ICON_SEQ_SPLITVIEW = BND_ICONID(5,0),
743 	BND_ICON_IMAGE_RGB = BND_ICONID(9,0),
744 	BND_ICON_IMAGE_RGB_ALPHA = BND_ICONID(10,0),
745 	BND_ICON_IMAGE_ALPHA = BND_ICONID(11,0),
746 	BND_ICON_IMAGE_ZDEPTH = BND_ICONID(12,0),
747 	BND_ICON_IMAGEFILE = BND_ICONID(13,0),
748 } BNDicon;
749 
750 ////////////////////////////////////////////////////////////////////////////////
751 
752 // set the current theme all widgets will be drawn with.
753 // the default Blender 2.6 theme is set by default.
754 BND_EXPORT void bndSetTheme(BNDtheme theme);
755 
756 // Returns the currently set theme
757 BND_EXPORT const BNDtheme *bndGetTheme();
758 
759 // designates an image handle as returned by nvgCreateImage*() as the themes'
760 // icon sheet. The icon sheet format must be compatible to Blender 2.6's icon
761 // sheet; the order of icons does not matter.
762 // A valid icon sheet is e.g. shown at
763 // http://wiki.blender.org/index.php/Dev:2.5/Doc/How_to/Add_an_icon
764 BND_EXPORT void bndSetIconImage(int image);
765 
766 // designates an image handle as returned by nvgCreateFont*() as the themes'
767 // UI font. Blender's original UI font Droid Sans is perfectly suited and
768 // available here:
769 // https://svn.blender.org/svnroot/bf-blender/trunk/blender/release/datafiles/fonts/
770 BND_EXPORT void bndSetFont(int font);
771 
772 ////////////////////////////////////////////////////////////////////////////////
773 
774 // High Level Functions
775 // --------------------
776 // Use these functions to draw themed widgets with your NVGcontext.
777 
778 // Draw a label with its lower left origin at (x,y) and size of (w,h).
779 // if iconid >= 0, an icon will be added to the widget
780 // if label is not NULL, a label will be added to the widget
781 // widget looks best when height is BND_WIDGET_HEIGHT
782 BND_EXPORT void bndLabel(NVGcontext *ctx,
783     float x, float y, float w, float h, int iconid, const char *label);
784 
785 // Draw a tool button  with its lower left origin at (x,y) and size of (w,h),
786 // where flags is one or multiple flags from BNDcornerFlags and state denotes
787 // the widgets current UI state.
788 // if iconid >= 0, an icon will be added to the widget
789 // if label is not NULL, a label will be added to the widget
790 // widget looks best when height is BND_WIDGET_HEIGHT
791 BND_EXPORT void bndToolButton(NVGcontext *ctx,
792     float x, float y, float w, float h, int flags, BNDwidgetState state,
793     int iconid, const char *label);
794 
795 // Draw a radio button with its lower left origin at (x,y) and size of (w,h),
796 // where flags is one or multiple flags from BNDcornerFlags and state denotes
797 // the widgets current UI state.
798 // if iconid >= 0, an icon will be added to the widget
799 // if label is not NULL, a label will be added to the widget
800 // widget looks best when height is BND_WIDGET_HEIGHT
801 BND_EXPORT void bndRadioButton(NVGcontext *ctx,
802     float x, float y, float w, float h, int flags, BNDwidgetState state,
803     int iconid, const char *label);
804 
805 
806 // Calculate the corresponding text position for given coordinates px/py
807 // in a text field.
808 // See bndTextField for more info.
809 BND_EXPORT int bndTextFieldTextPosition(NVGcontext *ctx, float x, float y, float w, float h,
810     int iconid, const char *text, int px, int py);
811 
812 // Draw a text field with its lower left origin at (x,y) and size of (w,h),
813 // where flags is one or multiple flags from BNDcornerFlags and state denotes
814 // the widgets current UI state.
815 // if iconid >= 0, an icon will be added to the widget
816 // if text is not NULL, text will be printed to the widget
817 // cbegin must be >= 0 and <= strlen(text) and denotes the beginning of the caret
818 // cend must be >= cbegin and <= strlen(text) and denotes the end of the caret
819 // if cend < cbegin, then no caret will be drawn
820 // widget looks best when height is BND_WIDGET_HEIGHT
821 BND_EXPORT void bndTextField(NVGcontext *ctx,
822     float x, float y, float w, float h, int flags, BNDwidgetState state,
823     int iconid, const char *text, int cbegin, int cend);
824 
825 // Draw an option button with its lower left origin at (x,y) and size of (w,h),
826 // where flags is one or multiple flags from BNDcornerFlags and state denotes
827 // the widgets current UI state.
828 // if label is not NULL, a label will be added to the widget
829 // widget looks best when height is BND_WIDGET_HEIGHT
830 BND_EXPORT void bndOptionButton(NVGcontext *ctx,
831     float x, float y, float w, float h, BNDwidgetState state,
832     const char *label);
833 
834 // Draw a choice button with its lower left origin at (x,y) and size of (w,h),
835 // where flags is one or multiple flags from BNDcornerFlags and state denotes
836 // the widgets current UI state.
837 // if iconid >= 0, an icon will be added to the widget
838 // if label is not NULL, a label will be added to the widget
839 // widget looks best when height is BND_WIDGET_HEIGHT
840 BND_EXPORT void bndChoiceButton(NVGcontext *ctx,
841     float x, float y, float w, float h, int flags, BNDwidgetState state,
842     int iconid, const char *label);
843 
844 // Draw a color button  with its lower left origin at (x,y) and size of (w,h),
845 // where flags is one or multiple flags from BNDcornerFlags and state denotes
846 // the widgets current UI state.
847 // widget looks best when height is BND_WIDGET_HEIGHT
848 BND_EXPORT void bndColorButton(NVGcontext *ctx,
849     float x, float y, float w, float h, int flags, NVGcolor color);
850 
851 // Draw a number field with its lower left origin at (x,y) and size of (w,h),
852 // where flags is one or multiple flags from BNDcornerFlags and state denotes
853 // the widgets current UI state.
854 // if label is not NULL, a label will be added to the widget
855 // if value is not NULL, a value will be added to the widget, along with
856 // a ":" separator
857 // widget looks best when height is BND_WIDGET_HEIGHT
858 BND_EXPORT void bndNumberField(NVGcontext *ctx,
859     float x, float y, float w, float h, int flags, BNDwidgetState state,
860     const char *label, const char *value);
861 
862 // Draw slider control with its lower left origin at (x,y) and size of (w,h),
863 // where flags is one or multiple flags from BNDcornerFlags and state denotes
864 // the widgets current UI state.
865 // progress must be in the range 0..1 and controls the size of the slider bar
866 // if label is not NULL, a label will be added to the widget
867 // if value is not NULL, a value will be added to the widget, along with
868 // a ":" separator
869 // widget looks best when height is BND_WIDGET_HEIGHT
870 BND_EXPORT void bndSlider(NVGcontext *ctx,
871     float x, float y, float w, float h, int flags, BNDwidgetState state,
872     float progress, const char *label, const char *value);
873 
874 // Draw scrollbar with its lower left origin at (x,y) and size of (w,h),
875 // where state denotes the widgets current UI state.
876 // offset is in the range 0..1 and controls the position of the scroll handle
877 // size is in the range 0..1 and controls the size of the scroll handle
878 // horizontal widget looks best when height is BND_SCROLLBAR_HEIGHT,
879 // vertical looks best when width is BND_SCROLLBAR_WIDTH
880 BND_EXPORT void bndScrollBar(NVGcontext *ctx,
881     float x, float y, float w, float h, BNDwidgetState state,
882     float offset, float size);
883 
884 // Draw a menu background with its lower left origin at (x,y) and size of (w,h),
885 // where flags is one or multiple flags from BNDcornerFlags.
886 BND_EXPORT void bndMenuBackground(NVGcontext *ctx,
887     float x, float y, float w, float h, int flags);
888 
889 // Draw a menu label with its lower left origin at (x,y) and size of (w,h).
890 // if iconid >= 0, an icon will be added to the widget
891 // if label is not NULL, a label will be added to the widget
892 // widget looks best when height is BND_WIDGET_HEIGHT
893 BND_EXPORT void bndMenuLabel(NVGcontext *ctx,
894     float x, float y, float w, float h, int iconid, const char *label);
895 
896 // Draw a menu item with its lower left origin at (x,y) and size of (w,h),
897 // where state denotes the widgets current UI state.
898 // if iconid >= 0, an icon will be added to the widget
899 // if label is not NULL, a label will be added to the widget
900 // widget looks best when height is BND_WIDGET_HEIGHT
901 BND_EXPORT void bndMenuItem(NVGcontext *ctx,
902     float x, float y, float w, float h, BNDwidgetState state,
903     int iconid, const char *label);
904 
905 // Draw a tooltip background with its lower left origin at (x,y) and size of (w,h)
906 BND_EXPORT void bndTooltipBackground(NVGcontext *ctx, float x, float y, float w, float h);
907 
908 // Draw a node port at the given position filled with the given color
909 BND_EXPORT void bndNodePort(NVGcontext *ctx, float x, float y, BNDwidgetState state,
910     NVGcolor color);
911 
912 // Draw a node wire originating at (x0,y0) and floating to (x1,y1), with
913 // a colored gradient based on the states state0 and state1:
914 // BND_DEFAULT: default wire color
915 // BND_HOVER: selected wire color
916 // BND_ACTIVE: dragged wire color
917 BND_EXPORT void bndNodeWire(NVGcontext *ctx, float x0, float y0, float x1, float y1,
918     BNDwidgetState state0, BNDwidgetState state1);
919 
920 // Draw a node wire originating at (x0,y0) and floating to (x1,y1), with
921 // a colored gradient based on the two colors color0 and color1
922 BND_EXPORT void bndColoredNodeWire(NVGcontext *ctx, float x0, float y0, float x1, float y1,
923     NVGcolor color0, NVGcolor color1);
924 
925 // Draw a node background with its upper left origin at (x,y) and size of (w,h)
926 // where titleColor provides the base color for the title bar
927 BND_EXPORT void bndNodeBackground(NVGcontext *ctx, float x, float y, float w, float h,
928     BNDwidgetState state, int iconid, const char *label, NVGcolor titleColor);
929 
930 // Draw a window with the upper right and lower left splitter widgets into
931 // the rectangle at origin (x,y) and size (w, h)
932 BND_EXPORT void bndSplitterWidgets(NVGcontext *ctx, float x, float y, float w, float h);
933 
934 // Draw the join area overlay stencil into the rectangle
935 // at origin (x,y) and size (w,h)
936 // vertical is 0 or 1 and designates the arrow orientation,
937 // mirror is 0 or 1 and flips the arrow side
938 BND_EXPORT void bndJoinAreaOverlay(NVGcontext *ctx, float x, float y, float w, float h,
939     int vertical, int mirror);
940 
941 ////////////////////////////////////////////////////////////////////////////////
942 
943 // Estimator Functions
944 // -------------------
945 // Use these functions to estimate sizes for widgets with your NVGcontext.
946 
947 // returns the ideal width for a label with given icon and text
948 BND_EXPORT float bndLabelWidth(NVGcontext *ctx, int iconid, const char *label);
949 
950 // returns the height for a label with given icon, text and width; this
951 // function is primarily useful in conjunction with multiline labels and textboxes
952 BND_EXPORT float bndLabelHeight(NVGcontext *ctx, int iconid, const char *label,
953     float width);
954 
955 ////////////////////////////////////////////////////////////////////////////////
956 
957 // Low Level Functions
958 // -------------------
959 // these are part of the implementation detail and can be used to theme
960 // new kinds of controls in a similar fashion.
961 
962 // make color transparent using the default alpha value
963 BND_EXPORT NVGcolor bndTransparent(NVGcolor color);
964 
965 // offset a color by a given integer delta in the range -100 to 100
966 BND_EXPORT NVGcolor bndOffsetColor(NVGcolor color, int delta);
967 
968 // assigns radius r to the four entries of array radiuses depending on whether
969 // the corner is marked as sharp or not; see BNDcornerFlags for possible
970 // flag values.
971 BND_EXPORT void bndSelectCorners(float *radiuses, float r, int flags);
972 
973 // computes the upper and lower gradient colors for the inner box from a widget
974 // theme and the widgets state. If flipActive is set and the state is
975 // BND_ACTIVE, the upper and lower colors will be swapped.
976 BND_EXPORT void bndInnerColors(NVGcolor *shade_top, NVGcolor *shade_down,
977     const BNDwidgetTheme *theme, BNDwidgetState state, int flipActive);
978 
979 // computes the text color for a widget label from a widget theme and the
980 // widgets state.
981 BND_EXPORT NVGcolor bndTextColor(const BNDwidgetTheme *theme, BNDwidgetState state);
982 
983 // computes the bounds of the scrollbar handle from the scrollbar size
984 // and the handles offset and size.
985 // offset is in the range 0..1 and defines the position of the scroll handle
986 // size is in the range 0..1 and defines the size of the scroll handle
987 BND_EXPORT void bndScrollHandleRect(float *x, float *y, float *w, float *h,
988     float offset, float size);
989 
990 // Add a rounded box path at position (x,y) with size (w,h) and a separate
991 // radius for each corner listed in clockwise order, so that cr0 = top left,
992 // cr1 = top right, cr2 = bottom right, cr3 = bottom left;
993 // this is a low level drawing function: the path must be stroked or filled
994 // to become visible.
995 BND_EXPORT void bndRoundedBox(NVGcontext *ctx, float x, float y, float w, float h,
996     float cr0, float cr1, float cr2, float cr3);
997 
998 // Draw a flat panel without any decorations at position (x,y) with size (w,h)
999 // and fills it with backgroundColor
1000 BND_EXPORT void bndBackground(NVGcontext *ctx, float x, float y, float w, float h);
1001 
1002 // Draw a beveled border at position (x,y) with size (w,h) shaded with
1003 // lighter and darker versions of backgroundColor
1004 BND_EXPORT void bndBevel(NVGcontext *ctx, float x, float y, float w, float h);
1005 
1006 // Draw a lower inset for a rounded box at position (x,y) with size (w,h)
1007 // that gives the impression the surface has been pushed in.
1008 // cr2 and cr3 contain the radiuses of the bottom right and bottom left
1009 // corners of the rounded box.
1010 BND_EXPORT void bndBevelInset(NVGcontext *ctx, float x, float y, float w, float h,
1011     float cr2, float cr3);
1012 
1013 // Draw an icon with (x,y) as its upper left coordinate; the iconid selects
1014 // the icon from the sheet; use the BND_ICONID macro to build icon IDs.
1015 BND_EXPORT void bndIcon(NVGcontext *ctx, float x, float y, int iconid);
1016 
1017 // Draw a drop shadow around the rounded box at (x,y) with size (w,h) and
1018 // radius r, with feather as its maximum range in pixels.
1019 // No shadow will be painted inside the rounded box.
1020 BND_EXPORT void bndDropShadow(NVGcontext *ctx, float x, float y, float w, float h,
1021     float r, float feather, float alpha);
1022 
1023 // Draw the inner part of a widget box, with a gradient from shade_top to
1024 // shade_down. If h>w, the gradient will be horizontal instead of
1025 // vertical.
1026 BND_EXPORT void bndInnerBox(NVGcontext *ctx, float x, float y, float w, float h,
1027     float cr0, float cr1, float cr2, float cr3,
1028     NVGcolor shade_top, NVGcolor shade_down);
1029 
1030 // Draw the outline part of a widget box with the given color
1031 BND_EXPORT void bndOutlineBox(NVGcontext *ctx, float x, float y, float w, float h,
1032     float cr0, float cr1, float cr2, float cr3, NVGcolor color);
1033 
1034 // Draw an optional icon specified by <iconid> and an optional label with
1035 // given alignment (BNDtextAlignment), fontsize and color within a widget box.
1036 // if iconid is >= 0, an icon will be drawn and the labels remaining space
1037 // will be adjusted.
1038 // if label is not NULL, it will be drawn with the specified alignment, fontsize
1039 // and color.
1040 // if value is not NULL, label and value will be drawn with a ":" separator
1041 // inbetween.
1042 BND_EXPORT void bndIconLabelValue(NVGcontext *ctx, float x, float y, float w, float h,
1043     int iconid, NVGcolor color, int align, float fontsize, const char *label,
1044     const char *value);
1045 
1046 // Draw an optional icon specified by <iconid> and an optional label with
1047 // given alignment (BNDtextAlignment), fontsize and color within a node title bar
1048 // if iconid is >= 0, an icon will be drawn
1049 // if label is not NULL, it will be drawn with the specified alignment, fontsize
1050 // and color.
1051 BND_EXPORT void bndNodeIconLabel(NVGcontext *ctx, float x, float y, float w, float h,
1052     int iconid, NVGcolor color, NVGcolor shadowColor, int align,
1053     float fontsize, const char *label);
1054 
1055 // Calculate the corresponding text position for given coordinates px/py
1056 // in an iconLabel.
1057 // See bndIconLabelCaret for more info.
1058 BND_EXPORT int bndIconLabelTextPosition(NVGcontext *ctx, float x, float y, float w, float h,
1059     int iconid, float fontsize, const char *label, int px, int py);
1060 
1061 // Draw an optional icon specified by <iconid>, an optional label and
1062 // a caret with given fontsize and color within a widget box.
1063 // if iconid is >= 0, an icon will be drawn and the labels remaining space
1064 // will be adjusted.
1065 // if label is not NULL, it will be drawn with the specified alignment, fontsize
1066 // and color.
1067 // cbegin must be >= 0 and <= strlen(text) and denotes the beginning of the caret
1068 // cend must be >= cbegin and <= strlen(text) and denotes the end of the caret
1069 // if cend < cbegin, then no caret will be drawn
1070 BND_EXPORT void bndIconLabelCaret(NVGcontext *ctx, float x, float y, float w, float h,
1071     int iconid, NVGcolor color, float fontsize, const char *label,
1072     NVGcolor caretcolor, int cbegin, int cend);
1073 
1074 // Draw a checkmark for an option box with the given upper left coordinates
1075 // (ox,oy) with the specified color.
1076 BND_EXPORT void bndCheck(NVGcontext *ctx, float ox, float oy, NVGcolor color);
1077 
1078 // Draw a horizontal arrow for a number field with its center at (x,y) and
1079 // size s; if s is negative, the arrow points to the left.
1080 BND_EXPORT void bndArrow(NVGcontext *ctx, float x, float y, float s, NVGcolor color);
1081 
1082 // Draw an up/down arrow for a choice box with its center at (x,y) and size s
1083 BND_EXPORT void bndUpDownArrow(NVGcontext *ctx, float x, float y, float s, NVGcolor color);
1084 
1085 // Draw a node down-arrow with its tip at (x,y) and size s
1086 BND_EXPORT void bndNodeArrowDown(NVGcontext *ctx, float x, float y, float s, NVGcolor color);
1087 
1088 // return the color of a node wire based on state
1089 // BND_HOVER indicates selected state,
1090 // BND_ACTIVE indicates dragged state
1091 BND_EXPORT NVGcolor bndNodeWireColor(const BNDnodeTheme *theme, BNDwidgetState state);
1092 
1093 #ifdef __cplusplus
1094 };
1095 #endif
1096 
1097 #endif // BLENDISH_H
1098 
1099 ////////////////////////////////////////////////////////////////////////////////
1100 ////////////////////////////////////////////////////////////////////////////////
1101 
1102 #ifdef BLENDISH_IMPLEMENTATION
1103 
1104 #include <memory.h>
1105 #include <math.h>
1106 
1107 #ifdef _MSC_VER
1108     #pragma warning (disable: 4996) // Switch off security warnings
1109     #pragma warning (disable: 4100) // Switch off unreferenced formal parameter warnings
1110     #pragma warning (disable: 4244)
1111     #pragma warning (disable: 4305)
1112     #pragma warning (disable: 4838) // warning C4838: conversion from 'double' to 'float' requires a narrowing conversion
1113     #ifdef __cplusplus
1114     #define BND_INLINE inline
1115     #else
1116     #define BND_INLINE
1117     #endif
1118 
1119 #include <float.h>
1120 
bnd_fminf(float a,float b)1121 inline float bnd_fminf ( float a, float b )
1122 {
1123     return _isnan(a) ? b : ( _isnan(b) ? a : ((a < b) ? a : b));
1124 }
1125 
bnd_fmaxf(float a,float b)1126 inline float bnd_fmaxf ( float a, float b )
1127 {
1128     return _isnan(a) ? b : ( _isnan(b) ? a : ((a > b) ? a : b));
1129 }
1130 
bnd_fmin(double a,double b)1131 inline double bnd_fmin ( double a, double b )
1132 {
1133     return _isnan(a) ? b : ( _isnan(b) ? a : ((a < b) ? a : b));
1134 }
1135 
bnd_fmax(double a,double b)1136 inline double bnd_fmax ( double a, double b )
1137 {
1138     return _isnan(a) ? b : ( _isnan(b) ? a : ((a > b) ? a : b));
1139 }
1140 
1141 #else
1142     #define BND_INLINE inline
1143     #define bnd_fminf(a, b) fminf(a, b)
1144     #define bnd_fmaxf(a, b) fmaxf(a, b)
1145     #define bnd_fmin(a, b) fmin(a, b)
1146     #define bnd_fmax(a, b) fmax(a, b)
1147 #endif
1148 
1149 ////////////////////////////////////////////////////////////////////////////////
1150 
1151 // default text size
1152 #define BND_LABEL_FONT_SIZE 13
1153 
1154 // default text padding in inner box
1155 #define BND_PAD_LEFT 8
1156 #define BND_PAD_RIGHT 8
1157 
1158 // label: value separator string
1159 #define BND_LABEL_SEPARATOR ": "
1160 
1161 // alpha intensity of transparent items (0xa4)
1162 #define BND_TRANSPARENT_ALPHA 0.643
1163 
1164 // shade intensity of beveled panels
1165 #define BND_BEVEL_SHADE 30
1166 // shade intensity of beveled insets
1167 #define BND_INSET_BEVEL_SHADE 30
1168 // shade intensity of hovered inner boxes
1169 #define BND_HOVER_SHADE 15
1170 // shade intensity of splitter bevels
1171 #define BND_SPLITTER_SHADE 100
1172 
1173 // width of icon sheet
1174 #define BND_ICON_SHEET_WIDTH 602
1175 // height of icon sheet
1176 #define BND_ICON_SHEET_HEIGHT 640
1177 // gridsize of icon sheet in both dimensions
1178 #define BND_ICON_SHEET_GRID 21
1179 // offset of first icon tile relative to left border
1180 #define BND_ICON_SHEET_OFFSET_X 5
1181 // offset of first icon tile relative to top border
1182 #define BND_ICON_SHEET_OFFSET_Y 10
1183 // resolution of single icon
1184 #define BND_ICON_SHEET_RES 16
1185 
1186 // size of number field arrow
1187 #define BND_NUMBER_ARROW_SIZE 4
1188 
1189 // default text color
1190 #define BND_COLOR_TEXT {{{ 0,0,0,1 }}}
1191 // default highlighted text color
1192 #define BND_COLOR_TEXT_SELECTED {{{ 1,1,1,1 }}}
1193 
1194 // radius of tool button
1195 #define BND_TOOL_RADIUS 4
1196 
1197 // radius of option button
1198 #define BND_OPTION_RADIUS 4
1199 // width of option button checkbox
1200 #define BND_OPTION_WIDTH 14
1201 // height of option button checkbox
1202 #define BND_OPTION_HEIGHT 15
1203 
1204 // radius of text field
1205 #define BND_TEXT_RADIUS 4
1206 
1207 // radius of number button
1208 #define BND_NUMBER_RADIUS 10
1209 
1210 // radius of menu popup
1211 #define BND_MENU_RADIUS 3
1212 // feather of menu popup shadow
1213 #define BND_SHADOW_FEATHER 12
1214 // alpha of menu popup shadow
1215 #define BND_SHADOW_ALPHA 0.5
1216 
1217 // radius of scrollbar
1218 #define BND_SCROLLBAR_RADIUS 7
1219 // shade intensity of active scrollbar
1220 #define BND_SCROLLBAR_ACTIVE_SHADE 15
1221 
1222 // max glyphs for position testing
1223 #define BND_MAX_GLYPHS 1024
1224 
1225 // max rows for position testing
1226 #define BND_MAX_ROWS 32
1227 
1228 // text distance from bottom
1229 #define BND_TEXT_PAD_DOWN 7
1230 
1231 // stroke width of wire outline
1232 #define BND_NODE_WIRE_OUTLINE_WIDTH 4
1233 // stroke width of wire
1234 #define BND_NODE_WIRE_WIDTH 2
1235 // radius of node box
1236 #define BND_NODE_RADIUS 8
1237 // feather of node title text
1238 #define BND_NODE_TITLE_FEATHER 1
1239 // size of node title arrow
1240 #define BND_NODE_ARROW_SIZE 9
1241 
1242 ////////////////////////////////////////////////////////////////////////////////
1243 
bnd_clamp(float v,float mn,float mx)1244 BND_INLINE float bnd_clamp(float v, float mn, float mx) {
1245     return (v > mx)?mx:(v < mn)?mn:v;
1246 }
1247 
1248 ////////////////////////////////////////////////////////////////////////////////
1249 
1250 // the initial theme
1251 static BNDtheme bnd_theme = {
1252     // backgroundColor
1253     {{{ 0.447, 0.447, 0.447, 1.0 }}},
1254     // regularTheme
1255     {
1256         {{{ 0.098,0.098,0.098,1 }}}, // color_outline
1257         {{{ 0.098,0.098,0.098,1 }}}, // color_item
1258         {{{ 0.6,0.6,0.6,1 }}}, // color_inner
1259         {{{ 0.392,0.392,0.392,1 }}}, // color_inner_selected
1260         BND_COLOR_TEXT, // color_text
1261         BND_COLOR_TEXT_SELECTED, // color_text_selected
1262         0, // shade_top
1263         0, // shade_down
1264     },
1265     // toolTheme
1266     {
1267         {{{ 0.098,0.098,0.098,1 }}}, // color_outline
1268         {{{ 0.098,0.098,0.098,1 }}}, // color_item
1269         {{{ 0.6,0.6,0.6,1 }}}, // color_inner
1270         {{{ 0.392,0.392,0.392,1 }}}, // color_inner_selected
1271         BND_COLOR_TEXT, // color_text
1272         BND_COLOR_TEXT_SELECTED, // color_text_selected
1273         15, // shade_top
1274         -15, // shade_down
1275     },
1276     // radioTheme
1277     {
1278         {{{ 0,0,0,1 }}}, // color_outline
1279         {{{ 1,1,1,1 }}}, // color_item
1280         {{{ 0.275,0.275,0.275,1 }}}, // color_inner
1281         {{{ 0.337,0.502,0.761,1 }}}, // color_inner_selected
1282         BND_COLOR_TEXT_SELECTED, // color_text
1283         BND_COLOR_TEXT, // color_text_selected
1284         15, // shade_top
1285         -15, // shade_down
1286     },
1287     // textFieldTheme
1288     {
1289         {{{ 0.098,0.098,0.098,1 }}}, // color_outline
1290         {{{ 0.353, 0.353, 0.353,1 }}}, // color_item
1291         {{{ 0.6, 0.6, 0.6,1 }}}, // color_inner
1292         {{{ 0.6, 0.6, 0.6,1 }}}, // color_inner_selected
1293         BND_COLOR_TEXT, // color_text
1294         BND_COLOR_TEXT_SELECTED, // color_text_selected
1295         0, // shade_top
1296         25, // shade_down
1297     },
1298     // optionTheme
1299     {
1300         {{{ 0,0,0,1 }}}, // color_outline
1301         {{{ 1,1,1,1 }}}, // color_item
1302         {{{ 0.275,0.275,0.275,1 }}}, // color_inner
1303         {{{ 0.275,0.275,0.275,1 }}}, // color_inner_selected
1304         BND_COLOR_TEXT, // color_text
1305         BND_COLOR_TEXT_SELECTED, // color_text_selected
1306         15, // shade_top
1307         -15, // shade_down
1308     },
1309     // choiceTheme
1310     {
1311         {{{ 0,0,0,1 }}}, // color_outline
1312         {{{ 1,1,1,1 }}}, // color_item
1313         {{{ 0.275,0.275,0.275,1 }}}, // color_inner
1314         {{{ 0.275,0.275,0.275,1 }}}, // color_inner_selected
1315         BND_COLOR_TEXT_SELECTED, // color_text
1316         {{{ 0.8,0.8,0.8,1 }}}, // color_text_selected
1317         15, // shade_top
1318         -15, // shade_down
1319     },
1320     // numberFieldTheme
1321     {
1322         {{{ 0.098,0.098,0.098,1 }}}, // color_outline
1323         {{{ 0.353, 0.353, 0.353,1 }}}, // color_item
1324         {{{ 0.706, 0.706, 0.706,1 }}}, // color_inner
1325         {{{ 0.6, 0.6, 0.6,1 }}}, // color_inner_selected
1326         BND_COLOR_TEXT, // color_text
1327         BND_COLOR_TEXT_SELECTED, // color_text_selected
1328         -20, // shade_top
1329         0, // shade_down
1330     },
1331     // sliderTheme
1332     {
1333         {{{ 0.098,0.098,0.098,1 }}}, // color_outline
1334         {{{ 0.502,0.502,0.502,1 }}}, // color_item
1335         {{{ 0.706, 0.706, 0.706,1 }}}, // color_inner
1336         {{{ 0.6, 0.6, 0.6,1 }}}, // color_inner_selected
1337         BND_COLOR_TEXT, // color_text
1338         BND_COLOR_TEXT_SELECTED, // color_text_selected
1339         -20, // shade_top
1340         0, // shade_down
1341     },
1342     // scrollBarTheme
1343     {
1344         {{{ 0.196,0.196,0.196,1 }}}, // color_outline
1345         {{{ 0.502,0.502,0.502,1 }}}, // color_item
1346         {{{ 0.314, 0.314, 0.314,0.706 }}}, // color_inner
1347         {{{ 0.392, 0.392, 0.392,0.706 }}}, // color_inner_selected
1348         BND_COLOR_TEXT, // color_text
1349         BND_COLOR_TEXT_SELECTED, // color_text_selected
1350         5, // shade_top
1351         -5, // shade_down
1352     },
1353     // tooltipTheme
1354     {
1355         {{{ 0,0,0,1 }}}, // color_outline
1356         {{{ 0.392,0.392,0.392,1 }}}, // color_item
1357         {{{ 0.098, 0.098, 0.098, 0.902 }}}, // color_inner
1358         {{{ 0.176, 0.176, 0.176, 0.902 }}}, // color_inner_selected
1359         {{{ 0.627, 0.627, 0.627, 1 }}}, // color_text
1360         BND_COLOR_TEXT_SELECTED, // color_text_selected
1361         0, // shade_top
1362         0, // shade_down
1363     },
1364     // menuTheme
1365     {
1366         {{{ 0,0,0,1 }}}, // color_outline
1367         {{{ 0.392,0.392,0.392,1 }}}, // color_item
1368         {{{ 0.098, 0.098, 0.098, 0.902 }}}, // color_inner
1369         {{{ 0.176, 0.176, 0.176, 0.902 }}}, // color_inner_selected
1370         {{{ 0.627, 0.627, 0.627, 1 }}}, // color_text
1371         BND_COLOR_TEXT_SELECTED, // color_text_selected
1372         0, // shade_top
1373         0, // shade_down
1374     },
1375     // menuItemTheme
1376     {
1377         {{{ 0,0,0,1 }}}, // color_outline
1378         {{{ 0.675,0.675,0.675,0.502 }}}, // color_item
1379         {{{ 0,0,0,0 }}}, // color_inner
1380         {{{ 0.337,0.502,0.761,1 }}}, // color_inner_selected
1381         BND_COLOR_TEXT_SELECTED, // color_text
1382         BND_COLOR_TEXT, // color_text_selected
1383         38, // shade_top
1384         0, // shade_down
1385     },
1386     // nodeTheme
1387     {
1388         {{{ 0.945,0.345,0,1 }}}, // nodeSelectedColor
1389         {{{ 0,0,0,1 }}}, // wiresColor
1390         {{{ 0.498,0.439,0.439,1 }}}, // textSelectedColor
1391         {{{ 1,0.667,0.251,1 }}}, // activeNodeColor
1392         {{{ 1,1,1,1 }}}, // wireSelectColor
1393         {{{ 0.608,0.608,0.608,0.627 }}}, // nodeBackdropColor
1394         5, // noodleCurving
1395     },
1396 };
1397 
1398 ////////////////////////////////////////////////////////////////////////////////
1399 
bndSetTheme(BNDtheme theme)1400 void bndSetTheme(BNDtheme theme) {
1401     bnd_theme = theme;
1402 }
1403 
bndGetTheme()1404 const BNDtheme *bndGetTheme() {
1405     return &bnd_theme;
1406 }
1407 
1408 // the handle to the image containing the icon sheet
1409 static int bnd_icon_image = -1;
1410 
bndSetIconImage(int image)1411 void bndSetIconImage(int image) {
1412     bnd_icon_image = image;
1413 }
1414 
1415 // the handle to the UI font
1416 static int bnd_font = -1;
1417 
bndSetFont(int font)1418 void bndSetFont(int font) {
1419     bnd_font = font;
1420 }
1421 
1422 ////////////////////////////////////////////////////////////////////////////////
1423 
bndLabel(NVGcontext * ctx,float x,float y,float w,float h,int iconid,const char * label)1424 void bndLabel(NVGcontext *ctx,
1425     float x, float y, float w, float h, int iconid, const char *label) {
1426     bndIconLabelValue(ctx,x,y,w,h,iconid,
1427         bnd_theme.regularTheme.textColor, BND_LEFT,
1428         BND_LABEL_FONT_SIZE, label, NULL);
1429 }
1430 
bndToolButton(NVGcontext * ctx,float x,float y,float w,float h,int flags,BNDwidgetState state,int iconid,const char * label)1431 void bndToolButton(NVGcontext *ctx,
1432     float x, float y, float w, float h, int flags, BNDwidgetState state,
1433     int iconid, const char *label) {
1434     float cr[4];
1435     NVGcolor shade_top, shade_down;
1436 
1437     bndSelectCorners(cr, BND_TOOL_RADIUS, flags);
1438     bndBevelInset(ctx,x,y,w,h,cr[2],cr[3]);
1439     bndInnerColors(&shade_top, &shade_down, &bnd_theme.toolTheme, state, 1);
1440     bndInnerBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3], shade_top, shade_down);
1441     bndOutlineBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3],
1442         bndTransparent(bnd_theme.toolTheme.outlineColor));
1443     bndIconLabelValue(ctx,x,y,w,h,iconid,
1444         bndTextColor(&bnd_theme.toolTheme, state), BND_CENTER,
1445         BND_LABEL_FONT_SIZE, label, NULL);
1446 }
1447 
bndRadioButton(NVGcontext * ctx,float x,float y,float w,float h,int flags,BNDwidgetState state,int iconid,const char * label)1448 void bndRadioButton(NVGcontext *ctx,
1449     float x, float y, float w, float h, int flags, BNDwidgetState state,
1450     int iconid, const char *label) {
1451     float cr[4];
1452     NVGcolor shade_top, shade_down;
1453 
1454     bndSelectCorners(cr, BND_OPTION_RADIUS, flags);
1455     bndBevelInset(ctx,x,y,w,h,cr[2],cr[3]);
1456     bndInnerColors(&shade_top, &shade_down, &bnd_theme.radioTheme, state, 1);
1457     bndInnerBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3], shade_top, shade_down);
1458     bndOutlineBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3],
1459         bndTransparent(bnd_theme.radioTheme.outlineColor));
1460     bndIconLabelValue(ctx,x,y,w,h,iconid,
1461         bndTextColor(&bnd_theme.radioTheme, state), BND_CENTER,
1462         BND_LABEL_FONT_SIZE, label, NULL);
1463 }
1464 
bndTextFieldTextPosition(NVGcontext * ctx,float x,float y,float w,float h,int iconid,const char * text,int px,int py)1465 int bndTextFieldTextPosition(NVGcontext *ctx, float x, float y, float w, float h,
1466     int iconid, const char *text, int px, int py) {
1467     return bndIconLabelTextPosition(ctx, x, y, w, h,
1468         iconid, BND_LABEL_FONT_SIZE, text, px, py);
1469 }
1470 
bndTextField(NVGcontext * ctx,float x,float y,float w,float h,int flags,BNDwidgetState state,int iconid,const char * text,int cbegin,int cend)1471 void bndTextField(NVGcontext *ctx,
1472     float x, float y, float w, float h, int flags, BNDwidgetState state,
1473     int iconid, const char *text, int cbegin, int cend) {
1474     float cr[4];
1475     NVGcolor shade_top, shade_down;
1476 
1477     bndSelectCorners(cr, BND_TEXT_RADIUS, flags);
1478     bndBevelInset(ctx,x,y,w,h,cr[2],cr[3]);
1479     bndInnerColors(&shade_top, &shade_down, &bnd_theme.textFieldTheme, state, 0);
1480     bndInnerBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3], shade_top, shade_down);
1481     bndOutlineBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3],
1482         bndTransparent(bnd_theme.textFieldTheme.outlineColor));
1483     if (state != BND_ACTIVE) {
1484         cend = -1;
1485     }
1486     bndIconLabelCaret(ctx,x,y,w,h,iconid,
1487         bndTextColor(&bnd_theme.textFieldTheme, state), BND_LABEL_FONT_SIZE,
1488         text, bnd_theme.textFieldTheme.itemColor, cbegin, cend);
1489 }
1490 
bndOptionButton(NVGcontext * ctx,float x,float y,float w,float h,BNDwidgetState state,const char * label)1491 void bndOptionButton(NVGcontext *ctx,
1492     float x, float y, float w, float h, BNDwidgetState state,
1493     const char *label) {
1494     float ox, oy;
1495     NVGcolor shade_top, shade_down;
1496 
1497     ox = x;
1498     oy = y+h-BND_OPTION_HEIGHT-3;
1499 
1500     bndBevelInset(ctx,ox,oy,
1501         BND_OPTION_WIDTH,BND_OPTION_HEIGHT,
1502         BND_OPTION_RADIUS,BND_OPTION_RADIUS);
1503     bndInnerColors(&shade_top, &shade_down, &bnd_theme.optionTheme, state, 1);
1504     bndInnerBox(ctx,ox,oy,
1505         BND_OPTION_WIDTH,BND_OPTION_HEIGHT,
1506         BND_OPTION_RADIUS,BND_OPTION_RADIUS,BND_OPTION_RADIUS,BND_OPTION_RADIUS,
1507         shade_top, shade_down);
1508     bndOutlineBox(ctx,ox,oy,
1509         BND_OPTION_WIDTH,BND_OPTION_HEIGHT,
1510         BND_OPTION_RADIUS,BND_OPTION_RADIUS,BND_OPTION_RADIUS,BND_OPTION_RADIUS,
1511         bndTransparent(bnd_theme.optionTheme.outlineColor));
1512     if (state == BND_ACTIVE) {
1513         bndCheck(ctx,ox,oy, bndTransparent(bnd_theme.optionTheme.itemColor));
1514     }
1515     bndIconLabelValue(ctx,x+12,y,w-12,h,-1,
1516         bndTextColor(&bnd_theme.optionTheme, state), BND_LEFT,
1517         BND_LABEL_FONT_SIZE, label, NULL);
1518 }
1519 
bndChoiceButton(NVGcontext * ctx,float x,float y,float w,float h,int flags,BNDwidgetState state,int iconid,const char * label)1520 void bndChoiceButton(NVGcontext *ctx,
1521     float x, float y, float w, float h, int flags, BNDwidgetState state,
1522     int iconid, const char *label) {
1523     float cr[4];
1524     NVGcolor shade_top, shade_down;
1525 
1526     bndSelectCorners(cr, BND_OPTION_RADIUS, flags);
1527     bndBevelInset(ctx,x,y,w,h,cr[2],cr[3]);
1528     bndInnerColors(&shade_top, &shade_down, &bnd_theme.choiceTheme, state, 1);
1529     bndInnerBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3], shade_top, shade_down);
1530     bndOutlineBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3],
1531         bndTransparent(bnd_theme.choiceTheme.outlineColor));
1532     bndIconLabelValue(ctx,x,y,w,h,iconid,
1533         bndTextColor(&bnd_theme.choiceTheme, state), BND_LEFT,
1534         BND_LABEL_FONT_SIZE, label, NULL);
1535     bndUpDownArrow(ctx,x+w-10,y+10,5,
1536         bndTransparent(bnd_theme.choiceTheme.itemColor));
1537 }
1538 
bndColorButton(NVGcontext * ctx,float x,float y,float w,float h,int flags,NVGcolor color)1539 void bndColorButton(NVGcontext *ctx,
1540     float x, float y, float w, float h, int flags, NVGcolor color) {
1541     float cr[4];
1542     bndSelectCorners(cr, BND_TOOL_RADIUS, flags);
1543     bndBevelInset(ctx,x,y,w,h,cr[2],cr[3]);
1544     bndInnerBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3], color, color);
1545     bndOutlineBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3],
1546         bndTransparent(bnd_theme.toolTheme.outlineColor));
1547 }
1548 
bndNumberField(NVGcontext * ctx,float x,float y,float w,float h,int flags,BNDwidgetState state,const char * label,const char * value)1549 void bndNumberField(NVGcontext *ctx,
1550     float x, float y, float w, float h, int flags, BNDwidgetState state,
1551     const char *label, const char *value) {
1552     float cr[4];
1553     NVGcolor shade_top, shade_down;
1554 
1555     bndSelectCorners(cr, BND_NUMBER_RADIUS, flags);
1556     bndBevelInset(ctx,x,y,w,h,cr[2],cr[3]);
1557     bndInnerColors(&shade_top, &shade_down, &bnd_theme.numberFieldTheme, state, 0);
1558     bndInnerBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3], shade_top, shade_down);
1559     bndOutlineBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3],
1560         bndTransparent(bnd_theme.numberFieldTheme.outlineColor));
1561     bndIconLabelValue(ctx,x,y,w,h,-1,
1562         bndTextColor(&bnd_theme.numberFieldTheme, state), BND_CENTER,
1563         BND_LABEL_FONT_SIZE, label, value);
1564     bndArrow(ctx,x+8,y+10,-BND_NUMBER_ARROW_SIZE,
1565         bndTransparent(bnd_theme.numberFieldTheme.itemColor));
1566     bndArrow(ctx,x+w-8,y+10,BND_NUMBER_ARROW_SIZE,
1567         bndTransparent(bnd_theme.numberFieldTheme.itemColor));
1568 }
1569 
bndSlider(NVGcontext * ctx,float x,float y,float w,float h,int flags,BNDwidgetState state,float progress,const char * label,const char * value)1570 void bndSlider(NVGcontext *ctx,
1571     float x, float y, float w, float h, int flags, BNDwidgetState state,
1572     float progress, const char *label, const char *value) {
1573     float cr[4];
1574     NVGcolor shade_top, shade_down;
1575 
1576     bndSelectCorners(cr, BND_NUMBER_RADIUS, flags);
1577     bndBevelInset(ctx,x,y,w,h,cr[2],cr[3]);
1578     bndInnerColors(&shade_top, &shade_down, &bnd_theme.sliderTheme, state, 0);
1579     bndInnerBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3], shade_top, shade_down);
1580 
1581     if (state == BND_ACTIVE) {
1582         shade_top = bndOffsetColor(
1583             bnd_theme.sliderTheme.itemColor, bnd_theme.sliderTheme.shadeTop);
1584         shade_down = bndOffsetColor(
1585             bnd_theme.sliderTheme.itemColor, bnd_theme.sliderTheme.shadeDown);
1586     } else {
1587         shade_top = bndOffsetColor(
1588             bnd_theme.sliderTheme.itemColor, bnd_theme.sliderTheme.shadeDown);
1589         shade_down = bndOffsetColor(
1590             bnd_theme.sliderTheme.itemColor, bnd_theme.sliderTheme.shadeTop);
1591     }
1592     nvgScissor(ctx,x,y,8+(w-8)*bnd_clamp(progress,0,1),h);
1593     bndInnerBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3], shade_top, shade_down);
1594     nvgResetScissor(ctx);
1595 
1596     bndOutlineBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3],
1597         bndTransparent(bnd_theme.sliderTheme.outlineColor));
1598     bndIconLabelValue(ctx,x,y,w,h,-1,
1599         bndTextColor(&bnd_theme.sliderTheme, state), BND_CENTER,
1600         BND_LABEL_FONT_SIZE, label, value);
1601 }
1602 
bndScrollBar(NVGcontext * ctx,float x,float y,float w,float h,BNDwidgetState state,float offset,float size)1603 void bndScrollBar(NVGcontext *ctx,
1604     float x, float y, float w, float h, BNDwidgetState state,
1605     float offset, float size) {
1606 
1607     bndBevelInset(ctx,x,y,w,h,
1608         BND_SCROLLBAR_RADIUS, BND_SCROLLBAR_RADIUS);
1609     bndInnerBox(ctx,x,y,w,h,
1610         BND_SCROLLBAR_RADIUS,BND_SCROLLBAR_RADIUS,
1611         BND_SCROLLBAR_RADIUS,BND_SCROLLBAR_RADIUS,
1612         bndOffsetColor(
1613             bnd_theme.scrollBarTheme.innerColor, 3*bnd_theme.scrollBarTheme.shadeDown),
1614         bndOffsetColor(
1615             bnd_theme.scrollBarTheme.innerColor, 3*bnd_theme.scrollBarTheme.shadeTop));
1616     bndOutlineBox(ctx,x,y,w,h,
1617         BND_SCROLLBAR_RADIUS,BND_SCROLLBAR_RADIUS,
1618         BND_SCROLLBAR_RADIUS,BND_SCROLLBAR_RADIUS,
1619         bndTransparent(bnd_theme.scrollBarTheme.outlineColor));
1620 
1621     NVGcolor itemColor = bndOffsetColor(
1622         bnd_theme.scrollBarTheme.itemColor,
1623         (state == BND_ACTIVE)?BND_SCROLLBAR_ACTIVE_SHADE:0);
1624 
1625     bndScrollHandleRect(&x,&y,&w,&h,offset,size);
1626 
1627     bndInnerBox(ctx,x,y,w,h,
1628         BND_SCROLLBAR_RADIUS,BND_SCROLLBAR_RADIUS,
1629         BND_SCROLLBAR_RADIUS,BND_SCROLLBAR_RADIUS,
1630         bndOffsetColor(
1631             itemColor, 3*bnd_theme.scrollBarTheme.shadeTop),
1632         bndOffsetColor(
1633             itemColor, 3*bnd_theme.scrollBarTheme.shadeDown));
1634     bndOutlineBox(ctx,x,y,w,h,
1635         BND_SCROLLBAR_RADIUS,BND_SCROLLBAR_RADIUS,
1636         BND_SCROLLBAR_RADIUS,BND_SCROLLBAR_RADIUS,
1637         bndTransparent(bnd_theme.scrollBarTheme.outlineColor));
1638 }
1639 
bndMenuBackground(NVGcontext * ctx,float x,float y,float w,float h,int flags)1640 void bndMenuBackground(NVGcontext *ctx,
1641     float x, float y, float w, float h, int flags) {
1642     float cr[4];
1643     NVGcolor shade_top, shade_down;
1644 
1645     bndSelectCorners(cr, BND_MENU_RADIUS, flags);
1646     bndInnerColors(&shade_top, &shade_down, &bnd_theme.menuTheme,
1647         BND_DEFAULT, 0);
1648     bndInnerBox(ctx,x,y,w,h+1,cr[0],cr[1],cr[2],cr[3], shade_top, shade_down);
1649     bndOutlineBox(ctx,x,y,w,h+1,cr[0],cr[1],cr[2],cr[3],
1650         bndTransparent(bnd_theme.menuTheme.outlineColor));
1651     bndDropShadow(ctx,x,y,w,h,BND_MENU_RADIUS,
1652         BND_SHADOW_FEATHER,BND_SHADOW_ALPHA);
1653 }
1654 
bndTooltipBackground(NVGcontext * ctx,float x,float y,float w,float h)1655 void bndTooltipBackground(NVGcontext *ctx, float x, float y, float w, float h) {
1656     NVGcolor shade_top, shade_down;
1657 
1658     bndInnerColors(&shade_top, &shade_down, &bnd_theme.tooltipTheme,
1659         BND_DEFAULT, 0);
1660     bndInnerBox(ctx,x,y,w,h+1,
1661         BND_MENU_RADIUS,BND_MENU_RADIUS,BND_MENU_RADIUS,BND_MENU_RADIUS,
1662         shade_top, shade_down);
1663     bndOutlineBox(ctx,x,y,w,h+1,
1664         BND_MENU_RADIUS,BND_MENU_RADIUS,BND_MENU_RADIUS,BND_MENU_RADIUS,
1665         bndTransparent(bnd_theme.tooltipTheme.outlineColor));
1666     bndDropShadow(ctx,x,y,w,h,BND_MENU_RADIUS,
1667         BND_SHADOW_FEATHER,BND_SHADOW_ALPHA);
1668 }
1669 
bndMenuLabel(NVGcontext * ctx,float x,float y,float w,float h,int iconid,const char * label)1670 void bndMenuLabel(NVGcontext *ctx,
1671     float x, float y, float w, float h, int iconid, const char *label) {
1672     bndIconLabelValue(ctx,x,y,w,h,iconid,
1673         bnd_theme.menuTheme.textColor, BND_LEFT,
1674         BND_LABEL_FONT_SIZE, label, NULL);
1675 }
1676 
bndMenuItem(NVGcontext * ctx,float x,float y,float w,float h,BNDwidgetState state,int iconid,const char * label)1677 void bndMenuItem(NVGcontext *ctx,
1678     float x, float y, float w, float h, BNDwidgetState state,
1679     int iconid, const char *label) {
1680     if (state != BND_DEFAULT) {
1681         bndInnerBox(ctx,x,y,w,h,0,0,0,0,
1682             bndOffsetColor(bnd_theme.menuItemTheme.innerSelectedColor,
1683                 bnd_theme.menuItemTheme.shadeTop),
1684             bndOffsetColor(bnd_theme.menuItemTheme.innerSelectedColor,
1685                 bnd_theme.menuItemTheme.shadeDown));
1686         state = BND_ACTIVE;
1687     }
1688     bndIconLabelValue(ctx,x,y,w,h,iconid,
1689         bndTextColor(&bnd_theme.menuItemTheme, state), BND_LEFT,
1690         BND_LABEL_FONT_SIZE, label, NULL);
1691 }
1692 
bndNodePort(NVGcontext * ctx,float x,float y,BNDwidgetState state,NVGcolor color)1693 void bndNodePort(NVGcontext *ctx, float x, float y, BNDwidgetState state,
1694     NVGcolor color) {
1695     nvgBeginPath(ctx);
1696     nvgCircle(ctx, x, y, BND_NODE_PORT_RADIUS);
1697     nvgStrokeColor(ctx,bnd_theme.nodeTheme.wiresColor);
1698     nvgStrokeWidth(ctx,1.0f);
1699     nvgStroke(ctx);
1700     nvgFillColor(ctx,(state != BND_DEFAULT)?
1701         bndOffsetColor(color, BND_HOVER_SHADE):color);
1702     nvgFill(ctx);
1703 }
1704 
bndColoredNodeWire(NVGcontext * ctx,float x0,float y0,float x1,float y1,NVGcolor color0,NVGcolor color1)1705 void bndColoredNodeWire(NVGcontext *ctx, float x0, float y0, float x1, float y1,
1706     NVGcolor color0, NVGcolor color1) {
1707     float length = bnd_fmaxf(fabsf(x1 - x0),fabsf(y1 - y0));
1708     float delta = length*(float)bnd_theme.nodeTheme.noodleCurving/10.0f;
1709 
1710     nvgBeginPath(ctx);
1711     nvgMoveTo(ctx, x0, y0);
1712     nvgBezierTo(ctx,
1713         x0 + delta, y0,
1714         x1 - delta, y1,
1715         x1, y1);
1716     NVGcolor colorw = bnd_theme.nodeTheme.wiresColor;
1717     colorw.a = (color0.a<color1.a)?color0.a:color1.a;
1718     nvgStrokeColor(ctx, colorw);
1719     nvgStrokeWidth(ctx, BND_NODE_WIRE_OUTLINE_WIDTH);
1720     nvgStroke(ctx);
1721     nvgStrokePaint(ctx, nvgLinearGradient(ctx,
1722         x0, y0, x1, y1,
1723         color0,
1724         color1));
1725     nvgStrokeWidth(ctx,BND_NODE_WIRE_WIDTH);
1726     nvgStroke(ctx);
1727 }
1728 
bndNodeWire(NVGcontext * ctx,float x0,float y0,float x1,float y1,BNDwidgetState state0,BNDwidgetState state1)1729 void bndNodeWire(NVGcontext *ctx, float x0, float y0, float x1, float y1,
1730     BNDwidgetState state0, BNDwidgetState state1) {
1731     bndColoredNodeWire(ctx, x0, y0, x1, y1,
1732         bndNodeWireColor(&bnd_theme.nodeTheme, state0),
1733         bndNodeWireColor(&bnd_theme.nodeTheme, state1));
1734 }
1735 
bndNodeBackground(NVGcontext * ctx,float x,float y,float w,float h,BNDwidgetState state,int iconid,const char * label,NVGcolor titleColor)1736 void bndNodeBackground(NVGcontext *ctx, float x, float y, float w, float h,
1737     BNDwidgetState state, int iconid, const char *label, NVGcolor titleColor) {
1738     bndInnerBox(ctx,x,y,w,BND_NODE_TITLE_HEIGHT+2,
1739         BND_NODE_RADIUS,BND_NODE_RADIUS,0,0,
1740         bndTransparent(bndOffsetColor(titleColor, BND_BEVEL_SHADE)),
1741         bndTransparent(titleColor));
1742     bndInnerBox(ctx,x,y+BND_NODE_TITLE_HEIGHT-1,w,h+2-BND_NODE_TITLE_HEIGHT,
1743         0,0,BND_NODE_RADIUS,BND_NODE_RADIUS,
1744         bndTransparent(bnd_theme.nodeTheme.nodeBackdropColor),
1745         bndTransparent(bnd_theme.nodeTheme.nodeBackdropColor));
1746     bndNodeIconLabel(ctx,
1747         x+BND_NODE_ARROW_AREA_WIDTH,y,
1748         w-BND_NODE_ARROW_AREA_WIDTH-BND_NODE_MARGIN_SIDE,BND_NODE_TITLE_HEIGHT,
1749         iconid, bnd_theme.regularTheme.textColor,
1750         bndOffsetColor(titleColor, BND_BEVEL_SHADE),
1751         BND_LEFT, BND_LABEL_FONT_SIZE, label);
1752     NVGcolor arrowColor;
1753     NVGcolor borderColor;
1754     switch(state) {
1755     default:
1756     case BND_DEFAULT: {
1757         borderColor = nvgRGBf(0,0,0);
1758         arrowColor = bndOffsetColor(titleColor, -BND_BEVEL_SHADE);
1759     } break;
1760     case BND_HOVER: {
1761         borderColor = bnd_theme.nodeTheme.nodeSelectedColor;
1762         arrowColor = bnd_theme.nodeTheme.nodeSelectedColor;
1763     } break;
1764     case BND_ACTIVE: {
1765         borderColor = bnd_theme.nodeTheme.activeNodeColor;
1766         arrowColor = bnd_theme.nodeTheme.nodeSelectedColor;
1767     } break;
1768     }
1769     bndOutlineBox(ctx,x,y,w,h+1,
1770         BND_NODE_RADIUS,BND_NODE_RADIUS,BND_NODE_RADIUS,BND_NODE_RADIUS,
1771         bndTransparent(borderColor));
1772     /*
1773     bndNodeArrowDown(ctx,
1774         x + BND_NODE_MARGIN_SIDE, y + BND_NODE_TITLE_HEIGHT-4,
1775         BND_NODE_ARROW_SIZE, arrowColor);
1776     */
1777     bndDropShadow(ctx,x,y,w,h,BND_NODE_RADIUS,
1778         BND_SHADOW_FEATHER,BND_SHADOW_ALPHA);
1779 }
1780 
bndSplitterWidgets(NVGcontext * ctx,float x,float y,float w,float h)1781 void bndSplitterWidgets(NVGcontext *ctx, float x, float y, float w, float h) {
1782     NVGcolor insetLight = bndTransparent(
1783         bndOffsetColor(bnd_theme.backgroundColor, BND_SPLITTER_SHADE));
1784     NVGcolor insetDark = bndTransparent(
1785         bndOffsetColor(bnd_theme.backgroundColor, -BND_SPLITTER_SHADE));
1786     NVGcolor inset = bndTransparent(bnd_theme.backgroundColor);
1787 
1788     float x2 = x+w;
1789     float y2 = y+h;
1790 
1791     nvgBeginPath(ctx);
1792     nvgMoveTo(ctx, x, y2-13);
1793     nvgLineTo(ctx, x+13, y2);
1794     nvgMoveTo(ctx, x, y2-9);
1795     nvgLineTo(ctx, x+9, y2);
1796     nvgMoveTo(ctx, x, y2-5);
1797     nvgLineTo(ctx, x+5, y2);
1798 
1799     nvgMoveTo(ctx, x2-11, y);
1800     nvgLineTo(ctx, x2, y+11);
1801     nvgMoveTo(ctx, x2-7, y);
1802     nvgLineTo(ctx, x2, y+7);
1803     nvgMoveTo(ctx, x2-3, y);
1804     nvgLineTo(ctx, x2, y+3);
1805 
1806     nvgStrokeColor(ctx, insetDark);
1807     nvgStroke(ctx);
1808 
1809     nvgBeginPath(ctx);
1810     nvgMoveTo(ctx, x, y2-11);
1811     nvgLineTo(ctx, x+11, y2);
1812     nvgMoveTo(ctx, x, y2-7);
1813     nvgLineTo(ctx, x+7, y2);
1814     nvgMoveTo(ctx, x, y2-3);
1815     nvgLineTo(ctx, x+3, y2);
1816 
1817     nvgMoveTo(ctx, x2-13, y);
1818     nvgLineTo(ctx, x2, y+13);
1819     nvgMoveTo(ctx, x2-9, y);
1820     nvgLineTo(ctx, x2, y+9);
1821     nvgMoveTo(ctx, x2-5, y);
1822     nvgLineTo(ctx, x2, y+5);
1823 
1824     nvgStrokeColor(ctx, insetLight);
1825     nvgStroke(ctx);
1826 
1827     nvgBeginPath(ctx);
1828     nvgMoveTo(ctx, x, y2-12);
1829     nvgLineTo(ctx, x+12, y2);
1830     nvgMoveTo(ctx, x, y2-8);
1831     nvgLineTo(ctx, x+8, y2);
1832     nvgMoveTo(ctx, x, y2-4);
1833     nvgLineTo(ctx, x+4, y2);
1834 
1835     nvgMoveTo(ctx, x2-12, y);
1836     nvgLineTo(ctx, x2, y+12);
1837     nvgMoveTo(ctx, x2-8, y);
1838     nvgLineTo(ctx, x2, y+8);
1839     nvgMoveTo(ctx, x2-4, y);
1840     nvgLineTo(ctx, x2, y+4);
1841 
1842     nvgStrokeColor(ctx, inset);
1843     nvgStroke(ctx);
1844 }
1845 
bndJoinAreaOverlay(NVGcontext * ctx,float x,float y,float w,float h,int vertical,int mirror)1846 void bndJoinAreaOverlay(NVGcontext *ctx, float x, float y, float w, float h,
1847     int vertical, int mirror) {
1848 
1849     if (vertical) {
1850         float u = w;
1851         w = h; h = u;
1852     }
1853 
1854     float s = (w<h)?w:h;
1855 
1856     float x0,y0,x1,y1;
1857     if (mirror) {
1858         x0 = w;
1859         y0 = h;
1860         x1 = 0;
1861         y1 = 0;
1862         s = -s;
1863     } else {
1864         x0 = 0;
1865         y0 = 0;
1866         x1 = w;
1867         y1 = h;
1868     }
1869 
1870     float yc = (y0+y1)*0.5f;
1871     float s2 = s/2.0f;
1872     float s4 = s/4.0f;
1873     float s8 = s/8.0f;
1874     float x4 = x0+s4;
1875 
1876     float points[][2] = {
1877         { x0,y0 },
1878         { x1,y0 },
1879         { x1,y1 },
1880         { x0,y1 },
1881         { x0,yc+s8 },
1882         { x4,yc+s8 },
1883         { x4,yc+s4 },
1884         { x0+s2,yc },
1885         { x4,yc-s4 },
1886         { x4,yc-s8 },
1887         { x0,yc-s8 }
1888     };
1889 
1890     nvgBeginPath(ctx);
1891     int count = sizeof(points) / (sizeof(float)*2);
1892     nvgMoveTo(ctx,x+points[0][vertical&1],y+points[0][(vertical&1)^1]);
1893     for (int i = 1; i < count; ++i) {
1894         nvgLineTo(ctx,x+points[i][vertical&1],y+points[i][(vertical&1)^1]);
1895     }
1896 
1897     nvgFillColor(ctx, nvgRGBAf(0,0,0,0.3));
1898     nvgFill(ctx);
1899 }
1900 
1901 ////////////////////////////////////////////////////////////////////////////////
1902 
bndLabelWidth(NVGcontext * ctx,int iconid,const char * label)1903 float bndLabelWidth(NVGcontext *ctx, int iconid, const char *label) {
1904     int w = BND_PAD_LEFT + BND_PAD_RIGHT;
1905     if (iconid >= 0) {
1906         w += BND_ICON_SHEET_RES;
1907     }
1908     if (label && (bnd_font >= 0)) {
1909         nvgFontFaceId(ctx, bnd_font);
1910         nvgFontSize(ctx, BND_LABEL_FONT_SIZE);
1911         w += nvgTextBounds(ctx, 1, 1, label, NULL, NULL);
1912     }
1913     return w;
1914 }
1915 
bndLabelHeight(NVGcontext * ctx,int iconid,const char * label,float width)1916 float bndLabelHeight(NVGcontext *ctx, int iconid, const char *label, float width) {
1917 	int h = BND_WIDGET_HEIGHT;
1918     width -= BND_TEXT_RADIUS*2;
1919     if (iconid >= 0) {
1920         width -= BND_ICON_SHEET_RES;
1921     }
1922     if (label && (bnd_font >= 0)) {
1923         nvgFontFaceId(ctx, bnd_font);
1924         nvgFontSize(ctx, BND_LABEL_FONT_SIZE);
1925         float bounds[4];
1926         nvgTextBoxBounds(ctx, 1, 1, width, label, NULL, bounds);
1927         int bh = int(bounds[3] - bounds[1]) + BND_TEXT_PAD_DOWN;
1928         if (bh > h)
1929         	h = bh;
1930     }
1931     return h;
1932 }
1933 
1934 ////////////////////////////////////////////////////////////////////////////////
1935 
bndRoundedBox(NVGcontext * ctx,float x,float y,float w,float h,float cr0,float cr1,float cr2,float cr3)1936 void bndRoundedBox(NVGcontext *ctx, float x, float y, float w, float h,
1937     float cr0, float cr1, float cr2, float cr3) {
1938     float d;
1939 
1940     w = bnd_fmaxf(0, w);
1941     h = bnd_fmaxf(0, h);
1942     d = bnd_fminf(w, h);
1943 
1944     nvgMoveTo(ctx, x,y+h*0.5f);
1945     nvgArcTo(ctx, x,y, x+w,y, bnd_fminf(cr0, d/2));
1946     nvgArcTo(ctx, x+w,y, x+w,y+h, bnd_fminf(cr1, d/2));
1947     nvgArcTo(ctx, x+w,y+h, x,y+h, bnd_fminf(cr2, d/2));
1948     nvgArcTo(ctx, x,y+h, x,y, bnd_fminf(cr3, d/2));
1949     nvgClosePath(ctx);
1950 }
1951 
bndTransparent(NVGcolor color)1952 NVGcolor bndTransparent(NVGcolor color) {
1953     color.a *= BND_TRANSPARENT_ALPHA;
1954     return color;
1955 }
1956 
bndOffsetColor(NVGcolor color,int delta)1957 NVGcolor bndOffsetColor(NVGcolor color, int delta) {
1958     float offset = (float)delta / 255.0f;
1959     return delta?(
1960         nvgRGBAf(
1961             bnd_clamp(color.r+offset,0,1),
1962             bnd_clamp(color.g+offset,0,1),
1963             bnd_clamp(color.b+offset,0,1),
1964             color.a)
1965     ):color;
1966 }
1967 
bndBevel(NVGcontext * ctx,float x,float y,float w,float h)1968 void bndBevel(NVGcontext *ctx, float x, float y, float w, float h) {
1969     nvgStrokeWidth(ctx, 1);
1970 
1971     x += 0.5f;
1972     y += 0.5f;
1973     w -= 1;
1974     h -= 1;
1975 
1976     nvgBeginPath(ctx);
1977     nvgMoveTo(ctx, x, y+h);
1978     nvgLineTo(ctx, x+w, y+h);
1979     nvgLineTo(ctx, x+w, y);
1980     nvgStrokeColor(ctx, bndTransparent(
1981         bndOffsetColor(bnd_theme.backgroundColor, -BND_BEVEL_SHADE)));
1982     nvgStroke(ctx);
1983 
1984     nvgBeginPath(ctx);
1985     nvgMoveTo(ctx, x, y+h);
1986     nvgLineTo(ctx, x, y);
1987     nvgLineTo(ctx, x+w, y);
1988     nvgStrokeColor(ctx, bndTransparent(
1989         bndOffsetColor(bnd_theme.backgroundColor, BND_BEVEL_SHADE)));
1990     nvgStroke(ctx);
1991 }
1992 
bndBevelInset(NVGcontext * ctx,float x,float y,float w,float h,float cr2,float cr3)1993 void bndBevelInset(NVGcontext *ctx, float x, float y, float w, float h,
1994     float cr2, float cr3) {
1995     float d;
1996 
1997     y -= 0.5f;
1998     d = bnd_fminf(w, h);
1999     cr2 = bnd_fminf(cr2, d/2);
2000     cr3 = bnd_fminf(cr3, d/2);
2001 
2002     nvgBeginPath(ctx);
2003     nvgMoveTo(ctx, x+w,y+h-cr2);
2004     nvgArcTo(ctx, x+w,y+h, x,y+h, cr2);
2005     nvgArcTo(ctx, x,y+h, x,y, cr3);
2006 
2007     NVGcolor bevelColor = bndOffsetColor(bnd_theme.backgroundColor,
2008         BND_INSET_BEVEL_SHADE);
2009 
2010     nvgStrokeWidth(ctx, 1);
2011     nvgStrokePaint(ctx,
2012         nvgLinearGradient(ctx,
2013             x,y+h-bnd_fmaxf(cr2,cr3)-1,
2014             x,y+h-1,
2015         nvgRGBAf(bevelColor.r, bevelColor.g, bevelColor.b, 0),
2016         bevelColor));
2017     nvgStroke(ctx);
2018 }
2019 
bndBackground(NVGcontext * ctx,float x,float y,float w,float h)2020 void bndBackground(NVGcontext *ctx, float x, float y, float w, float h) {
2021     nvgBeginPath(ctx);
2022     nvgRect(ctx, x, y, w, h);
2023     nvgFillColor(ctx, bnd_theme.backgroundColor);
2024     nvgFill(ctx);
2025 }
2026 
bndIcon(NVGcontext * ctx,float x,float y,int iconid)2027 void bndIcon(NVGcontext *ctx, float x, float y, int iconid) {
2028     int ix, iy, u, v;
2029     if (bnd_icon_image < 0) return; // no icons loaded
2030 
2031     ix = iconid & 0xff;
2032     iy = (iconid>>8) & 0xff;
2033     u = BND_ICON_SHEET_OFFSET_X + ix*BND_ICON_SHEET_GRID;
2034     v = BND_ICON_SHEET_OFFSET_Y + iy*BND_ICON_SHEET_GRID;
2035 
2036     nvgBeginPath(ctx);
2037     nvgRect(ctx,x,y,BND_ICON_SHEET_RES,BND_ICON_SHEET_RES);
2038     nvgFillPaint(ctx,
2039         nvgImagePattern(ctx,x-u,y-v,
2040         BND_ICON_SHEET_WIDTH,
2041         BND_ICON_SHEET_HEIGHT,
2042         0,bnd_icon_image,1));
2043     nvgFill(ctx);
2044 }
2045 
bndDropShadow(NVGcontext * ctx,float x,float y,float w,float h,float r,float feather,float alpha)2046 void bndDropShadow(NVGcontext *ctx, float x, float y, float w, float h,
2047     float r, float feather, float alpha) {
2048 
2049     nvgBeginPath(ctx);
2050     y += feather;
2051     h -= feather;
2052 
2053     nvgMoveTo(ctx, x-feather, y-feather);
2054     nvgLineTo(ctx, x, y-feather);
2055     nvgLineTo(ctx, x, y+h-feather);
2056     nvgArcTo(ctx, x,y+h,x+r,y+h,r);
2057     nvgArcTo(ctx, x+w,y+h,x+w,y+h-r,r);
2058     nvgLineTo(ctx, x+w, y-feather);
2059     nvgLineTo(ctx, x+w+feather, y-feather);
2060     nvgLineTo(ctx, x+w+feather, y+h+feather);
2061     nvgLineTo(ctx, x-feather, y+h+feather);
2062     nvgClosePath(ctx);
2063 
2064     nvgFillPaint(ctx, nvgBoxGradient(ctx,
2065         x - feather*0.5f,y - feather*0.5f,
2066         w + feather,h+feather,
2067         r+feather*0.5f,
2068         feather,
2069         nvgRGBAf(0,0,0,alpha*alpha),
2070         nvgRGBAf(0,0,0,0)));
2071     nvgFill(ctx);
2072 }
2073 
bndInnerBox(NVGcontext * ctx,float x,float y,float w,float h,float cr0,float cr1,float cr2,float cr3,NVGcolor shade_top,NVGcolor shade_down)2074 void bndInnerBox(NVGcontext *ctx, float x, float y, float w, float h,
2075     float cr0, float cr1, float cr2, float cr3,
2076     NVGcolor shade_top, NVGcolor shade_down) {
2077     nvgBeginPath(ctx);
2078     bndRoundedBox(ctx,x+1,y+1,w-2,h-3,bnd_fmaxf(0,cr0-1),
2079         bnd_fmaxf(0,cr1-1),bnd_fmaxf(0,cr2-1),bnd_fmaxf(0,cr3-1));
2080     nvgFillPaint(ctx,((h-2)>w)?
2081         nvgLinearGradient(ctx,x,y,x+w,y,shade_top,shade_down):
2082         nvgLinearGradient(ctx,x,y,x,y+h,shade_top,shade_down));
2083     nvgFill(ctx);
2084 }
2085 
bndOutlineBox(NVGcontext * ctx,float x,float y,float w,float h,float cr0,float cr1,float cr2,float cr3,NVGcolor color)2086 void bndOutlineBox(NVGcontext *ctx, float x, float y, float w, float h,
2087     float cr0, float cr1, float cr2, float cr3, NVGcolor color) {
2088     nvgBeginPath(ctx);
2089     bndRoundedBox(ctx,x+0.5f,y+0.5f,w-1,h-2,cr0,cr1,cr2,cr3);
2090     nvgStrokeColor(ctx,color);
2091     nvgStrokeWidth(ctx,1);
2092     nvgStroke(ctx);
2093 }
2094 
bndSelectCorners(float * radiuses,float r,int flags)2095 void bndSelectCorners(float *radiuses, float r, int flags) {
2096     radiuses[0] = (flags & BND_CORNER_TOP_LEFT)?0:r;
2097     radiuses[1] = (flags & BND_CORNER_TOP_RIGHT)?0:r;
2098     radiuses[2] = (flags & BND_CORNER_DOWN_RIGHT)?0:r;
2099     radiuses[3] = (flags & BND_CORNER_DOWN_LEFT)?0:r;
2100 }
2101 
bndInnerColors(NVGcolor * shade_top,NVGcolor * shade_down,const BNDwidgetTheme * theme,BNDwidgetState state,int flipActive)2102 void bndInnerColors(
2103     NVGcolor *shade_top, NVGcolor *shade_down,
2104     const BNDwidgetTheme *theme, BNDwidgetState state, int flipActive) {
2105 
2106     switch(state) {
2107     default:
2108     case BND_DEFAULT: {
2109         *shade_top = bndOffsetColor(theme->innerColor, theme->shadeTop);
2110         *shade_down = bndOffsetColor(theme->innerColor, theme->shadeDown);
2111     } break;
2112     case BND_HOVER: {
2113         NVGcolor color = bndOffsetColor(theme->innerColor, BND_HOVER_SHADE);
2114         *shade_top = bndOffsetColor(color, theme->shadeTop);
2115         *shade_down = bndOffsetColor(color, theme->shadeDown);
2116     } break;
2117     case BND_ACTIVE: {
2118         *shade_top = bndOffsetColor(theme->innerSelectedColor,
2119             flipActive?theme->shadeDown:theme->shadeTop);
2120         *shade_down = bndOffsetColor(theme->innerSelectedColor,
2121             flipActive?theme->shadeTop:theme->shadeDown);
2122     } break;
2123     }
2124 }
2125 
bndTextColor(const BNDwidgetTheme * theme,BNDwidgetState state)2126 NVGcolor bndTextColor(const BNDwidgetTheme *theme, BNDwidgetState state) {
2127     return (state == BND_ACTIVE)?theme->textSelectedColor:theme->textColor;
2128 }
2129 
bndIconLabelValue(NVGcontext * ctx,float x,float y,float w,float h,int iconid,NVGcolor color,int align,float fontsize,const char * label,const char * value)2130 void bndIconLabelValue(NVGcontext *ctx, float x, float y, float w, float h,
2131     int iconid, NVGcolor color, int align, float fontsize, const char *label,
2132     const char *value) {
2133     float pleft = BND_PAD_LEFT;
2134     if (label) {
2135         if (iconid >= 0) {
2136             bndIcon(ctx,x+4,y+2,iconid);
2137             pleft += BND_ICON_SHEET_RES;
2138         }
2139 
2140         if (bnd_font < 0) return;
2141         nvgFontFaceId(ctx, bnd_font);
2142         nvgFontSize(ctx, fontsize);
2143         nvgBeginPath(ctx);
2144         nvgFillColor(ctx, color);
2145         if (value) {
2146             float label_width = nvgTextBounds(ctx, 1, 1, label, NULL, NULL);
2147             float sep_width = nvgTextBounds(ctx, 1, 1,
2148                 BND_LABEL_SEPARATOR, NULL, NULL);
2149 
2150             nvgTextAlign(ctx, NVG_ALIGN_LEFT|NVG_ALIGN_BASELINE);
2151             x += pleft;
2152             if (align == BND_CENTER) {
2153                 float width = label_width + sep_width
2154                     + nvgTextBounds(ctx, 1, 1, value, NULL, NULL);
2155                 x += ((w-BND_PAD_RIGHT-pleft)-width)*0.5f;
2156             }
2157             y += BND_WIDGET_HEIGHT-BND_TEXT_PAD_DOWN;
2158             nvgText(ctx, x, y, label, NULL);
2159             x += label_width;
2160             nvgText(ctx, x, y, BND_LABEL_SEPARATOR, NULL);
2161             x += sep_width;
2162             nvgText(ctx, x, y, value, NULL);
2163         } else {
2164             nvgTextAlign(ctx,
2165                 (align==BND_LEFT)?(NVG_ALIGN_LEFT|NVG_ALIGN_BASELINE):
2166                 (NVG_ALIGN_CENTER|NVG_ALIGN_BASELINE));
2167             nvgTextBox(ctx,x+pleft,y+BND_WIDGET_HEIGHT-BND_TEXT_PAD_DOWN,
2168                 w-BND_PAD_RIGHT-pleft,label, NULL);
2169         }
2170     } else if (iconid >= 0) {
2171         bndIcon(ctx,x+2,y+2,iconid);
2172     }
2173 }
2174 
bndNodeIconLabel(NVGcontext * ctx,float x,float y,float w,float h,int iconid,NVGcolor color,NVGcolor shadowColor,int align,float fontsize,const char * label)2175 void bndNodeIconLabel(NVGcontext *ctx, float x, float y, float w, float h,
2176     int iconid, NVGcolor color, NVGcolor shadowColor,
2177     int align, float fontsize, const char *label) {
2178     if (label && (bnd_font >= 0)) {
2179         nvgFontFaceId(ctx, bnd_font);
2180         nvgFontSize(ctx, fontsize);
2181         nvgBeginPath(ctx);
2182         nvgTextAlign(ctx, NVG_ALIGN_LEFT|NVG_ALIGN_BASELINE);
2183         nvgFillColor(ctx, shadowColor);
2184         nvgFontBlur(ctx, BND_NODE_TITLE_FEATHER);
2185         nvgTextBox(ctx,x+1,y+h+3-BND_TEXT_PAD_DOWN,
2186             w,label, NULL);
2187         nvgFillColor(ctx, color);
2188         nvgFontBlur(ctx, 0);
2189         nvgTextBox(ctx,x,y+h+2-BND_TEXT_PAD_DOWN,
2190             w,label, NULL);
2191     }
2192     if (iconid >= 0) {
2193         bndIcon(ctx,x+w-BND_ICON_SHEET_RES,y+3,iconid);
2194     }
2195 }
2196 
bndIconLabelTextPosition(NVGcontext * ctx,float x,float y,float w,float h,int iconid,float fontsize,const char * label,int px,int py)2197 int bndIconLabelTextPosition(NVGcontext *ctx, float x, float y, float w, float h,
2198     int iconid, float fontsize, const char *label, int px, int py) {
2199     float bounds[4];
2200     float pleft = BND_TEXT_RADIUS;
2201     if (!label) return -1;
2202     if (iconid >= 0)
2203         pleft += BND_ICON_SHEET_RES;
2204 
2205     if (bnd_font < 0) return -1;
2206 
2207     x += pleft;
2208     y += BND_WIDGET_HEIGHT - BND_TEXT_PAD_DOWN;
2209 
2210     nvgFontFaceId(ctx, bnd_font);
2211     nvgFontSize(ctx, fontsize);
2212     nvgTextAlign(ctx, NVG_ALIGN_LEFT | NVG_ALIGN_BASELINE);
2213 
2214     w -= BND_TEXT_RADIUS + pleft;
2215 
2216     float asc, desc, lh;
2217     static NVGtextRow rows[BND_MAX_ROWS];
2218     int nrows = nvgTextBreakLines(
2219         ctx, label, NULL, w, rows, BND_MAX_ROWS);
2220     if (nrows == 0) return 0;
2221     nvgTextBoxBounds(ctx, x, y, w, label, NULL, bounds);
2222     nvgTextMetrics(ctx, &asc, &desc, &lh);
2223 
2224     // calculate vertical position
2225     int row = bnd_clamp((int)((float)(py - bounds[1]) / lh), 0, nrows - 1);
2226     // search horizontal position
2227     static NVGglyphPosition glyphs[BND_MAX_GLYPHS];
2228     int nglyphs = nvgTextGlyphPositions(
2229         ctx, x, y, rows[row].start, rows[row].end + 1, glyphs, BND_MAX_GLYPHS);
2230     int col, p = 0;
2231     for (col = 0; col < nglyphs && glyphs[col].x < px; ++col)
2232         p = (int)(glyphs[col].str - label);
2233     // see if we should move one character further
2234     if (col > 0 && col < nglyphs && glyphs[col].x - px < px - glyphs[col - 1].x)
2235         p = (int)(glyphs[col].str - label);
2236     return p;
2237 }
2238 
bndCaretPosition(NVGcontext * ctx,float x,float y,float desc,float lineHeight,const char * caret,NVGtextRow * rows,int nrows,int * cr,float * cx,float * cy)2239 static void bndCaretPosition(NVGcontext *ctx, float x, float y,
2240     float desc, float lineHeight, const char *caret, NVGtextRow *rows,int nrows,
2241     int *cr, float *cx, float *cy) {
2242     static NVGglyphPosition glyphs[BND_MAX_GLYPHS];
2243     int r,nglyphs;
2244     for (r=0; r < nrows && rows[r].end < caret; ++r);
2245     *cr = r;
2246     *cx = x;
2247     *cy = y-lineHeight-desc + r*lineHeight;
2248     if (nrows == 0) return;
2249     *cx = rows[r].minx;
2250     nglyphs = nvgTextGlyphPositions(
2251         ctx, x, y, rows[r].start, rows[r].end+1, glyphs, BND_MAX_GLYPHS);
2252     for (int i=0; i < nglyphs; ++i) {
2253         *cx=glyphs[i].x;
2254         if (glyphs[i].str == caret) break;
2255     }
2256 }
2257 
bndIconLabelCaret(NVGcontext * ctx,float x,float y,float w,float h,int iconid,NVGcolor color,float fontsize,const char * label,NVGcolor caretcolor,int cbegin,int cend)2258 void bndIconLabelCaret(NVGcontext *ctx, float x, float y, float w, float h,
2259     int iconid, NVGcolor color, float fontsize, const char *label,
2260     NVGcolor caretcolor, int cbegin, int cend) {
2261     float pleft = BND_TEXT_RADIUS;
2262     if (!label) return;
2263     if (iconid >= 0) {
2264         bndIcon(ctx,x+4,y+2,iconid);
2265         pleft += BND_ICON_SHEET_RES;
2266     }
2267 
2268     if (bnd_font < 0) return;
2269 
2270     x+=pleft;
2271     y+=BND_WIDGET_HEIGHT-BND_TEXT_PAD_DOWN;
2272 
2273     nvgFontFaceId(ctx, bnd_font);
2274     nvgFontSize(ctx, fontsize);
2275     nvgTextAlign(ctx, NVG_ALIGN_LEFT|NVG_ALIGN_BASELINE);
2276 
2277     w -= BND_TEXT_RADIUS+pleft;
2278 
2279     if (cend >= cbegin) {
2280         int c0r,c1r;
2281         float c0x,c0y,c1x,c1y;
2282         float desc,lh;
2283         static NVGtextRow rows[BND_MAX_ROWS];
2284         int nrows = nvgTextBreakLines(
2285             ctx, label, label+cend+1, w, rows, BND_MAX_ROWS);
2286         nvgTextMetrics(ctx, NULL, &desc, &lh);
2287 
2288         bndCaretPosition(ctx, x, y, desc, lh, label+cbegin,
2289             rows, nrows, &c0r, &c0x, &c0y);
2290         bndCaretPosition(ctx, x, y, desc, lh, label+cend,
2291             rows, nrows, &c1r, &c1x, &c1y);
2292 
2293         nvgBeginPath(ctx);
2294         if (cbegin == cend) {
2295             nvgFillColor(ctx, nvgRGBf(0.337,0.502,0.761));
2296             nvgRect(ctx, c0x-1, c0y, 2, lh+1);
2297         } else {
2298             nvgFillColor(ctx, caretcolor);
2299             if (c0r == c1r) {
2300                 nvgRect(ctx, c0x-1, c0y, c1x-c0x+1, lh+1);
2301             } else {
2302                 int blk=c1r-c0r-1;
2303                 nvgRect(ctx, c0x-1, c0y, x+w-c0x+1, lh+1);
2304                 nvgRect(ctx, x, c1y, c1x-x+1, lh+1);
2305 
2306                 if (blk)
2307                     nvgRect(ctx, x, c0y+lh, w, blk*lh+1);
2308             }
2309         }
2310         nvgFill(ctx);
2311     }
2312 
2313     nvgBeginPath(ctx);
2314     nvgFillColor(ctx, color);
2315     nvgTextBox(ctx,x,y,w,label, NULL);
2316 }
2317 
bndCheck(NVGcontext * ctx,float ox,float oy,NVGcolor color)2318 void bndCheck(NVGcontext *ctx, float ox, float oy, NVGcolor color) {
2319     nvgBeginPath(ctx);
2320     nvgStrokeWidth(ctx,2);
2321     nvgStrokeColor(ctx,color);
2322     nvgLineCap(ctx,NVG_BUTT);
2323     nvgLineJoin(ctx,NVG_MITER);
2324     nvgMoveTo(ctx,ox+4,oy+5);
2325     nvgLineTo(ctx,ox+7,oy+8);
2326     nvgLineTo(ctx,ox+14,oy+1);
2327     nvgStroke(ctx);
2328 }
2329 
bndArrow(NVGcontext * ctx,float x,float y,float s,NVGcolor color)2330 void bndArrow(NVGcontext *ctx, float x, float y, float s, NVGcolor color) {
2331     nvgBeginPath(ctx);
2332     nvgMoveTo(ctx,x,y);
2333     nvgLineTo(ctx,x-s,y+s);
2334     nvgLineTo(ctx,x-s,y-s);
2335     nvgClosePath(ctx);
2336     nvgFillColor(ctx,color);
2337     nvgFill(ctx);
2338 }
2339 
bndUpDownArrow(NVGcontext * ctx,float x,float y,float s,NVGcolor color)2340 void bndUpDownArrow(NVGcontext *ctx, float x, float y, float s, NVGcolor color) {
2341     float w;
2342 
2343     nvgBeginPath(ctx);
2344     w = 1.1f*s;
2345     nvgMoveTo(ctx,x,y-1);
2346     nvgLineTo(ctx,x+0.5*w,y-s-1);
2347     nvgLineTo(ctx,x+w,y-1);
2348     nvgClosePath(ctx);
2349     nvgMoveTo(ctx,x,y+1);
2350     nvgLineTo(ctx,x+0.5*w,y+s+1);
2351     nvgLineTo(ctx,x+w,y+1);
2352     nvgClosePath(ctx);
2353     nvgFillColor(ctx,color);
2354     nvgFill(ctx);
2355 }
2356 
bndNodeArrowDown(NVGcontext * ctx,float x,float y,float s,NVGcolor color)2357 void bndNodeArrowDown(NVGcontext *ctx, float x, float y, float s, NVGcolor color) {
2358     float w;
2359     nvgBeginPath(ctx);
2360     w = 1.0f*s;
2361     nvgMoveTo(ctx,x,y);
2362     nvgLineTo(ctx,x+0.5*w,y-s);
2363     nvgLineTo(ctx,x-0.5*w,y-s);
2364     nvgClosePath(ctx);
2365     nvgFillColor(ctx,color);
2366     nvgFill(ctx);
2367 }
2368 
bndScrollHandleRect(float * x,float * y,float * w,float * h,float offset,float size)2369 void bndScrollHandleRect(float *x, float *y, float *w, float *h,
2370     float offset, float size) {
2371     size = bnd_clamp(size,0,1);
2372     offset = bnd_clamp(offset,0,1);
2373     if ((*h) > (*w)) {
2374         float hs = bnd_fmaxf(size*(*h), (*w)+1);
2375         *y = (*y) + ((*h)-hs)*offset;
2376         *h = hs;
2377     } else {
2378         float ws = bnd_fmaxf(size*(*w), (*h)-1);
2379         *x = (*x) + ((*w)-ws)*offset;
2380         *w = ws;
2381     }
2382 }
2383 
bndNodeWireColor(const BNDnodeTheme * theme,BNDwidgetState state)2384 NVGcolor bndNodeWireColor(const BNDnodeTheme *theme, BNDwidgetState state) {
2385     switch(state) {
2386         default:
2387         case BND_DEFAULT: return nvgRGBf(0.5f,0.5f,0.5f);
2388         case BND_HOVER: return theme->wireSelectColor;
2389         case BND_ACTIVE: return theme->activeNodeColor;
2390     }
2391 }
2392 
2393 ////////////////////////////////////////////////////////////////////////////////
2394 
2395 #ifdef BND_INLINE
2396 #undef BND_INLINE
2397 #endif
2398 
2399 #endif // BLENDISH_IMPLEMENTATION
2400