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