DPF

DISTRHO Plugin Framework
Log | Files | Refs | Submodules | README | LICENSE

commit c3e5d5199960157377736dce3b5e2cac61804d11
parent 867dd9bd953f274474d2afa49fc9aa00149721d8
Author: falkTX <falktx@gmail.com>
Date:   Tue,  1 Mar 2016 17:13:40 +0100

Remove blendish and NanoWidgets code

Diffstat:
Ddgl/NanoWidgets.hpp | 77-----------------------------------------------------------------------------
Ddgl/src/NanoWidgets.cpp | 152-------------------------------------------------------------------------------
Ddgl/src/oui-blendish/LICENSE | 21---------------------
Ddgl/src/oui-blendish/blendish.h | 2399-------------------------------------------------------------------------------
Ddgl/src/oui-blendish/oui.h | 2025-------------------------------------------------------------------------------
5 files changed, 0 insertions(+), 4674 deletions(-)

diff --git a/dgl/NanoWidgets.hpp b/dgl/NanoWidgets.hpp @@ -1,77 +0,0 @@ -/* - * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> - * - * Permission to use, copy, modify, and/or distribute this software for any purpose with - * or without fee is hereby granted, provided that the above copyright notice and this - * permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef DGL_NANO_WIDGETS_HPP_INCLUDED -#define DGL_NANO_WIDGETS_HPP_INCLUDED - -#include "NanoVG.hpp" - -START_NAMESPACE_DGL - -// ----------------------------------------------------------------------- - -class BlendishWidget : public NanoWidget -{ -public: - explicit BlendishWidget(Window& parent); - explicit BlendishWidget(NanoWidget* widget); - - void loadSharedResources() override; -}; - -// ----------------------------------------------------------------------- - -class BlendishButton : public BlendishWidget -{ -public: - class Callback - { - public: - virtual ~Callback() {} - virtual void blendishButtonClicked(BlendishButton* blendishButton, int button) = 0; - }; - - explicit BlendishButton(Window& parent, const char* text = "", int iconId = -1); - explicit BlendishButton(NanoWidget* widget, const char* text = "", int iconId = -1); - ~BlendishButton() override; - - int getIconId() const noexcept; - void setIconId(int iconId) noexcept; - - const char* getText() const noexcept; - void setText(const char* text) noexcept; - - void setCallback(Callback* callback) noexcept; - -protected: - void onNanoDisplay() override; - bool onMouse(const MouseEvent&) override; - bool onMotion(const MotionEvent&) override; - -private: - struct PrivateData; - PrivateData* const pData; - - void _updateBounds(); - - DISTRHO_LEAK_DETECTOR(BlendishButton) -}; - -// ----------------------------------------------------------------------- - -END_NAMESPACE_DGL - -#endif // DGL_NANO_WIDGETS_HPP_INCLUDED diff --git a/dgl/src/NanoWidgets.cpp b/dgl/src/NanoWidgets.cpp @@ -1,152 +0,0 @@ -/* - * DISTRHO Plugin Framework (DPF) - * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> - * - * Permission to use, copy, modify, and/or distribute this software for any purpose with - * or without fee is hereby granted, provided that the above copyright notice and this - * permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD - * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "Common.hpp" -#include "Resources.hpp" - -#define BLENDISH_IMPLEMENTATION -#include "nanovg/nanovg.h" -#include "oui-blendish/blendish.h" -#include "../distrho/extra/String.hpp" - -START_NAMESPACE_DGL - -// ----------------------------------------------------------------------- - -BlendishWidget::BlendishWidget(Window& parent) - : NanoWidget(parent) -{ - loadSharedResources(); -} - -BlendishWidget::BlendishWidget(NanoWidget* widget) - : NanoWidget(widget) -{ - loadSharedResources(); -} - -void BlendishWidget::loadSharedResources() -{ - if (nvgFindFont(fContext, NANOVG_DEJAVU_SANS_TTF) >= 0) - return; - - using namespace dpf_resources; - - bndSetFont(nvgCreateFontMem(fContext, NANOVG_DEJAVU_SANS_TTF, (const uchar*)dejavusans_ttf, dejavusans_ttf_size, 0)); - bndSetIconImage(nvgCreateImageMem(fContext, 0, (const uchar*)blender_icons16_png, blender_icons16_png_size)); -} - -// ----------------------------------------------------------------------- - -struct BlendishButton::PrivateData { - ButtonImpl impl; - int iconId; - DISTRHO_NAMESPACE::String text; - - PrivateData(Widget* const s, const char* const t, const int i) noexcept - : impl(s), - iconId(i), - text(t) {} - - DISTRHO_DECLARE_NON_COPY_STRUCT(PrivateData) -}; - -// ----------------------------------------------------------------------- - -BlendishButton::BlendishButton(Window& parent, const char* text, int iconId) - : BlendishWidget(parent), - pData(new PrivateData(this, text, iconId)) -{ - _updateBounds(); -} - -BlendishButton::BlendishButton(NanoWidget* widget, const char* text, int iconId) - : BlendishWidget(widget), - pData(new PrivateData(this, text, iconId)) -{ - _updateBounds(); -} - -BlendishButton::~BlendishButton() -{ - delete pData; -} - -int BlendishButton::getIconId() const noexcept -{ - return pData->iconId; -} - -void BlendishButton::setIconId(int iconId) noexcept -{ - if (pData->iconId == iconId) - return; - - pData->iconId = iconId; - _updateBounds(); - repaint(); -} - -const char* BlendishButton::getText() const noexcept -{ - return pData->text; -} - -void BlendishButton::setText(const char* text) noexcept -{ - if (pData->text == text) - return; - - pData->text = text; - _updateBounds(); - repaint(); -} - -void BlendishButton::setCallback(Callback* callback) noexcept -{ - pData->impl.callback_b = callback; -} - -void BlendishButton::onNanoDisplay() -{ - bndToolButton(getContext(), - getAbsoluteX(), getAbsoluteY(), getWidth(), getHeight(), - 0, static_cast<BNDwidgetState>(pData->impl.state), pData->iconId, pData->text); -} - -bool BlendishButton::onMouse(const MouseEvent& ev) -{ - return pData->impl.onMouse(ev); -} - -bool BlendishButton::onMotion(const MotionEvent& ev) -{ - return pData->impl.onMotion(ev); -} - -void BlendishButton::_updateBounds() -{ - const float width = bndLabelWidth (getContext(), pData->iconId, pData->text); - const float height = bndLabelHeight(getContext(), pData->iconId, pData->text, width); - - setSize(width, height); -} - -// ----------------------------------------------------------------------- - -END_NAMESPACE_DGL - -// ----------------------------------------------------------------------- diff --git a/dgl/src/oui-blendish/LICENSE b/dgl/src/oui-blendish/LICENSE @@ -1,21 +0,0 @@ -Blendish - Blender 2.5 UI based theming functions for NanoVG - -Copyright (c) 2014 Leonard Ritter <leonard.ritter@duangle.com> - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/dgl/src/oui-blendish/blendish.h b/dgl/src/oui-blendish/blendish.h @@ -1,2399 +0,0 @@ -/* -Blendish - Blender 2.5 UI based theming functions for NanoVG - -Copyright (c) 2014 Leonard Ritter <leonard.ritter@duangle.com> - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -#ifndef BLENDISH_H -#define BLENDISH_H - -#ifndef NANOVG_H -#error "nanovg.h must be included first." -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* - -Revision 6 (2014-09-21) - -Summary -------- - -Blendish is a small collection of drawing functions for NanoVG, designed to -replicate the look of the Blender 2.5+ User Interface. You can use these -functions to theme your UI library. Several metric constants for faithful -reproduction are also included. - -Blendish supports the original Blender icon sheet; As the licensing of Blenders -icons is unclear, they are not included in Blendishes repository, but a SVG -template, "icons_template.svg" is provided, which you can use to build your own -icon sheet. - -To use icons, you must first load the icon sheet using one of the -nvgCreateImage*() functions and then pass the image handle to bndSetIconImage(); -otherwise, no icons will be drawn. See bndSetIconImage() for more information. - -Blendish will not render text until a suitable UI font has been passed to -bndSetFont() has been called. See bndSetFont() for more information. - - -Drawbacks ---------- - -There is no support for varying dpi resolutions yet. The library is hardcoded -to the equivalent of 72 dpi in the Blender system settings. - -Support for label truncation is missing. Text rendering breaks when widgets are -too short to contain their labels. - -Usage ------ - -To use this header file in implementation mode, define BLENDISH_IMPLEMENTATION -before including blendish.h, otherwise the file will be in header-only mode. - -*/ - -// you can override this from the outside to pick -// the export level you need -#ifndef BND_EXPORT -#define BND_EXPORT -#endif - -// if that typedef is provided elsewhere, you may define -// BLENDISH_NO_NVG_TYPEDEFS before including the header. -#ifndef BLENDISH_NO_NVG_TYPEDEFS -typedef struct NVGcontext NVGcontext; -typedef struct NVGcolor NVGcolor; -typedef struct NVGglyphPosition NVGglyphPosition; -#endif - -// describes the theme used to draw a single widget or widget box; -// these values correspond to the same values that can be retrieved from -// the Theme panel in the Blender preferences -typedef struct BNDwidgetTheme { - // color of widget box outline - NVGcolor outlineColor; - // color of widget item (meaning changes depending on class) - NVGcolor itemColor; - // fill color of widget box - NVGcolor innerColor; - // fill color of widget box when active - NVGcolor innerSelectedColor; - // color of text label - NVGcolor textColor; - // color of text label when active - NVGcolor textSelectedColor; - // delta modifier for upper part of gradient (-100 to 100) - int shadeTop; - // delta modifier for lower part of gradient (-100 to 100) - int shadeDown; -} BNDwidgetTheme; - -// describes the theme used to draw nodes -typedef struct BNDnodeTheme { - // inner color of selected node (and downarrow) - NVGcolor nodeSelectedColor; - // outline of wires - NVGcolor wiresColor; - // color of text label when active - NVGcolor textSelectedColor; - - // inner color of active node (and dragged wire) - NVGcolor activeNodeColor; - // color of selected wire - NVGcolor wireSelectColor; - // color of background of node - NVGcolor nodeBackdropColor; - - // how much a noodle curves (0 to 10) - int noodleCurving; -} BNDnodeTheme; - -// describes the theme used to draw widgets -typedef struct BNDtheme { - // the background color of panels and windows - NVGcolor backgroundColor; - // theme for labels - BNDwidgetTheme regularTheme; - // theme for tool buttons - BNDwidgetTheme toolTheme; - // theme for radio buttons - BNDwidgetTheme radioTheme; - // theme for text fields - BNDwidgetTheme textFieldTheme; - // theme for option buttons (checkboxes) - BNDwidgetTheme optionTheme; - // theme for choice buttons (comboboxes) - // Blender calls them "menu buttons" - BNDwidgetTheme choiceTheme; - // theme for number fields - BNDwidgetTheme numberFieldTheme; - // theme for slider controls - BNDwidgetTheme sliderTheme; - // theme for scrollbars - BNDwidgetTheme scrollBarTheme; - // theme for tooltips - BNDwidgetTheme tooltipTheme; - // theme for menu backgrounds - BNDwidgetTheme menuTheme; - // theme for menu items - BNDwidgetTheme menuItemTheme; - // theme for nodes - BNDnodeTheme nodeTheme; -} BNDtheme; - -// how text on a control is aligned -typedef enum BNDtextAlignment { - BND_LEFT = 0, - BND_CENTER, -} BNDtextAlignment; - -// states altering the styling of a widget -typedef enum BNDwidgetState { - // not interacting - BND_DEFAULT = 0, - // the mouse is hovering over the control - BND_HOVER, - // the widget is activated (pressed) or in an active state (toggled) - BND_ACTIVE -} BNDwidgetState; - -// flags indicating which corners are sharp (for grouping widgets) -typedef enum BNDcornerFlags { - // all corners are round - BND_CORNER_NONE = 0, - // sharp top left corner - BND_CORNER_TOP_LEFT = 1, - // sharp top right corner - BND_CORNER_TOP_RIGHT = 2, - // sharp bottom right corner - BND_CORNER_DOWN_RIGHT = 4, - // sharp bottom left corner - BND_CORNER_DOWN_LEFT = 8, - // all corners are sharp; - // you can invert a set of flags using ^= BND_CORNER_ALL - BND_CORNER_ALL = 0xF, - // top border is sharp - BND_CORNER_TOP = 3, - // bottom border is sharp - BND_CORNER_DOWN = 0xC, - // left border is sharp - BND_CORNER_LEFT = 9, - // right border is sharp - BND_CORNER_RIGHT = 6 -} BNDcornerFlags; - -// build an icon ID from two coordinates into the icon sheet, where -// (0,0) designates the upper-leftmost icon, (1,0) the one right next to it, -// and so on. -#define BND_ICONID(x,y) ((x)|((y)<<8)) -// alpha of disabled widget groups -// can be used in conjunction with nvgGlobalAlpha() -#define BND_DISABLED_ALPHA 0.5 - -enum { - // default widget height - BND_WIDGET_HEIGHT = 21, - // default toolbutton width (if icon only) - BND_TOOL_WIDTH = 20, - - // default radius of node ports - BND_NODE_PORT_RADIUS = 5, - // top margin of node content - BND_NODE_MARGIN_TOP = 25, - // bottom margin of node content - BND_NODE_MARGIN_DOWN = 5, - // left and right margin of node content - BND_NODE_MARGIN_SIDE = 10, - // height of node title bar - BND_NODE_TITLE_HEIGHT = 20, - // width of node title arrow click area - BND_NODE_ARROW_AREA_WIDTH = 20, - - // size of splitter corner click area - BND_SPLITTER_AREA_SIZE = 12, - - // width of vertical scrollbar - BND_SCROLLBAR_WIDTH = 13, - // height of horizontal scrollbar - BND_SCROLLBAR_HEIGHT = 14, - - // default vertical spacing - BND_VSPACING = 1, - // default vertical spacing between groups - BND_VSPACING_GROUP = 8, - // default horizontal spacing - BND_HSPACING = 8, -}; - -typedef enum BNDicon { - BND_ICON_NONE = BND_ICONID(0,29), - BND_ICON_QUESTION = BND_ICONID(1,29), - BND_ICON_ERROR = BND_ICONID(2,29), - BND_ICON_CANCEL = BND_ICONID(3,29), - BND_ICON_TRIA_RIGHT = BND_ICONID(4,29), - BND_ICON_TRIA_DOWN = BND_ICONID(5,29), - BND_ICON_TRIA_LEFT = BND_ICONID(6,29), - BND_ICON_TRIA_UP = BND_ICONID(7,29), - BND_ICON_ARROW_LEFTRIGHT = BND_ICONID(8,29), - BND_ICON_PLUS = BND_ICONID(9,29), - BND_ICON_DISCLOSURE_TRI_DOWN = BND_ICONID(10,29), - BND_ICON_DISCLOSURE_TRI_RIGHT = BND_ICONID(11,29), - BND_ICON_RADIOBUT_OFF = BND_ICONID(12,29), - BND_ICON_RADIOBUT_ON = BND_ICONID(13,29), - BND_ICON_MENU_PANEL = BND_ICONID(14,29), - BND_ICON_BLENDER = BND_ICONID(15,29), - BND_ICON_GRIP = BND_ICONID(16,29), - BND_ICON_DOT = BND_ICONID(17,29), - BND_ICON_COLLAPSEMENU = BND_ICONID(18,29), - BND_ICON_X = BND_ICONID(19,29), - BND_ICON_GO_LEFT = BND_ICONID(21,29), - BND_ICON_PLUG = BND_ICONID(22,29), - BND_ICON_UI = BND_ICONID(23,29), - BND_ICON_NODE = BND_ICONID(24,29), - BND_ICON_NODE_SEL = BND_ICONID(25,29), - - BND_ICON_FULLSCREEN = BND_ICONID(0,28), - BND_ICON_SPLITSCREEN = BND_ICONID(1,28), - BND_ICON_RIGHTARROW_THIN = BND_ICONID(2,28), - BND_ICON_BORDERMOVE = BND_ICONID(3,28), - BND_ICON_VIEWZOOM = BND_ICONID(4,28), - BND_ICON_ZOOMIN = BND_ICONID(5,28), - BND_ICON_ZOOMOUT = BND_ICONID(6,28), - BND_ICON_PANEL_CLOSE = BND_ICONID(7,28), - BND_ICON_COPY_ID = BND_ICONID(8,28), - BND_ICON_EYEDROPPER = BND_ICONID(9,28), - BND_ICON_LINK_AREA = BND_ICONID(10,28), - BND_ICON_AUTO = BND_ICONID(11,28), - BND_ICON_CHECKBOX_DEHLT = BND_ICONID(12,28), - BND_ICON_CHECKBOX_HLT = BND_ICONID(13,28), - BND_ICON_UNLOCKED = BND_ICONID(14,28), - BND_ICON_LOCKED = BND_ICONID(15,28), - BND_ICON_UNPINNED = BND_ICONID(16,28), - BND_ICON_PINNED = BND_ICONID(17,28), - BND_ICON_SCREEN_BACK = BND_ICONID(18,28), - BND_ICON_RIGHTARROW = BND_ICONID(19,28), - BND_ICON_DOWNARROW_HLT = BND_ICONID(20,28), - BND_ICON_DOTSUP = BND_ICONID(21,28), - BND_ICON_DOTSDOWN = BND_ICONID(22,28), - BND_ICON_LINK = BND_ICONID(23,28), - BND_ICON_INLINK = BND_ICONID(24,28), - BND_ICON_PLUGIN = BND_ICONID(25,28), - - BND_ICON_HELP = BND_ICONID(0,27), - BND_ICON_GHOST_ENABLED = BND_ICONID(1,27), - BND_ICON_COLOR = BND_ICONID(2,27), - BND_ICON_LINKED = BND_ICONID(3,27), - BND_ICON_UNLINKED = BND_ICONID(4,27), - BND_ICON_HAND = BND_ICONID(5,27), - BND_ICON_ZOOM_ALL = BND_ICONID(6,27), - BND_ICON_ZOOM_SELECTED = BND_ICONID(7,27), - BND_ICON_ZOOM_PREVIOUS = BND_ICONID(8,27), - BND_ICON_ZOOM_IN = BND_ICONID(9,27), - BND_ICON_ZOOM_OUT = BND_ICONID(10,27), - BND_ICON_RENDER_REGION = BND_ICONID(11,27), - BND_ICON_BORDER_RECT = BND_ICONID(12,27), - BND_ICON_BORDER_LASSO = BND_ICONID(13,27), - BND_ICON_FREEZE = BND_ICONID(14,27), - BND_ICON_STYLUS_PRESSURE = BND_ICONID(15,27), - BND_ICON_GHOST_DISABLED = BND_ICONID(16,27), - BND_ICON_NEW = BND_ICONID(17,27), - BND_ICON_FILE_TICK = BND_ICONID(18,27), - BND_ICON_QUIT = BND_ICONID(19,27), - BND_ICON_URL = BND_ICONID(20,27), - BND_ICON_RECOVER_LAST = BND_ICONID(21,27), - BND_ICON_FULLSCREEN_ENTER = BND_ICONID(23,27), - BND_ICON_FULLSCREEN_EXIT = BND_ICONID(24,27), - BND_ICON_BLANK1 = BND_ICONID(25,27), - - BND_ICON_LAMP = BND_ICONID(0,26), - BND_ICON_MATERIAL = BND_ICONID(1,26), - BND_ICON_TEXTURE = BND_ICONID(2,26), - BND_ICON_ANIM = BND_ICONID(3,26), - BND_ICON_WORLD = BND_ICONID(4,26), - BND_ICON_SCENE = BND_ICONID(5,26), - BND_ICON_EDIT = BND_ICONID(6,26), - BND_ICON_GAME = BND_ICONID(7,26), - BND_ICON_RADIO = BND_ICONID(8,26), - BND_ICON_SCRIPT = BND_ICONID(9,26), - BND_ICON_PARTICLES = BND_ICONID(10,26), - BND_ICON_PHYSICS = BND_ICONID(11,26), - BND_ICON_SPEAKER = BND_ICONID(12,26), - BND_ICON_TEXTURE_SHADED = BND_ICONID(13,26), - - BND_ICON_VIEW3D = BND_ICONID(0,25), - BND_ICON_IPO = BND_ICONID(1,25), - BND_ICON_OOPS = BND_ICONID(2,25), - BND_ICON_BUTS = BND_ICONID(3,25), - BND_ICON_FILESEL = BND_ICONID(4,25), - BND_ICON_IMAGE_COL = BND_ICONID(5,25), - BND_ICON_INFO = BND_ICONID(6,25), - BND_ICON_SEQUENCE = BND_ICONID(7,25), - BND_ICON_TEXT = BND_ICONID(8,25), - BND_ICON_IMASEL = BND_ICONID(9,25), - BND_ICON_SOUND = BND_ICONID(10,25), - BND_ICON_ACTION = BND_ICONID(11,25), - BND_ICON_NLA = BND_ICONID(12,25), - BND_ICON_SCRIPTWIN = BND_ICONID(13,25), - BND_ICON_TIME = BND_ICONID(14,25), - BND_ICON_NODETREE = BND_ICONID(15,25), - BND_ICON_LOGIC = BND_ICONID(16,25), - BND_ICON_CONSOLE = BND_ICONID(17,25), - BND_ICON_PREFERENCES = BND_ICONID(18,25), - BND_ICON_CLIP = BND_ICONID(19,25), - BND_ICON_ASSET_MANAGER = BND_ICONID(20,25), - - BND_ICON_OBJECT_DATAMODE = BND_ICONID(0,24), - BND_ICON_EDITMODE_HLT = BND_ICONID(1,24), - BND_ICON_FACESEL_HLT = BND_ICONID(2,24), - BND_ICON_VPAINT_HLT = BND_ICONID(3,24), - BND_ICON_TPAINT_HLT = BND_ICONID(4,24), - BND_ICON_WPAINT_HLT = BND_ICONID(5,24), - BND_ICON_SCULPTMODE_HLT = BND_ICONID(6,24), - BND_ICON_POSE_HLT = BND_ICONID(7,24), - BND_ICON_PARTICLEMODE = BND_ICONID(8,24), - BND_ICON_LIGHTPAINT = BND_ICONID(9,24), - - BND_ICON_SCENE_DATA = BND_ICONID(0,23), - BND_ICON_RENDERLAYERS = BND_ICONID(1,23), - BND_ICON_WORLD_DATA = BND_ICONID(2,23), - BND_ICON_OBJECT_DATA = BND_ICONID(3,23), - BND_ICON_MESH_DATA = BND_ICONID(4,23), - BND_ICON_CURVE_DATA = BND_ICONID(5,23), - BND_ICON_META_DATA = BND_ICONID(6,23), - BND_ICON_LATTICE_DATA = BND_ICONID(7,23), - BND_ICON_LAMP_DATA = BND_ICONID(8,23), - BND_ICON_MATERIAL_DATA = BND_ICONID(9,23), - BND_ICON_TEXTURE_DATA = BND_ICONID(10,23), - BND_ICON_ANIM_DATA = BND_ICONID(11,23), - BND_ICON_CAMERA_DATA = BND_ICONID(12,23), - BND_ICON_PARTICLE_DATA = BND_ICONID(13,23), - BND_ICON_LIBRARY_DATA_DIRECT = BND_ICONID(14,23), - BND_ICON_GROUP = BND_ICONID(15,23), - BND_ICON_ARMATURE_DATA = BND_ICONID(16,23), - BND_ICON_POSE_DATA = BND_ICONID(17,23), - BND_ICON_BONE_DATA = BND_ICONID(18,23), - BND_ICON_CONSTRAINT = BND_ICONID(19,23), - BND_ICON_SHAPEKEY_DATA = BND_ICONID(20,23), - BND_ICON_CONSTRAINT_BONE = BND_ICONID(21,23), - BND_ICON_CAMERA_STEREO = BND_ICONID(22,23), - BND_ICON_PACKAGE = BND_ICONID(23,23), - BND_ICON_UGLYPACKAGE = BND_ICONID(24,23), - - BND_ICON_BRUSH_DATA = BND_ICONID(0,22), - BND_ICON_IMAGE_DATA = BND_ICONID(1,22), - BND_ICON_FILE = BND_ICONID(2,22), - BND_ICON_FCURVE = BND_ICONID(3,22), - BND_ICON_FONT_DATA = BND_ICONID(4,22), - BND_ICON_RENDER_RESULT = BND_ICONID(5,22), - BND_ICON_SURFACE_DATA = BND_ICONID(6,22), - BND_ICON_EMPTY_DATA = BND_ICONID(7,22), - BND_ICON_SETTINGS = BND_ICONID(8,22), - BND_ICON_RENDER_ANIMATION = BND_ICONID(9,22), - BND_ICON_RENDER_STILL = BND_ICONID(10,22), - BND_ICON_BOIDS = BND_ICONID(12,22), - BND_ICON_STRANDS = BND_ICONID(13,22), - BND_ICON_LIBRARY_DATA_INDIRECT = BND_ICONID(14,22), - BND_ICON_GREASEPENCIL = BND_ICONID(15,22), - BND_ICON_LINE_DATA = BND_ICONID(16,22), - BND_ICON_GROUP_BONE = BND_ICONID(18,22), - BND_ICON_GROUP_VERTEX = BND_ICONID(19,22), - BND_ICON_GROUP_VCOL = BND_ICONID(20,22), - BND_ICON_GROUP_UVS = BND_ICONID(21,22), - BND_ICON_RNA = BND_ICONID(24,22), - BND_ICON_RNA_ADD = BND_ICONID(25,22), - - BND_ICON_OUTLINER_OB_EMPTY = BND_ICONID(0,20), - BND_ICON_OUTLINER_OB_MESH = BND_ICONID(1,20), - BND_ICON_OUTLINER_OB_CURVE = BND_ICONID(2,20), - BND_ICON_OUTLINER_OB_LATTICE = BND_ICONID(3,20), - BND_ICON_OUTLINER_OB_META = BND_ICONID(4,20), - BND_ICON_OUTLINER_OB_LAMP = BND_ICONID(5,20), - BND_ICON_OUTLINER_OB_CAMERA = BND_ICONID(6,20), - BND_ICON_OUTLINER_OB_ARMATURE = BND_ICONID(7,20), - BND_ICON_OUTLINER_OB_FONT = BND_ICONID(8,20), - BND_ICON_OUTLINER_OB_SURFACE = BND_ICONID(9,20), - BND_ICON_OUTLINER_OB_SPEAKER = BND_ICONID(10,20), - BND_ICON_RESTRICT_VIEW_OFF = BND_ICONID(19,20), - BND_ICON_RESTRICT_VIEW_ON = BND_ICONID(20,20), - BND_ICON_RESTRICT_SELECT_OFF = BND_ICONID(21,20), - BND_ICON_RESTRICT_SELECT_ON = BND_ICONID(22,20), - BND_ICON_RESTRICT_RENDER_OFF = BND_ICONID(23,20), - BND_ICON_RESTRICT_RENDER_ON = BND_ICONID(24,20), - - BND_ICON_OUTLINER_DATA_EMPTY = BND_ICONID(0,19), - BND_ICON_OUTLINER_DATA_MESH = BND_ICONID(1,19), - BND_ICON_OUTLINER_DATA_CURVE = BND_ICONID(2,19), - BND_ICON_OUTLINER_DATA_LATTICE = BND_ICONID(3,19), - BND_ICON_OUTLINER_DATA_META = BND_ICONID(4,19), - BND_ICON_OUTLINER_DATA_LAMP = BND_ICONID(5,19), - BND_ICON_OUTLINER_DATA_CAMERA = BND_ICONID(6,19), - BND_ICON_OUTLINER_DATA_ARMATURE = BND_ICONID(7,19), - BND_ICON_OUTLINER_DATA_FONT = BND_ICONID(8,19), - BND_ICON_OUTLINER_DATA_SURFACE = BND_ICONID(9,19), - BND_ICON_OUTLINER_DATA_SPEAKER = BND_ICONID(10,19), - BND_ICON_OUTLINER_DATA_POSE = BND_ICONID(11,19), - - BND_ICON_MESH_PLANE = BND_ICONID(0,18), - BND_ICON_MESH_CUBE = BND_ICONID(1,18), - BND_ICON_MESH_CIRCLE = BND_ICONID(2,18), - BND_ICON_MESH_UVSPHERE = BND_ICONID(3,18), - BND_ICON_MESH_ICOSPHERE = BND_ICONID(4,18), - BND_ICON_MESH_GRID = BND_ICONID(5,18), - BND_ICON_MESH_MONKEY = BND_ICONID(6,18), - BND_ICON_MESH_CYLINDER = BND_ICONID(7,18), - BND_ICON_MESH_TORUS = BND_ICONID(8,18), - BND_ICON_MESH_CONE = BND_ICONID(9,18), - BND_ICON_LAMP_POINT = BND_ICONID(12,18), - BND_ICON_LAMP_SUN = BND_ICONID(13,18), - BND_ICON_LAMP_SPOT = BND_ICONID(14,18), - BND_ICON_LAMP_HEMI = BND_ICONID(15,18), - BND_ICON_LAMP_AREA = BND_ICONID(16,18), - BND_ICON_META_EMPTY = BND_ICONID(19,18), - BND_ICON_META_PLANE = BND_ICONID(20,18), - BND_ICON_META_CUBE = BND_ICONID(21,18), - BND_ICON_META_BALL = BND_ICONID(22,18), - BND_ICON_META_ELLIPSOID = BND_ICONID(23,18), - BND_ICON_META_CAPSULE = BND_ICONID(24,18), - - BND_ICON_SURFACE_NCURVE = BND_ICONID(0,17), - BND_ICON_SURFACE_NCIRCLE = BND_ICONID(1,17), - BND_ICON_SURFACE_NSURFACE = BND_ICONID(2,17), - BND_ICON_SURFACE_NCYLINDER = BND_ICONID(3,17), - BND_ICON_SURFACE_NSPHERE = BND_ICONID(4,17), - BND_ICON_SURFACE_NTORUS = BND_ICONID(5,17), - BND_ICON_CURVE_BEZCURVE = BND_ICONID(9,17), - BND_ICON_CURVE_BEZCIRCLE = BND_ICONID(10,17), - BND_ICON_CURVE_NCURVE = BND_ICONID(11,17), - BND_ICON_CURVE_NCIRCLE = BND_ICONID(12,17), - BND_ICON_CURVE_PATH = BND_ICONID(13,17), - BND_ICON_COLOR_RED = BND_ICONID(19,17), - BND_ICON_COLOR_GREEN = BND_ICONID(20,17), - BND_ICON_COLOR_BLUE = BND_ICONID(21,17), - - BND_ICON_FORCE_FORCE = BND_ICONID(0,16), - BND_ICON_FORCE_WIND = BND_ICONID(1,16), - BND_ICON_FORCE_VORTEX = BND_ICONID(2,16), - BND_ICON_FORCE_MAGNETIC = BND_ICONID(3,16), - BND_ICON_FORCE_HARMONIC = BND_ICONID(4,16), - BND_ICON_FORCE_CHARGE = BND_ICONID(5,16), - BND_ICON_FORCE_LENNARDJONES = BND_ICONID(6,16), - BND_ICON_FORCE_TEXTURE = BND_ICONID(7,16), - BND_ICON_FORCE_CURVE = BND_ICONID(8,16), - BND_ICON_FORCE_BOID = BND_ICONID(9,16), - BND_ICON_FORCE_TURBULENCE = BND_ICONID(10,16), - BND_ICON_FORCE_DRAG = BND_ICONID(11,16), - BND_ICON_FORCE_SMOKEFLOW = BND_ICONID(12,16), - - BND_ICON_MODIFIER = BND_ICONID(0,12), - BND_ICON_MOD_WAVE = BND_ICONID(1,12), - BND_ICON_MOD_BUILD = BND_ICONID(2,12), - BND_ICON_MOD_DECIM = BND_ICONID(3,12), - BND_ICON_MOD_MIRROR = BND_ICONID(4,12), - BND_ICON_MOD_SOFT = BND_ICONID(5,12), - BND_ICON_MOD_SUBSURF = BND_ICONID(6,12), - BND_ICON_HOOK = BND_ICONID(7,12), - BND_ICON_MOD_PHYSICS = BND_ICONID(8,12), - BND_ICON_MOD_PARTICLES = BND_ICONID(9,12), - BND_ICON_MOD_BOOLEAN = BND_ICONID(10,12), - BND_ICON_MOD_EDGESPLIT = BND_ICONID(11,12), - BND_ICON_MOD_ARRAY = BND_ICONID(12,12), - BND_ICON_MOD_UVPROJECT = BND_ICONID(13,12), - BND_ICON_MOD_DISPLACE = BND_ICONID(14,12), - BND_ICON_MOD_CURVE = BND_ICONID(15,12), - BND_ICON_MOD_LATTICE = BND_ICONID(16,12), - BND_ICON_CONSTRAINT_DATA = BND_ICONID(17,12), - BND_ICON_MOD_ARMATURE = BND_ICONID(18,12), - BND_ICON_MOD_SHRINKWRAP = BND_ICONID(19,12), - BND_ICON_MOD_CAST = BND_ICONID(20,12), - BND_ICON_MOD_MESHDEFORM = BND_ICONID(21,12), - BND_ICON_MOD_BEVEL = BND_ICONID(22,12), - BND_ICON_MOD_SMOOTH = BND_ICONID(23,12), - BND_ICON_MOD_SIMPLEDEFORM = BND_ICONID(24,12), - BND_ICON_MOD_MASK = BND_ICONID(25,12), - - BND_ICON_MOD_CLOTH = BND_ICONID(0,11), - BND_ICON_MOD_EXPLODE = BND_ICONID(1,11), - BND_ICON_MOD_FLUIDSIM = BND_ICONID(2,11), - BND_ICON_MOD_MULTIRES = BND_ICONID(3,11), - BND_ICON_MOD_SMOKE = BND_ICONID(4,11), - BND_ICON_MOD_SOLIDIFY = BND_ICONID(5,11), - BND_ICON_MOD_SCREW = BND_ICONID(6,11), - BND_ICON_MOD_VERTEX_WEIGHT = BND_ICONID(7,11), - BND_ICON_MOD_DYNAMICPAINT = BND_ICONID(8,11), - BND_ICON_MOD_REMESH = BND_ICONID(9,11), - BND_ICON_MOD_OCEAN = BND_ICONID(10,11), - BND_ICON_MOD_WARP = BND_ICONID(11,11), - BND_ICON_MOD_SKIN = BND_ICONID(12,11), - BND_ICON_MOD_TRIANGULATE = BND_ICONID(13,11), - BND_ICON_MOD_WIREFRAME = BND_ICONID(14,11), - - BND_ICON_REC = BND_ICONID(0,10), - BND_ICON_PLAY = BND_ICONID(1,10), - BND_ICON_FF = BND_ICONID(2,10), - BND_ICON_REW = BND_ICONID(3,10), - BND_ICON_PAUSE = BND_ICONID(4,10), - BND_ICON_PREV_KEYFRAME = BND_ICONID(5,10), - BND_ICON_NEXT_KEYFRAME = BND_ICONID(6,10), - BND_ICON_PLAY_AUDIO = BND_ICONID(7,10), - BND_ICON_PLAY_REVERSE = BND_ICONID(8,10), - BND_ICON_PREVIEW_RANGE = BND_ICONID(9,10), - BND_ICON_ACTION_TWEAK = BND_ICONID(10,10), - BND_ICON_PMARKER_ACT = BND_ICONID(11,10), - BND_ICON_PMARKER_SEL = BND_ICONID(12,10), - BND_ICON_PMARKER = BND_ICONID(13,10), - BND_ICON_MARKER_HLT = BND_ICONID(14,10), - BND_ICON_MARKER = BND_ICONID(15,10), - BND_ICON_SPACE2 = BND_ICONID(16,10), - BND_ICON_SPACE3 = BND_ICONID(17,10), - BND_ICON_KEYINGSET = BND_ICONID(18,10), - BND_ICON_KEY_DEHLT = BND_ICONID(19,10), - BND_ICON_KEY_HLT = BND_ICONID(20,10), - BND_ICON_MUTE_IPO_OFF = BND_ICONID(21,10), - BND_ICON_MUTE_IPO_ON = BND_ICONID(22,10), - BND_ICON_VISIBLE_IPO_OFF = BND_ICONID(23,10), - BND_ICON_VISIBLE_IPO_ON = BND_ICONID(24,10), - BND_ICON_DRIVER = BND_ICONID(25,10), - - BND_ICON_SOLO_OFF = BND_ICONID(0,9), - BND_ICON_SOLO_ON = BND_ICONID(1,9), - BND_ICON_FRAME_PREV = BND_ICONID(2,9), - BND_ICON_FRAME_NEXT = BND_ICONID(3,9), - BND_ICON_NLA_PUSHDOWN = BND_ICONID(4,9), - BND_ICON_IPO_CONSTANT = BND_ICONID(5,9), - BND_ICON_IPO_LINEAR = BND_ICONID(6,9), - BND_ICON_IPO_BEZIER = BND_ICONID(7,9), - BND_ICON_IPO_SINE = BND_ICONID(8,9), - BND_ICON_IPO_QUAD = BND_ICONID(9,9), - BND_ICON_IPO_CUBIC = BND_ICONID(10,9), - BND_ICON_IPO_QUART = BND_ICONID(11,9), - BND_ICON_IPO_QUINT = BND_ICONID(12,9), - BND_ICON_IPO_EXPO = BND_ICONID(13,9), - BND_ICON_IPO_CIRC = BND_ICONID(14,9), - BND_ICON_IPO_BOUNCE = BND_ICONID(15,9), - BND_ICON_IPO_ELASTIC = BND_ICONID(16,9), - BND_ICON_IPO_BACK = BND_ICONID(17,9), - BND_ICON_IPO_EASE_IN = BND_ICONID(18,9), - BND_ICON_IPO_EASE_OUT = BND_ICONID(19,9), - BND_ICON_IPO_EASE_IN_OUT = BND_ICONID(20,9), - - BND_ICON_VERTEXSEL = BND_ICONID(0,8), - BND_ICON_EDGESEL = BND_ICONID(1,8), - BND_ICON_FACESEL = BND_ICONID(2,8), - BND_ICON_LOOPSEL = BND_ICONID(3,8), - BND_ICON_ROTATE = BND_ICONID(5,8), - BND_ICON_CURSOR = BND_ICONID(6,8), - BND_ICON_ROTATECOLLECTION = BND_ICONID(7,8), - BND_ICON_ROTATECENTER = BND_ICONID(8,8), - BND_ICON_ROTACTIVE = BND_ICONID(9,8), - BND_ICON_ALIGN = BND_ICONID(10,8), - BND_ICON_SMOOTHCURVE = BND_ICONID(12,8), - BND_ICON_SPHERECURVE = BND_ICONID(13,8), - BND_ICON_ROOTCURVE = BND_ICONID(14,8), - BND_ICON_SHARPCURVE = BND_ICONID(15,8), - BND_ICON_LINCURVE = BND_ICONID(16,8), - BND_ICON_NOCURVE = BND_ICONID(17,8), - BND_ICON_RNDCURVE = BND_ICONID(18,8), - BND_ICON_PROP_OFF = BND_ICONID(19,8), - BND_ICON_PROP_ON = BND_ICONID(20,8), - BND_ICON_PROP_CON = BND_ICONID(21,8), - BND_ICON_SCULPT_DYNTOPO = BND_ICONID(22,8), - BND_ICON_PARTICLE_POINT = BND_ICONID(23,8), - BND_ICON_PARTICLE_TIP = BND_ICONID(24,8), - BND_ICON_PARTICLE_PATH = BND_ICONID(25,8), - - BND_ICON_MAN_TRANS = BND_ICONID(0,7), - BND_ICON_MAN_ROT = BND_ICONID(1,7), - BND_ICON_MAN_SCALE = BND_ICONID(2,7), - BND_ICON_MANIPUL = BND_ICONID(3,7), - BND_ICON_SNAP_OFF = BND_ICONID(4,7), - BND_ICON_SNAP_ON = BND_ICONID(5,7), - BND_ICON_SNAP_NORMAL = BND_ICONID(6,7), - BND_ICON_SNAP_INCREMENT = BND_ICONID(7,7), - BND_ICON_SNAP_VERTEX = BND_ICONID(8,7), - BND_ICON_SNAP_EDGE = BND_ICONID(9,7), - BND_ICON_SNAP_FACE = BND_ICONID(10,7), - BND_ICON_SNAP_VOLUME = BND_ICONID(11,7), - BND_ICON_STICKY_UVS_LOC = BND_ICONID(13,7), - BND_ICON_STICKY_UVS_DISABLE = BND_ICONID(14,7), - BND_ICON_STICKY_UVS_VERT = BND_ICONID(15,7), - BND_ICON_CLIPUV_DEHLT = BND_ICONID(16,7), - BND_ICON_CLIPUV_HLT = BND_ICONID(17,7), - BND_ICON_SNAP_PEEL_OBJECT = BND_ICONID(18,7), - BND_ICON_GRID = BND_ICONID(19,7), - - BND_ICON_PASTEDOWN = BND_ICONID(0,6), - BND_ICON_COPYDOWN = BND_ICONID(1,6), - BND_ICON_PASTEFLIPUP = BND_ICONID(2,6), - BND_ICON_PASTEFLIPDOWN = BND_ICONID(3,6), - BND_ICON_SNAP_SURFACE = BND_ICONID(8,6), - BND_ICON_AUTOMERGE_ON = BND_ICONID(9,6), - BND_ICON_AUTOMERGE_OFF = BND_ICONID(10,6), - BND_ICON_RETOPO = BND_ICONID(11,6), - BND_ICON_UV_VERTEXSEL = BND_ICONID(12,6), - BND_ICON_UV_EDGESEL = BND_ICONID(13,6), - BND_ICON_UV_FACESEL = BND_ICONID(14,6), - BND_ICON_UV_ISLANDSEL = BND_ICONID(15,6), - BND_ICON_UV_SYNC_SELECT = BND_ICONID(16,6), - - BND_ICON_BBOX = BND_ICONID(0,5), - BND_ICON_WIRE = BND_ICONID(1,5), - BND_ICON_SOLID = BND_ICONID(2,5), - BND_ICON_SMOOTH = BND_ICONID(3,5), - BND_ICON_POTATO = BND_ICONID(4,5), - BND_ICON_ORTHO = BND_ICONID(6,5), - BND_ICON_LOCKVIEW_OFF = BND_ICONID(9,5), - BND_ICON_LOCKVIEW_ON = BND_ICONID(10,5), - BND_ICON_AXIS_SIDE = BND_ICONID(12,5), - BND_ICON_AXIS_FRONT = BND_ICONID(13,5), - BND_ICON_AXIS_TOP = BND_ICONID(14,5), - BND_ICON_NDOF_DOM = BND_ICONID(15,5), - BND_ICON_NDOF_TURN = BND_ICONID(16,5), - BND_ICON_NDOF_FLY = BND_ICONID(17,5), - BND_ICON_NDOF_TRANS = BND_ICONID(18,5), - BND_ICON_LAYER_USED = BND_ICONID(19,5), - BND_ICON_LAYER_ACTIVE = BND_ICONID(20,5), - - BND_ICON_SORTALPHA = BND_ICONID(0,3), - BND_ICON_SORTBYEXT = BND_ICONID(1,3), - BND_ICON_SORTTIME = BND_ICONID(2,3), - BND_ICON_SORTSIZE = BND_ICONID(3,3), - BND_ICON_LONGDISPLAY = BND_ICONID(4,3), - BND_ICON_SHORTDISPLAY = BND_ICONID(5,3), - BND_ICON_GHOST = BND_ICONID(6,3), - BND_ICON_IMGDISPLAY = BND_ICONID(7,3), - BND_ICON_SAVE_AS = BND_ICONID(8,3), - BND_ICON_SAVE_COPY = BND_ICONID(9,3), - BND_ICON_BOOKMARKS = BND_ICONID(10,3), - BND_ICON_FONTPREVIEW = BND_ICONID(11,3), - BND_ICON_FILTER = BND_ICONID(12,3), - BND_ICON_NEWFOLDER = BND_ICONID(13,3), - BND_ICON_OPEN_RECENT = BND_ICONID(14,3), - BND_ICON_FILE_PARENT = BND_ICONID(15,3), - BND_ICON_FILE_REFRESH = BND_ICONID(16,3), - BND_ICON_FILE_FOLDER = BND_ICONID(17,3), - BND_ICON_FILE_BLANK = BND_ICONID(18,3), - BND_ICON_FILE_BLEND = BND_ICONID(19,3), - BND_ICON_FILE_IMAGE = BND_ICONID(20,3), - BND_ICON_FILE_MOVIE = BND_ICONID(21,3), - BND_ICON_FILE_SCRIPT = BND_ICONID(22,3), - BND_ICON_FILE_SOUND = BND_ICONID(23,3), - BND_ICON_FILE_FONT = BND_ICONID(24,3), - BND_ICON_FILE_TEXT = BND_ICONID(25,3), - - BND_ICON_RECOVER_AUTO = BND_ICONID(0,2), - BND_ICON_SAVE_PREFS = BND_ICONID(1,2), - BND_ICON_LINK_BLEND = BND_ICONID(2,2), - BND_ICON_APPEND_BLEND = BND_ICONID(3,2), - BND_ICON_IMPORT = BND_ICONID(4,2), - BND_ICON_EXPORT = BND_ICONID(5,2), - BND_ICON_EXTERNAL_DATA = BND_ICONID(6,2), - BND_ICON_LOAD_FACTORY = BND_ICONID(7,2), - BND_ICON_LOOP_BACK = BND_ICONID(13,2), - BND_ICON_LOOP_FORWARDS = BND_ICONID(14,2), - BND_ICON_BACK = BND_ICONID(15,2), - BND_ICON_FORWARD = BND_ICONID(16,2), - BND_ICON_FILE_BACKUP = BND_ICONID(24,2), - BND_ICON_DISK_DRIVE = BND_ICONID(25,2), - - BND_ICON_MATPLANE = BND_ICONID(0,1), - BND_ICON_MATSPHERE = BND_ICONID(1,1), - BND_ICON_MATCUBE = BND_ICONID(2,1), - BND_ICON_MONKEY = BND_ICONID(3,1), - BND_ICON_HAIR = BND_ICONID(4,1), - BND_ICON_ALIASED = BND_ICONID(5,1), - BND_ICON_ANTIALIASED = BND_ICONID(6,1), - BND_ICON_MAT_SPHERE_SKY = BND_ICONID(7,1), - BND_ICON_WORDWRAP_OFF = BND_ICONID(12,1), - BND_ICON_WORDWRAP_ON = BND_ICONID(13,1), - BND_ICON_SYNTAX_OFF = BND_ICONID(14,1), - BND_ICON_SYNTAX_ON = BND_ICONID(15,1), - BND_ICON_LINENUMBERS_OFF = BND_ICONID(16,1), - BND_ICON_LINENUMBERS_ON = BND_ICONID(17,1), - BND_ICON_SCRIPTPLUGINS = BND_ICONID(18,1), - - BND_ICON_SEQ_SEQUENCER = BND_ICONID(0,0), - BND_ICON_SEQ_PREVIEW = BND_ICONID(1,0), - BND_ICON_SEQ_LUMA_WAVEFORM = BND_ICONID(2,0), - BND_ICON_SEQ_CHROMA_SCOPE = BND_ICONID(3,0), - BND_ICON_SEQ_HISTOGRAM = BND_ICONID(4,0), - BND_ICON_SEQ_SPLITVIEW = BND_ICONID(5,0), - BND_ICON_IMAGE_RGB = BND_ICONID(9,0), - BND_ICON_IMAGE_RGB_ALPHA = BND_ICONID(10,0), - BND_ICON_IMAGE_ALPHA = BND_ICONID(11,0), - BND_ICON_IMAGE_ZDEPTH = BND_ICONID(12,0), - BND_ICON_IMAGEFILE = BND_ICONID(13,0), -} BNDicon; - -//////////////////////////////////////////////////////////////////////////////// - -// set the current theme all widgets will be drawn with. -// the default Blender 2.6 theme is set by default. -BND_EXPORT void bndSetTheme(BNDtheme theme); - -// Returns the currently set theme -BND_EXPORT const BNDtheme *bndGetTheme(); - -// designates an image handle as returned by nvgCreateImage*() as the themes' -// icon sheet. The icon sheet format must be compatible to Blender 2.6's icon -// sheet; the order of icons does not matter. -// A valid icon sheet is e.g. shown at -// http://wiki.blender.org/index.php/Dev:2.5/Doc/How_to/Add_an_icon -BND_EXPORT void bndSetIconImage(int image); - -// designates an image handle as returned by nvgCreateFont*() as the themes' -// UI font. Blender's original UI font Droid Sans is perfectly suited and -// available here: -// https://svn.blender.org/svnroot/bf-blender/trunk/blender/release/datafiles/fonts/ -BND_EXPORT void bndSetFont(int font); - -//////////////////////////////////////////////////////////////////////////////// - -// High Level Functions -// -------------------- -// Use these functions to draw themed widgets with your NVGcontext. - -// Draw a label with its lower left origin at (x,y) and size of (w,h). -// if iconid >= 0, an icon will be added to the widget -// if label is not NULL, a label will be added to the widget -// widget looks best when height is BND_WIDGET_HEIGHT -BND_EXPORT void bndLabel(NVGcontext *ctx, - float x, float y, float w, float h, int iconid, const char *label); - -// Draw a tool button with its lower left origin at (x,y) and size of (w,h), -// where flags is one or multiple flags from BNDcornerFlags and state denotes -// the widgets current UI state. -// if iconid >= 0, an icon will be added to the widget -// if label is not NULL, a label will be added to the widget -// widget looks best when height is BND_WIDGET_HEIGHT -BND_EXPORT void bndToolButton(NVGcontext *ctx, - float x, float y, float w, float h, int flags, BNDwidgetState state, - int iconid, const char *label); - -// Draw a radio button with its lower left origin at (x,y) and size of (w,h), -// where flags is one or multiple flags from BNDcornerFlags and state denotes -// the widgets current UI state. -// if iconid >= 0, an icon will be added to the widget -// if label is not NULL, a label will be added to the widget -// widget looks best when height is BND_WIDGET_HEIGHT -BND_EXPORT void bndRadioButton(NVGcontext *ctx, - float x, float y, float w, float h, int flags, BNDwidgetState state, - int iconid, const char *label); - - -// Calculate the corresponding text position for given coordinates px/py -// in a text field. -// See bndTextField for more info. -BND_EXPORT int bndTextFieldTextPosition(NVGcontext *ctx, float x, float y, float w, float h, - int iconid, const char *text, int px, int py); - -// Draw a text field with its lower left origin at (x,y) and size of (w,h), -// where flags is one or multiple flags from BNDcornerFlags and state denotes -// the widgets current UI state. -// if iconid >= 0, an icon will be added to the widget -// if text is not NULL, text will be printed to the widget -// cbegin must be >= 0 and <= strlen(text) and denotes the beginning of the caret -// cend must be >= cbegin and <= strlen(text) and denotes the end of the caret -// if cend < cbegin, then no caret will be drawn -// widget looks best when height is BND_WIDGET_HEIGHT -BND_EXPORT void bndTextField(NVGcontext *ctx, - float x, float y, float w, float h, int flags, BNDwidgetState state, - int iconid, const char *text, int cbegin, int cend); - -// Draw an option button with its lower left origin at (x,y) and size of (w,h), -// where flags is one or multiple flags from BNDcornerFlags and state denotes -// the widgets current UI state. -// if label is not NULL, a label will be added to the widget -// widget looks best when height is BND_WIDGET_HEIGHT -BND_EXPORT void bndOptionButton(NVGcontext *ctx, - float x, float y, float w, float h, BNDwidgetState state, - const char *label); - -// Draw a choice button with its lower left origin at (x,y) and size of (w,h), -// where flags is one or multiple flags from BNDcornerFlags and state denotes -// the widgets current UI state. -// if iconid >= 0, an icon will be added to the widget -// if label is not NULL, a label will be added to the widget -// widget looks best when height is BND_WIDGET_HEIGHT -BND_EXPORT void bndChoiceButton(NVGcontext *ctx, - float x, float y, float w, float h, int flags, BNDwidgetState state, - int iconid, const char *label); - -// Draw a color button with its lower left origin at (x,y) and size of (w,h), -// where flags is one or multiple flags from BNDcornerFlags and state denotes -// the widgets current UI state. -// widget looks best when height is BND_WIDGET_HEIGHT -BND_EXPORT void bndColorButton(NVGcontext *ctx, - float x, float y, float w, float h, int flags, NVGcolor color); - -// Draw a number field with its lower left origin at (x,y) and size of (w,h), -// where flags is one or multiple flags from BNDcornerFlags and state denotes -// the widgets current UI state. -// if label is not NULL, a label will be added to the widget -// if value is not NULL, a value will be added to the widget, along with -// a ":" separator -// widget looks best when height is BND_WIDGET_HEIGHT -BND_EXPORT void bndNumberField(NVGcontext *ctx, - float x, float y, float w, float h, int flags, BNDwidgetState state, - const char *label, const char *value); - -// Draw slider control with its lower left origin at (x,y) and size of (w,h), -// where flags is one or multiple flags from BNDcornerFlags and state denotes -// the widgets current UI state. -// progress must be in the range 0..1 and controls the size of the slider bar -// if label is not NULL, a label will be added to the widget -// if value is not NULL, a value will be added to the widget, along with -// a ":" separator -// widget looks best when height is BND_WIDGET_HEIGHT -BND_EXPORT void bndSlider(NVGcontext *ctx, - float x, float y, float w, float h, int flags, BNDwidgetState state, - float progress, const char *label, const char *value); - -// Draw scrollbar with its lower left origin at (x,y) and size of (w,h), -// where state denotes the widgets current UI state. -// offset is in the range 0..1 and controls the position of the scroll handle -// size is in the range 0..1 and controls the size of the scroll handle -// horizontal widget looks best when height is BND_SCROLLBAR_HEIGHT, -// vertical looks best when width is BND_SCROLLBAR_WIDTH -BND_EXPORT void bndScrollBar(NVGcontext *ctx, - float x, float y, float w, float h, BNDwidgetState state, - float offset, float size); - -// Draw a menu background with its lower left origin at (x,y) and size of (w,h), -// where flags is one or multiple flags from BNDcornerFlags. -BND_EXPORT void bndMenuBackground(NVGcontext *ctx, - float x, float y, float w, float h, int flags); - -// Draw a menu label with its lower left origin at (x,y) and size of (w,h). -// if iconid >= 0, an icon will be added to the widget -// if label is not NULL, a label will be added to the widget -// widget looks best when height is BND_WIDGET_HEIGHT -BND_EXPORT void bndMenuLabel(NVGcontext *ctx, - float x, float y, float w, float h, int iconid, const char *label); - -// Draw a menu item with its lower left origin at (x,y) and size of (w,h), -// where state denotes the widgets current UI state. -// if iconid >= 0, an icon will be added to the widget -// if label is not NULL, a label will be added to the widget -// widget looks best when height is BND_WIDGET_HEIGHT -BND_EXPORT void bndMenuItem(NVGcontext *ctx, - float x, float y, float w, float h, BNDwidgetState state, - int iconid, const char *label); - -// Draw a tooltip background with its lower left origin at (x,y) and size of (w,h) -BND_EXPORT void bndTooltipBackground(NVGcontext *ctx, float x, float y, float w, float h); - -// Draw a node port at the given position filled with the given color -BND_EXPORT void bndNodePort(NVGcontext *ctx, float x, float y, BNDwidgetState state, - NVGcolor color); - -// Draw a node wire originating at (x0,y0) and floating to (x1,y1), with -// a colored gradient based on the states state0 and state1: -// BND_DEFAULT: default wire color -// BND_HOVER: selected wire color -// BND_ACTIVE: dragged wire color -BND_EXPORT void bndNodeWire(NVGcontext *ctx, float x0, float y0, float x1, float y1, - BNDwidgetState state0, BNDwidgetState state1); - -// Draw a node wire originating at (x0,y0) and floating to (x1,y1), with -// a colored gradient based on the two colors color0 and color1 -BND_EXPORT void bndColoredNodeWire(NVGcontext *ctx, float x0, float y0, float x1, float y1, - NVGcolor color0, NVGcolor color1); - -// Draw a node background with its upper left origin at (x,y) and size of (w,h) -// where titleColor provides the base color for the title bar -BND_EXPORT void bndNodeBackground(NVGcontext *ctx, float x, float y, float w, float h, - BNDwidgetState state, int iconid, const char *label, NVGcolor titleColor); - -// Draw a window with the upper right and lower left splitter widgets into -// the rectangle at origin (x,y) and size (w, h) -BND_EXPORT void bndSplitterWidgets(NVGcontext *ctx, float x, float y, float w, float h); - -// Draw the join area overlay stencil into the rectangle -// at origin (x,y) and size (w,h) -// vertical is 0 or 1 and designates the arrow orientation, -// mirror is 0 or 1 and flips the arrow side -BND_EXPORT void bndJoinAreaOverlay(NVGcontext *ctx, float x, float y, float w, float h, - int vertical, int mirror); - -//////////////////////////////////////////////////////////////////////////////// - -// Estimator Functions -// ------------------- -// Use these functions to estimate sizes for widgets with your NVGcontext. - -// returns the ideal width for a label with given icon and text -BND_EXPORT float bndLabelWidth(NVGcontext *ctx, int iconid, const char *label); - -// returns the height for a label with given icon, text and width; this -// function is primarily useful in conjunction with multiline labels and textboxes -BND_EXPORT float bndLabelHeight(NVGcontext *ctx, int iconid, const char *label, - float width); - -//////////////////////////////////////////////////////////////////////////////// - -// Low Level Functions -// ------------------- -// these are part of the implementation detail and can be used to theme -// new kinds of controls in a similar fashion. - -// make color transparent using the default alpha value -BND_EXPORT NVGcolor bndTransparent(NVGcolor color); - -// offset a color by a given integer delta in the range -100 to 100 -BND_EXPORT NVGcolor bndOffsetColor(NVGcolor color, int delta); - -// assigns radius r to the four entries of array radiuses depending on whether -// the corner is marked as sharp or not; see BNDcornerFlags for possible -// flag values. -BND_EXPORT void bndSelectCorners(float *radiuses, float r, int flags); - -// computes the upper and lower gradient colors for the inner box from a widget -// theme and the widgets state. If flipActive is set and the state is -// BND_ACTIVE, the upper and lower colors will be swapped. -BND_EXPORT void bndInnerColors(NVGcolor *shade_top, NVGcolor *shade_down, - const BNDwidgetTheme *theme, BNDwidgetState state, int flipActive); - -// computes the text color for a widget label from a widget theme and the -// widgets state. -BND_EXPORT NVGcolor bndTextColor(const BNDwidgetTheme *theme, BNDwidgetState state); - -// computes the bounds of the scrollbar handle from the scrollbar size -// and the handles offset and size. -// offset is in the range 0..1 and defines the position of the scroll handle -// size is in the range 0..1 and defines the size of the scroll handle -BND_EXPORT void bndScrollHandleRect(float *x, float *y, float *w, float *h, - float offset, float size); - -// Add a rounded box path at position (x,y) with size (w,h) and a separate -// radius for each corner listed in clockwise order, so that cr0 = top left, -// cr1 = top right, cr2 = bottom right, cr3 = bottom left; -// this is a low level drawing function: the path must be stroked or filled -// to become visible. -BND_EXPORT void bndRoundedBox(NVGcontext *ctx, float x, float y, float w, float h, - float cr0, float cr1, float cr2, float cr3); - -// Draw a flat panel without any decorations at position (x,y) with size (w,h) -// and fills it with backgroundColor -BND_EXPORT void bndBackground(NVGcontext *ctx, float x, float y, float w, float h); - -// Draw a beveled border at position (x,y) with size (w,h) shaded with -// lighter and darker versions of backgroundColor -BND_EXPORT void bndBevel(NVGcontext *ctx, float x, float y, float w, float h); - -// Draw a lower inset for a rounded box at position (x,y) with size (w,h) -// that gives the impression the surface has been pushed in. -// cr2 and cr3 contain the radiuses of the bottom right and bottom left -// corners of the rounded box. -BND_EXPORT void bndBevelInset(NVGcontext *ctx, float x, float y, float w, float h, - float cr2, float cr3); - -// Draw an icon with (x,y) as its upper left coordinate; the iconid selects -// the icon from the sheet; use the BND_ICONID macro to build icon IDs. -BND_EXPORT void bndIcon(NVGcontext *ctx, float x, float y, int iconid); - -// Draw a drop shadow around the rounded box at (x,y) with size (w,h) and -// radius r, with feather as its maximum range in pixels. -// No shadow will be painted inside the rounded box. -BND_EXPORT void bndDropShadow(NVGcontext *ctx, float x, float y, float w, float h, - float r, float feather, float alpha); - -// Draw the inner part of a widget box, with a gradient from shade_top to -// shade_down. If h>w, the gradient will be horizontal instead of -// vertical. -BND_EXPORT void 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); - -// Draw the outline part of a widget box with the given color -BND_EXPORT void bndOutlineBox(NVGcontext *ctx, float x, float y, float w, float h, - float cr0, float cr1, float cr2, float cr3, NVGcolor color); - -// Draw an optional icon specified by <iconid> and an optional label with -// given alignment (BNDtextAlignment), fontsize and color within a widget box. -// if iconid is >= 0, an icon will be drawn and the labels remaining space -// will be adjusted. -// if label is not NULL, it will be drawn with the specified alignment, fontsize -// and color. -// if value is not NULL, label and value will be drawn with a ":" separator -// inbetween. -BND_EXPORT void 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); - -// Draw an optional icon specified by <iconid> and an optional label with -// given alignment (BNDtextAlignment), fontsize and color within a node title bar -// if iconid is >= 0, an icon will be drawn -// if label is not NULL, it will be drawn with the specified alignment, fontsize -// and color. -BND_EXPORT void bndNodeIconLabel(NVGcontext *ctx, float x, float y, float w, float h, - int iconid, NVGcolor color, NVGcolor shadowColor, int align, - float fontsize, const char *label); - -// Calculate the corresponding text position for given coordinates px/py -// in an iconLabel. -// See bndIconLabelCaret for more info. -BND_EXPORT int bndIconLabelTextPosition(NVGcontext *ctx, float x, float y, float w, float h, - int iconid, float fontsize, const char *label, int px, int py); - -// Draw an optional icon specified by <iconid>, an optional label and -// a caret with given fontsize and color within a widget box. -// if iconid is >= 0, an icon will be drawn and the labels remaining space -// will be adjusted. -// if label is not NULL, it will be drawn with the specified alignment, fontsize -// and color. -// cbegin must be >= 0 and <= strlen(text) and denotes the beginning of the caret -// cend must be >= cbegin and <= strlen(text) and denotes the end of the caret -// if cend < cbegin, then no caret will be drawn -BND_EXPORT void 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); - -// Draw a checkmark for an option box with the given upper left coordinates -// (ox,oy) with the specified color. -BND_EXPORT void bndCheck(NVGcontext *ctx, float ox, float oy, NVGcolor color); - -// Draw a horizontal arrow for a number field with its center at (x,y) and -// size s; if s is negative, the arrow points to the left. -BND_EXPORT void bndArrow(NVGcontext *ctx, float x, float y, float s, NVGcolor color); - -// Draw an up/down arrow for a choice box with its center at (x,y) and size s -BND_EXPORT void bndUpDownArrow(NVGcontext *ctx, float x, float y, float s, NVGcolor color); - -// Draw a node down-arrow with its tip at (x,y) and size s -BND_EXPORT void bndNodeArrowDown(NVGcontext *ctx, float x, float y, float s, NVGcolor color); - -// return the color of a node wire based on state -// BND_HOVER indicates selected state, -// BND_ACTIVE indicates dragged state -BND_EXPORT NVGcolor bndNodeWireColor(const BNDnodeTheme *theme, BNDwidgetState state); - -#ifdef __cplusplus -}; -#endif - -#endif // BLENDISH_H - -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// - -#ifdef BLENDISH_IMPLEMENTATION - -#include <memory.h> -#include <math.h> - -#ifdef _MSC_VER - #pragma warning (disable: 4996) // Switch off security warnings - #pragma warning (disable: 4100) // Switch off unreferenced formal parameter warnings - #pragma warning (disable: 4244) - #pragma warning (disable: 4305) - #ifdef __cplusplus - #define BND_INLINE inline - #else - #define BND_INLINE - #endif - -#include <float.h> - -static float bnd_fminf ( float a, float b ) -{ - return _isnan(a) ? b : ( _isnan(b) ? a : ((a < b) ? a : b)); -} - -static float bnd_fmaxf ( float a, float b ) -{ - return _isnan(a) ? b : ( _isnan(b) ? a : ((a > b) ? a : b)); -} - -static double bnd_fmin ( double a, double b ) -{ - return _isnan(a) ? b : ( _isnan(b) ? a : ((a < b) ? a : b)); -} - -static double bnd_fmax ( double a, double b ) -{ - return _isnan(a) ? b : ( _isnan(b) ? a : ((a > b) ? a : b)); -} - -#else - #define BND_INLINE inline - #define bnd_fminf(a, b) fminf(a, b) - #define bnd_fmaxf(a, b) fmaxf(a, b) - #define bnd_fmin(a, b) fmin(a, b) - #define bnd_fmax(a, b) fmax(a, b) -#endif - -//////////////////////////////////////////////////////////////////////////////// - -// default text size -#define BND_LABEL_FONT_SIZE 13 - -// default text padding in inner box -#define BND_PAD_LEFT 8 -#define BND_PAD_RIGHT 8 - -// label: value separator string -#define BND_LABEL_SEPARATOR ": " - -// alpha intensity of transparent items (0xa4) -#define BND_TRANSPARENT_ALPHA 0.643 - -// shade intensity of beveled panels -#define BND_BEVEL_SHADE 30 -// shade intensity of beveled insets -#define BND_INSET_BEVEL_SHADE 30 -// shade intensity of hovered inner boxes -#define BND_HOVER_SHADE 15 -// shade intensity of splitter bevels -#define BND_SPLITTER_SHADE 100 - -// width of icon sheet -#define BND_ICON_SHEET_WIDTH 602 -// height of icon sheet -#define BND_ICON_SHEET_HEIGHT 640 -// gridsize of icon sheet in both dimensions -#define BND_ICON_SHEET_GRID 21 -// offset of first icon tile relative to left border -#define BND_ICON_SHEET_OFFSET_X 5 -// offset of first icon tile relative to top border -#define BND_ICON_SHEET_OFFSET_Y 10 -// resolution of single icon -#define BND_ICON_SHEET_RES 16 - -// size of number field arrow -#define BND_NUMBER_ARROW_SIZE 4 - -// default text color -#define BND_COLOR_TEXT {{{ 0,0,0,1 }}} -// default highlighted text color -#define BND_COLOR_TEXT_SELECTED {{{ 1,1,1,1 }}} - -// radius of tool button -#define BND_TOOL_RADIUS 4 - -// radius of option button -#define BND_OPTION_RADIUS 4 -// width of option button checkbox -#define BND_OPTION_WIDTH 14 -// height of option button checkbox -#define BND_OPTION_HEIGHT 15 - -// radius of text field -#define BND_TEXT_RADIUS 4 - -// radius of number button -#define BND_NUMBER_RADIUS 10 - -// radius of menu popup -#define BND_MENU_RADIUS 3 -// feather of menu popup shadow -#define BND_SHADOW_FEATHER 12 -// alpha of menu popup shadow -#define BND_SHADOW_ALPHA 0.5 - -// radius of scrollbar -#define BND_SCROLLBAR_RADIUS 7 -// shade intensity of active scrollbar -#define BND_SCROLLBAR_ACTIVE_SHADE 15 - -// max glyphs for position testing -#define BND_MAX_GLYPHS 1024 - -// max rows for position testing -#define BND_MAX_ROWS 32 - -// text distance from bottom -#define BND_TEXT_PAD_DOWN 7 - -// stroke width of wire outline -#define BND_NODE_WIRE_OUTLINE_WIDTH 4 -// stroke width of wire -#define BND_NODE_WIRE_WIDTH 2 -// radius of node box -#define BND_NODE_RADIUS 8 -// feather of node title text -#define BND_NODE_TITLE_FEATHER 1 -// size of node title arrow -#define BND_NODE_ARROW_SIZE 9 - -//////////////////////////////////////////////////////////////////////////////// - -BND_INLINE float bnd_clamp(float v, float mn, float mx) { - return (v > mx)?mx:(v < mn)?mn:v; -} - -//////////////////////////////////////////////////////////////////////////////// - -// the initial theme -static BNDtheme bnd_theme = { - // backgroundColor - {{{ 0.447, 0.447, 0.447, 1.0 }}}, - // regularTheme - { - {{{ 0.098,0.098,0.098,1 }}}, // color_outline - {{{ 0.098,0.098,0.098,1 }}}, // color_item - {{{ 0.6,0.6,0.6,1 }}}, // color_inner - {{{ 0.392,0.392,0.392,1 }}}, // color_inner_selected - BND_COLOR_TEXT, // color_text - BND_COLOR_TEXT_SELECTED, // color_text_selected - 0, // shade_top - 0, // shade_down - }, - // toolTheme - { - {{{ 0.098,0.098,0.098,1 }}}, // color_outline - {{{ 0.098,0.098,0.098,1 }}}, // color_item - {{{ 0.6,0.6,0.6,1 }}}, // color_inner - {{{ 0.392,0.392,0.392,1 }}}, // color_inner_selected - BND_COLOR_TEXT, // color_text - BND_COLOR_TEXT_SELECTED, // color_text_selected - 15, // shade_top - -15, // shade_down - }, - // radioTheme - { - {{{ 0,0,0,1 }}}, // color_outline - {{{ 1,1,1,1 }}}, // color_item - {{{ 0.275,0.275,0.275,1 }}}, // color_inner - {{{ 0.337,0.502,0.761,1 }}}, // color_inner_selected - BND_COLOR_TEXT_SELECTED, // color_text - BND_COLOR_TEXT, // color_text_selected - 15, // shade_top - -15, // shade_down - }, - // textFieldTheme - { - {{{ 0.098,0.098,0.098,1 }}}, // color_outline - {{{ 0.353, 0.353, 0.353,1 }}}, // color_item - {{{ 0.6, 0.6, 0.6,1 }}}, // color_inner - {{{ 0.6, 0.6, 0.6,1 }}}, // color_inner_selected - BND_COLOR_TEXT, // color_text - BND_COLOR_TEXT_SELECTED, // color_text_selected - 0, // shade_top - 25, // shade_down - }, - // optionTheme - { - {{{ 0,0,0,1 }}}, // color_outline - {{{ 1,1,1,1 }}}, // color_item - {{{ 0.275,0.275,0.275,1 }}}, // color_inner - {{{ 0.275,0.275,0.275,1 }}}, // color_inner_selected - BND_COLOR_TEXT, // color_text - BND_COLOR_TEXT_SELECTED, // color_text_selected - 15, // shade_top - -15, // shade_down - }, - // choiceTheme - { - {{{ 0,0,0,1 }}}, // color_outline - {{{ 1,1,1,1 }}}, // color_item - {{{ 0.275,0.275,0.275,1 }}}, // color_inner - {{{ 0.275,0.275,0.275,1 }}}, // color_inner_selected - BND_COLOR_TEXT_SELECTED, // color_text - {{{ 0.8,0.8,0.8,1 }}}, // color_text_selected - 15, // shade_top - -15, // shade_down - }, - // numberFieldTheme - { - {{{ 0.098,0.098,0.098,1 }}}, // color_outline - {{{ 0.353, 0.353, 0.353,1 }}}, // color_item - {{{ 0.706, 0.706, 0.706,1 }}}, // color_inner - {{{ 0.6, 0.6, 0.6,1 }}}, // color_inner_selected - BND_COLOR_TEXT, // color_text - BND_COLOR_TEXT_SELECTED, // color_text_selected - -20, // shade_top - 0, // shade_down - }, - // sliderTheme - { - {{{ 0.098,0.098,0.098,1 }}}, // color_outline - {{{ 0.502,0.502,0.502,1 }}}, // color_item - {{{ 0.706, 0.706, 0.706,1 }}}, // color_inner - {{{ 0.6, 0.6, 0.6,1 }}}, // color_inner_selected - BND_COLOR_TEXT, // color_text - BND_COLOR_TEXT_SELECTED, // color_text_selected - -20, // shade_top - 0, // shade_down - }, - // scrollBarTheme - { - {{{ 0.196,0.196,0.196,1 }}}, // color_outline - {{{ 0.502,0.502,0.502,1 }}}, // color_item - {{{ 0.314, 0.314, 0.314,0.706 }}}, // color_inner - {{{ 0.392, 0.392, 0.392,0.706 }}}, // color_inner_selected - BND_COLOR_TEXT, // color_text - BND_COLOR_TEXT_SELECTED, // color_text_selected - 5, // shade_top - -5, // shade_down - }, - // tooltipTheme - { - {{{ 0,0,0,1 }}}, // color_outline - {{{ 0.392,0.392,0.392,1 }}}, // color_item - {{{ 0.098, 0.098, 0.098, 0.902 }}}, // color_inner - {{{ 0.176, 0.176, 0.176, 0.902 }}}, // color_inner_selected - {{{ 0.627, 0.627, 0.627, 1 }}}, // color_text - BND_COLOR_TEXT_SELECTED, // color_text_selected - 0, // shade_top - 0, // shade_down - }, - // menuTheme - { - {{{ 0,0,0,1 }}}, // color_outline - {{{ 0.392,0.392,0.392,1 }}}, // color_item - {{{ 0.098, 0.098, 0.098, 0.902 }}}, // color_inner - {{{ 0.176, 0.176, 0.176, 0.902 }}}, // color_inner_selected - {{{ 0.627, 0.627, 0.627, 1 }}}, // color_text - BND_COLOR_TEXT_SELECTED, // color_text_selected - 0, // shade_top - 0, // shade_down - }, - // menuItemTheme - { - {{{ 0,0,0,1 }}}, // color_outline - {{{ 0.675,0.675,0.675,0.502 }}}, // color_item - {{{ 0,0,0,0 }}}, // color_inner - {{{ 0.337,0.502,0.761,1 }}}, // color_inner_selected - BND_COLOR_TEXT_SELECTED, // color_text - BND_COLOR_TEXT, // color_text_selected - 38, // shade_top - 0, // shade_down - }, - // nodeTheme - { - {{{ 0.945,0.345,0,1 }}}, // nodeSelectedColor - {{{ 0,0,0,1 }}}, // wiresColor - {{{ 0.498,0.439,0.439,1 }}}, // textSelectedColor - {{{ 1,0.667,0.251,1 }}}, // activeNodeColor - {{{ 1,1,1,1 }}}, // wireSelectColor - {{{ 0.608,0.608,0.608,0.627 }}}, // nodeBackdropColor - 5, // noodleCurving - }, -}; - -//////////////////////////////////////////////////////////////////////////////// - -void bndSetTheme(BNDtheme theme) { - bnd_theme = theme; -} - -const BNDtheme *bndGetTheme() { - return &bnd_theme; -} - -// the handle to the image containing the icon sheet -static int bnd_icon_image = -1; - -void bndSetIconImage(int image) { - bnd_icon_image = image; -} - -// the handle to the UI font -static int bnd_font = -1; - -void bndSetFont(int font) { - bnd_font = font; -} - -//////////////////////////////////////////////////////////////////////////////// - -void bndLabel(NVGcontext *ctx, - float x, float y, float w, float h, int iconid, const char *label) { - bndIconLabelValue(ctx,x,y,w,h,iconid, - bnd_theme.regularTheme.textColor, BND_LEFT, - BND_LABEL_FONT_SIZE, label, NULL); -} - -void bndToolButton(NVGcontext *ctx, - float x, float y, float w, float h, int flags, BNDwidgetState state, - int iconid, const char *label) { - float cr[4]; - NVGcolor shade_top, shade_down; - - bndSelectCorners(cr, BND_TOOL_RADIUS, flags); - bndBevelInset(ctx,x,y,w,h,cr[2],cr[3]); - bndInnerColors(&shade_top, &shade_down, &bnd_theme.toolTheme, state, 1); - bndInnerBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3], shade_top, shade_down); - bndOutlineBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3], - bndTransparent(bnd_theme.toolTheme.outlineColor)); - bndIconLabelValue(ctx,x,y,w,h,iconid, - bndTextColor(&bnd_theme.toolTheme, state), BND_CENTER, - BND_LABEL_FONT_SIZE, label, NULL); -} - -void bndRadioButton(NVGcontext *ctx, - float x, float y, float w, float h, int flags, BNDwidgetState state, - int iconid, const char *label) { - float cr[4]; - NVGcolor shade_top, shade_down; - - bndSelectCorners(cr, BND_OPTION_RADIUS, flags); - bndBevelInset(ctx,x,y,w,h,cr[2],cr[3]); - bndInnerColors(&shade_top, &shade_down, &bnd_theme.radioTheme, state, 1); - bndInnerBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3], shade_top, shade_down); - bndOutlineBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3], - bndTransparent(bnd_theme.radioTheme.outlineColor)); - bndIconLabelValue(ctx,x,y,w,h,iconid, - bndTextColor(&bnd_theme.radioTheme, state), BND_CENTER, - BND_LABEL_FONT_SIZE, label, NULL); -} - -int bndTextFieldTextPosition(NVGcontext *ctx, float x, float y, float w, float h, - int iconid, const char *text, int px, int py) { - return bndIconLabelTextPosition(ctx, x, y, w, h, - iconid, BND_LABEL_FONT_SIZE, text, px, py); -} - -void bndTextField(NVGcontext *ctx, - float x, float y, float w, float h, int flags, BNDwidgetState state, - int iconid, const char *text, int cbegin, int cend) { - float cr[4]; - NVGcolor shade_top, shade_down; - - bndSelectCorners(cr, BND_TEXT_RADIUS, flags); - bndBevelInset(ctx,x,y,w,h,cr[2],cr[3]); - bndInnerColors(&shade_top, &shade_down, &bnd_theme.textFieldTheme, state, 0); - bndInnerBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3], shade_top, shade_down); - bndOutlineBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3], - bndTransparent(bnd_theme.textFieldTheme.outlineColor)); - if (state != BND_ACTIVE) { - cend = -1; - } - bndIconLabelCaret(ctx,x,y,w,h,iconid, - bndTextColor(&bnd_theme.textFieldTheme, state), BND_LABEL_FONT_SIZE, - text, bnd_theme.textFieldTheme.itemColor, cbegin, cend); -} - -void bndOptionButton(NVGcontext *ctx, - float x, float y, float w, float h, BNDwidgetState state, - const char *label) { - float ox, oy; - NVGcolor shade_top, shade_down; - - ox = x; - oy = y+h-BND_OPTION_HEIGHT-3; - - bndBevelInset(ctx,ox,oy, - BND_OPTION_WIDTH,BND_OPTION_HEIGHT, - BND_OPTION_RADIUS,BND_OPTION_RADIUS); - bndInnerColors(&shade_top, &shade_down, &bnd_theme.optionTheme, state, 1); - bndInnerBox(ctx,ox,oy, - BND_OPTION_WIDTH,BND_OPTION_HEIGHT, - BND_OPTION_RADIUS,BND_OPTION_RADIUS,BND_OPTION_RADIUS,BND_OPTION_RADIUS, - shade_top, shade_down); - bndOutlineBox(ctx,ox,oy, - BND_OPTION_WIDTH,BND_OPTION_HEIGHT, - BND_OPTION_RADIUS,BND_OPTION_RADIUS,BND_OPTION_RADIUS,BND_OPTION_RADIUS, - bndTransparent(bnd_theme.optionTheme.outlineColor)); - if (state == BND_ACTIVE) { - bndCheck(ctx,ox,oy, bndTransparent(bnd_theme.optionTheme.itemColor)); - } - bndIconLabelValue(ctx,x+12,y,w-12,h,-1, - bndTextColor(&bnd_theme.optionTheme, state), BND_LEFT, - BND_LABEL_FONT_SIZE, label, NULL); -} - -void bndChoiceButton(NVGcontext *ctx, - float x, float y, float w, float h, int flags, BNDwidgetState state, - int iconid, const char *label) { - float cr[4]; - NVGcolor shade_top, shade_down; - - bndSelectCorners(cr, BND_OPTION_RADIUS, flags); - bndBevelInset(ctx,x,y,w,h,cr[2],cr[3]); - bndInnerColors(&shade_top, &shade_down, &bnd_theme.choiceTheme, state, 1); - bndInnerBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3], shade_top, shade_down); - bndOutlineBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3], - bndTransparent(bnd_theme.choiceTheme.outlineColor)); - bndIconLabelValue(ctx,x,y,w,h,iconid, - bndTextColor(&bnd_theme.choiceTheme, state), BND_LEFT, - BND_LABEL_FONT_SIZE, label, NULL); - bndUpDownArrow(ctx,x+w-10,y+10,5, - bndTransparent(bnd_theme.choiceTheme.itemColor)); -} - -void bndColorButton(NVGcontext *ctx, - float x, float y, float w, float h, int flags, NVGcolor color) { - float cr[4]; - bndSelectCorners(cr, BND_TOOL_RADIUS, flags); - bndBevelInset(ctx,x,y,w,h,cr[2],cr[3]); - bndInnerBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3], color, color); - bndOutlineBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3], - bndTransparent(bnd_theme.toolTheme.outlineColor)); -} - -void bndNumberField(NVGcontext *ctx, - float x, float y, float w, float h, int flags, BNDwidgetState state, - const char *label, const char *value) { - float cr[4]; - NVGcolor shade_top, shade_down; - - bndSelectCorners(cr, BND_NUMBER_RADIUS, flags); - bndBevelInset(ctx,x,y,w,h,cr[2],cr[3]); - bndInnerColors(&shade_top, &shade_down, &bnd_theme.numberFieldTheme, state, 0); - bndInnerBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3], shade_top, shade_down); - bndOutlineBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3], - bndTransparent(bnd_theme.numberFieldTheme.outlineColor)); - bndIconLabelValue(ctx,x,y,w,h,-1, - bndTextColor(&bnd_theme.numberFieldTheme, state), BND_CENTER, - BND_LABEL_FONT_SIZE, label, value); - bndArrow(ctx,x+8,y+10,-BND_NUMBER_ARROW_SIZE, - bndTransparent(bnd_theme.numberFieldTheme.itemColor)); - bndArrow(ctx,x+w-8,y+10,BND_NUMBER_ARROW_SIZE, - bndTransparent(bnd_theme.numberFieldTheme.itemColor)); -} - -void bndSlider(NVGcontext *ctx, - float x, float y, float w, float h, int flags, BNDwidgetState state, - float progress, const char *label, const char *value) { - float cr[4]; - NVGcolor shade_top, shade_down; - - bndSelectCorners(cr, BND_NUMBER_RADIUS, flags); - bndBevelInset(ctx,x,y,w,h,cr[2],cr[3]); - bndInnerColors(&shade_top, &shade_down, &bnd_theme.sliderTheme, state, 0); - bndInnerBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3], shade_top, shade_down); - - if (state == BND_ACTIVE) { - shade_top = bndOffsetColor( - bnd_theme.sliderTheme.itemColor, bnd_theme.sliderTheme.shadeTop); - shade_down = bndOffsetColor( - bnd_theme.sliderTheme.itemColor, bnd_theme.sliderTheme.shadeDown); - } else { - shade_top = bndOffsetColor( - bnd_theme.sliderTheme.itemColor, bnd_theme.sliderTheme.shadeDown); - shade_down = bndOffsetColor( - bnd_theme.sliderTheme.itemColor, bnd_theme.sliderTheme.shadeTop); - } - nvgScissor(ctx,x,y,8+(w-8)*bnd_clamp(progress,0,1),h); - bndInnerBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3], shade_top, shade_down); - nvgResetScissor(ctx); - - bndOutlineBox(ctx,x,y,w,h,cr[0],cr[1],cr[2],cr[3], - bndTransparent(bnd_theme.sliderTheme.outlineColor)); - bndIconLabelValue(ctx,x,y,w,h,-1, - bndTextColor(&bnd_theme.sliderTheme, state), BND_CENTER, - BND_LABEL_FONT_SIZE, label, value); -} - -void bndScrollBar(NVGcontext *ctx, - float x, float y, float w, float h, BNDwidgetState state, - float offset, float size) { - - bndBevelInset(ctx,x,y,w,h, - BND_SCROLLBAR_RADIUS, BND_SCROLLBAR_RADIUS); - bndInnerBox(ctx,x,y,w,h, - BND_SCROLLBAR_RADIUS,BND_SCROLLBAR_RADIUS, - BND_SCROLLBAR_RADIUS,BND_SCROLLBAR_RADIUS, - bndOffsetColor( - bnd_theme.scrollBarTheme.innerColor, 3*bnd_theme.scrollBarTheme.shadeDown), - bndOffsetColor( - bnd_theme.scrollBarTheme.innerColor, 3*bnd_theme.scrollBarTheme.shadeTop)); - bndOutlineBox(ctx,x,y,w,h, - BND_SCROLLBAR_RADIUS,BND_SCROLLBAR_RADIUS, - BND_SCROLLBAR_RADIUS,BND_SCROLLBAR_RADIUS, - bndTransparent(bnd_theme.scrollBarTheme.outlineColor)); - - NVGcolor itemColor = bndOffsetColor( - bnd_theme.scrollBarTheme.itemColor, - (state == BND_ACTIVE)?BND_SCROLLBAR_ACTIVE_SHADE:0); - - bndScrollHandleRect(&x,&y,&w,&h,offset,size); - - bndInnerBox(ctx,x,y,w,h, - BND_SCROLLBAR_RADIUS,BND_SCROLLBAR_RADIUS, - BND_SCROLLBAR_RADIUS,BND_SCROLLBAR_RADIUS, - bndOffsetColor( - itemColor, 3*bnd_theme.scrollBarTheme.shadeTop), - bndOffsetColor( - itemColor, 3*bnd_theme.scrollBarTheme.shadeDown)); - bndOutlineBox(ctx,x,y,w,h, - BND_SCROLLBAR_RADIUS,BND_SCROLLBAR_RADIUS, - BND_SCROLLBAR_RADIUS,BND_SCROLLBAR_RADIUS, - bndTransparent(bnd_theme.scrollBarTheme.outlineColor)); -} - -void bndMenuBackground(NVGcontext *ctx, - float x, float y, float w, float h, int flags) { - float cr[4]; - NVGcolor shade_top, shade_down; - - bndSelectCorners(cr, BND_MENU_RADIUS, flags); - bndInnerColors(&shade_top, &shade_down, &bnd_theme.menuTheme, - BND_DEFAULT, 0); - bndInnerBox(ctx,x,y,w,h+1,cr[0],cr[1],cr[2],cr[3], shade_top, shade_down); - bndOutlineBox(ctx,x,y,w,h+1,cr[0],cr[1],cr[2],cr[3], - bndTransparent(bnd_theme.menuTheme.outlineColor)); - bndDropShadow(ctx,x,y,w,h,BND_MENU_RADIUS, - BND_SHADOW_FEATHER,BND_SHADOW_ALPHA); -} - -void bndTooltipBackground(NVGcontext *ctx, float x, float y, float w, float h) { - NVGcolor shade_top, shade_down; - - bndInnerColors(&shade_top, &shade_down, &bnd_theme.tooltipTheme, - BND_DEFAULT, 0); - bndInnerBox(ctx,x,y,w,h+1, - BND_MENU_RADIUS,BND_MENU_RADIUS,BND_MENU_RADIUS,BND_MENU_RADIUS, - shade_top, shade_down); - bndOutlineBox(ctx,x,y,w,h+1, - BND_MENU_RADIUS,BND_MENU_RADIUS,BND_MENU_RADIUS,BND_MENU_RADIUS, - bndTransparent(bnd_theme.tooltipTheme.outlineColor)); - bndDropShadow(ctx,x,y,w,h,BND_MENU_RADIUS, - BND_SHADOW_FEATHER,BND_SHADOW_ALPHA); -} - -void bndMenuLabel(NVGcontext *ctx, - float x, float y, float w, float h, int iconid, const char *label) { - bndIconLabelValue(ctx,x,y,w,h,iconid, - bnd_theme.menuTheme.textColor, BND_LEFT, - BND_LABEL_FONT_SIZE, label, NULL); -} - -void bndMenuItem(NVGcontext *ctx, - float x, float y, float w, float h, BNDwidgetState state, - int iconid, const char *label) { - if (state != BND_DEFAULT) { - bndInnerBox(ctx,x,y,w,h,0,0,0,0, - bndOffsetColor(bnd_theme.menuItemTheme.innerSelectedColor, - bnd_theme.menuItemTheme.shadeTop), - bndOffsetColor(bnd_theme.menuItemTheme.innerSelectedColor, - bnd_theme.menuItemTheme.shadeDown)); - state = BND_ACTIVE; - } - bndIconLabelValue(ctx,x,y,w,h,iconid, - bndTextColor(&bnd_theme.menuItemTheme, state), BND_LEFT, - BND_LABEL_FONT_SIZE, label, NULL); -} - -void bndNodePort(NVGcontext *ctx, float x, float y, BNDwidgetState state, - NVGcolor color) { - nvgBeginPath(ctx); - nvgCircle(ctx, x, y, BND_NODE_PORT_RADIUS); - nvgStrokeColor(ctx,bnd_theme.nodeTheme.wiresColor); - nvgStrokeWidth(ctx,1.0f); - nvgStroke(ctx); - nvgFillColor(ctx,(state != BND_DEFAULT)? - bndOffsetColor(color, BND_HOVER_SHADE):color); - nvgFill(ctx); -} - -void bndColoredNodeWire(NVGcontext *ctx, float x0, float y0, float x1, float y1, - NVGcolor color0, NVGcolor color1) { - float length = bnd_fmaxf(fabsf(x1 - x0),fabsf(y1 - y0)); - float delta = length*(float)bnd_theme.nodeTheme.noodleCurving/10.0f; - - nvgBeginPath(ctx); - nvgMoveTo(ctx, x0, y0); - nvgBezierTo(ctx, - x0 + delta, y0, - x1 - delta, y1, - x1, y1); - NVGcolor colorw = bnd_theme.nodeTheme.wiresColor; - colorw.a = (color0.a<color1.a)?color0.a:color1.a; - nvgStrokeColor(ctx, colorw); - nvgStrokeWidth(ctx, BND_NODE_WIRE_OUTLINE_WIDTH); - nvgStroke(ctx); - nvgStrokePaint(ctx, nvgLinearGradient(ctx, - x0, y0, x1, y1, - color0, - color1)); - nvgStrokeWidth(ctx,BND_NODE_WIRE_WIDTH); - nvgStroke(ctx); -} - -void bndNodeWire(NVGcontext *ctx, float x0, float y0, float x1, float y1, - BNDwidgetState state0, BNDwidgetState state1) { - bndColoredNodeWire(ctx, x0, y0, x1, y1, - bndNodeWireColor(&bnd_theme.nodeTheme, state0), - bndNodeWireColor(&bnd_theme.nodeTheme, state1)); -} - -void bndNodeBackground(NVGcontext *ctx, float x, float y, float w, float h, - BNDwidgetState state, int iconid, const char *label, NVGcolor titleColor) { - bndInnerBox(ctx,x,y,w,BND_NODE_TITLE_HEIGHT+2, - BND_NODE_RADIUS,BND_NODE_RADIUS,0,0, - bndTransparent(bndOffsetColor(titleColor, BND_BEVEL_SHADE)), - bndTransparent(titleColor)); - bndInnerBox(ctx,x,y+BND_NODE_TITLE_HEIGHT-1,w,h+2-BND_NODE_TITLE_HEIGHT, - 0,0,BND_NODE_RADIUS,BND_NODE_RADIUS, - bndTransparent(bnd_theme.nodeTheme.nodeBackdropColor), - bndTransparent(bnd_theme.nodeTheme.nodeBackdropColor)); - bndNodeIconLabel(ctx, - x+BND_NODE_ARROW_AREA_WIDTH,y, - w-BND_NODE_ARROW_AREA_WIDTH-BND_NODE_MARGIN_SIDE,BND_NODE_TITLE_HEIGHT, - iconid, bnd_theme.regularTheme.textColor, - bndOffsetColor(titleColor, BND_BEVEL_SHADE), - BND_LEFT, BND_LABEL_FONT_SIZE, label); - /*NVGcolor arrowColor;*/ - NVGcolor borderColor; - switch(state) { - default: - case BND_DEFAULT: { - borderColor = nvgRGBf(0,0,0); - /*arrowColor = bndOffsetColor(titleColor, -BND_BEVEL_SHADE);*/ - } break; - case BND_HOVER: { - borderColor = bnd_theme.nodeTheme.nodeSelectedColor; - /*arrowColor = bnd_theme.nodeTheme.nodeSelectedColor;*/ - } break; - case BND_ACTIVE: { - borderColor = bnd_theme.nodeTheme.activeNodeColor; - /*arrowColor = bnd_theme.nodeTheme.nodeSelectedColor;*/ - } break; - } - bndOutlineBox(ctx,x,y,w,h+1, - BND_NODE_RADIUS,BND_NODE_RADIUS,BND_NODE_RADIUS,BND_NODE_RADIUS, - bndTransparent(borderColor)); - /* - bndNodeArrowDown(ctx, - x + BND_NODE_MARGIN_SIDE, y + BND_NODE_TITLE_HEIGHT-4, - BND_NODE_ARROW_SIZE, arrowColor); - */ - bndDropShadow(ctx,x,y,w,h,BND_NODE_RADIUS, - BND_SHADOW_FEATHER,BND_SHADOW_ALPHA); -} - -void bndSplitterWidgets(NVGcontext *ctx, float x, float y, float w, float h) { - NVGcolor insetLight = bndTransparent( - bndOffsetColor(bnd_theme.backgroundColor, BND_SPLITTER_SHADE)); - NVGcolor insetDark = bndTransparent( - bndOffsetColor(bnd_theme.backgroundColor, -BND_SPLITTER_SHADE)); - NVGcolor inset = bndTransparent(bnd_theme.backgroundColor); - - float x2 = x+w; - float y2 = y+h; - - nvgBeginPath(ctx); - nvgMoveTo(ctx, x, y2-13); - nvgLineTo(ctx, x+13, y2); - nvgMoveTo(ctx, x, y2-9); - nvgLineTo(ctx, x+9, y2); - nvgMoveTo(ctx, x, y2-5); - nvgLineTo(ctx, x+5, y2); - - nvgMoveTo(ctx, x2-11, y); - nvgLineTo(ctx, x2, y+11); - nvgMoveTo(ctx, x2-7, y); - nvgLineTo(ctx, x2, y+7); - nvgMoveTo(ctx, x2-3, y); - nvgLineTo(ctx, x2, y+3); - - nvgStrokeColor(ctx, insetDark); - nvgStroke(ctx); - - nvgBeginPath(ctx); - nvgMoveTo(ctx, x, y2-11); - nvgLineTo(ctx, x+11, y2); - nvgMoveTo(ctx, x, y2-7); - nvgLineTo(ctx, x+7, y2); - nvgMoveTo(ctx, x, y2-3); - nvgLineTo(ctx, x+3, y2); - - nvgMoveTo(ctx, x2-13, y); - nvgLineTo(ctx, x2, y+13); - nvgMoveTo(ctx, x2-9, y); - nvgLineTo(ctx, x2, y+9); - nvgMoveTo(ctx, x2-5, y); - nvgLineTo(ctx, x2, y+5); - - nvgStrokeColor(ctx, insetLight); - nvgStroke(ctx); - - nvgBeginPath(ctx); - nvgMoveTo(ctx, x, y2-12); - nvgLineTo(ctx, x+12, y2); - nvgMoveTo(ctx, x, y2-8); - nvgLineTo(ctx, x+8, y2); - nvgMoveTo(ctx, x, y2-4); - nvgLineTo(ctx, x+4, y2); - - nvgMoveTo(ctx, x2-12, y); - nvgLineTo(ctx, x2, y+12); - nvgMoveTo(ctx, x2-8, y); - nvgLineTo(ctx, x2, y+8); - nvgMoveTo(ctx, x2-4, y); - nvgLineTo(ctx, x2, y+4); - - nvgStrokeColor(ctx, inset); - nvgStroke(ctx); -} - -void bndJoinAreaOverlay(NVGcontext *ctx, float x, float y, float w, float h, - int vertical, int mirror) { - - if (vertical) { - float u = w; - w = h; h = u; - } - - float s = (w<h)?w:h; - - float x0,y0,x1,y1; - if (mirror) { - x0 = w; - y0 = h; - x1 = 0; - y1 = 0; - s = -s; - } else { - x0 = 0; - y0 = 0; - x1 = w; - y1 = h; - } - - float yc = (y0+y1)*0.5f; - float s2 = s/2.0f; - float s4 = s/4.0f; - float s8 = s/8.0f; - float x4 = x0+s4; - - float points[][2] = { - { x0,y0 }, - { x1,y0 }, - { x1,y1 }, - { x0,y1 }, - { x0,yc+s8 }, - { x4,yc+s8 }, - { x4,yc+s4 }, - { x0+s2,yc }, - { x4,yc-s4 }, - { x4,yc-s8 }, - { x0,yc-s8 } - }; - - nvgBeginPath(ctx); - int count = sizeof(points) / (sizeof(float)*2); - nvgMoveTo(ctx,x+points[0][vertical&1],y+points[0][(vertical&1)^1]); - int i; - for (i = 1; i < count; ++i) { - nvgLineTo(ctx,x+points[i][vertical&1],y+points[i][(vertical&1)^1]); - } - - nvgFillColor(ctx, nvgRGBAf(0,0,0,0.3)); - nvgFill(ctx); -} - -//////////////////////////////////////////////////////////////////////////////// - -float bndLabelWidth(NVGcontext *ctx, int iconid, const char *label) { - int w = BND_PAD_LEFT + BND_PAD_RIGHT; - if (iconid >= 0) { - w += BND_ICON_SHEET_RES; - } - if (label && (bnd_font >= 0)) { - nvgFontFaceId(ctx, bnd_font); - nvgFontSize(ctx, BND_LABEL_FONT_SIZE); - w += nvgTextBounds(ctx, 1, 1, label, NULL, NULL); - } - return w; -} - -float bndLabelHeight(NVGcontext *ctx, int iconid, const char *label, float width) { - int h = BND_WIDGET_HEIGHT; - width -= BND_TEXT_RADIUS*2; - if (iconid >= 0) { - width -= BND_ICON_SHEET_RES; - } - if (label && (bnd_font >= 0)) { - nvgFontFaceId(ctx, bnd_font); - nvgFontSize(ctx, BND_LABEL_FONT_SIZE); - float bounds[4]; - nvgTextBoxBounds(ctx, 1, 1, width, label, NULL, bounds); - int bh = (int)(bounds[3] - bounds[1]) + BND_TEXT_PAD_DOWN; - if (bh > h) - h = bh; - } - return h; -} - -//////////////////////////////////////////////////////////////////////////////// - -void bndRoundedBox(NVGcontext *ctx, float x, float y, float w, float h, - float cr0, float cr1, float cr2, float cr3) { - float d; - - w = bnd_fmaxf(0, w); - h = bnd_fmaxf(0, h); - d = bnd_fminf(w, h); - - nvgMoveTo(ctx, x,y+h*0.5f); - nvgArcTo(ctx, x,y, x+w,y, bnd_fminf(cr0, d/2)); - nvgArcTo(ctx, x+w,y, x+w,y+h, bnd_fminf(cr1, d/2)); - nvgArcTo(ctx, x+w,y+h, x,y+h, bnd_fminf(cr2, d/2)); - nvgArcTo(ctx, x,y+h, x,y, bnd_fminf(cr3, d/2)); - nvgClosePath(ctx); -} - -NVGcolor bndTransparent(NVGcolor color) { - color.a *= BND_TRANSPARENT_ALPHA; - return color; -} - -NVGcolor bndOffsetColor(NVGcolor color, int delta) { - float offset = (float)delta / 255.0f; - return delta?( - nvgRGBAf( - bnd_clamp(color.r+offset,0,1), - bnd_clamp(color.g+offset,0,1), - bnd_clamp(color.b+offset,0,1), - color.a) - ):color; -} - -void bndBevel(NVGcontext *ctx, float x, float y, float w, float h) { - nvgStrokeWidth(ctx, 1); - - x += 0.5f; - y += 0.5f; - w -= 1; - h -= 1; - - nvgBeginPath(ctx); - nvgMoveTo(ctx, x, y+h); - nvgLineTo(ctx, x+w, y+h); - nvgLineTo(ctx, x+w, y); - nvgStrokeColor(ctx, bndTransparent( - bndOffsetColor(bnd_theme.backgroundColor, -BND_BEVEL_SHADE))); - nvgStroke(ctx); - - nvgBeginPath(ctx); - nvgMoveTo(ctx, x, y+h); - nvgLineTo(ctx, x, y); - nvgLineTo(ctx, x+w, y); - nvgStrokeColor(ctx, bndTransparent( - bndOffsetColor(bnd_theme.backgroundColor, BND_BEVEL_SHADE))); - nvgStroke(ctx); -} - -void bndBevelInset(NVGcontext *ctx, float x, float y, float w, float h, - float cr2, float cr3) { - float d; - - y -= 0.5f; - d = bnd_fminf(w, h); - cr2 = bnd_fminf(cr2, d/2); - cr3 = bnd_fminf(cr3, d/2); - - nvgBeginPath(ctx); - nvgMoveTo(ctx, x+w,y+h-cr2); - nvgArcTo(ctx, x+w,y+h, x,y+h, cr2); - nvgArcTo(ctx, x,y+h, x,y, cr3); - - NVGcolor bevelColor = bndOffsetColor(bnd_theme.backgroundColor, - BND_INSET_BEVEL_SHADE); - - nvgStrokeWidth(ctx, 1); - nvgStrokePaint(ctx, - nvgLinearGradient(ctx, - x,y+h-bnd_fmaxf(cr2,cr3)-1, - x,y+h-1, - nvgRGBAf(bevelColor.r, bevelColor.g, bevelColor.b, 0), - bevelColor)); - nvgStroke(ctx); -} - -void bndBackground(NVGcontext *ctx, float x, float y, float w, float h) { - nvgBeginPath(ctx); - nvgRect(ctx, x, y, w, h); - nvgFillColor(ctx, bnd_theme.backgroundColor); - nvgFill(ctx); -} - -void bndIcon(NVGcontext *ctx, float x, float y, int iconid) { - int ix, iy, u, v; - if (bnd_icon_image < 0) return; // no icons loaded - - ix = iconid & 0xff; - iy = (iconid>>8) & 0xff; - u = BND_ICON_SHEET_OFFSET_X + ix*BND_ICON_SHEET_GRID; - v = BND_ICON_SHEET_OFFSET_Y + iy*BND_ICON_SHEET_GRID; - - nvgBeginPath(ctx); - nvgRect(ctx,x,y,BND_ICON_SHEET_RES,BND_ICON_SHEET_RES); - nvgFillPaint(ctx, - nvgImagePattern(ctx,x-u,y-v, - BND_ICON_SHEET_WIDTH, - BND_ICON_SHEET_HEIGHT, - 0,bnd_icon_image,1)); - nvgFill(ctx); -} - -void bndDropShadow(NVGcontext *ctx, float x, float y, float w, float h, - float r, float feather, float alpha) { - - nvgBeginPath(ctx); - y += feather; - h -= feather; - - nvgMoveTo(ctx, x-feather, y-feather); - nvgLineTo(ctx, x, y-feather); - nvgLineTo(ctx, x, y+h-feather); - nvgArcTo(ctx, x,y+h,x+r,y+h,r); - nvgArcTo(ctx, x+w,y+h,x+w,y+h-r,r); - nvgLineTo(ctx, x+w, y-feather); - nvgLineTo(ctx, x+w+feather, y-feather); - nvgLineTo(ctx, x+w+feather, y+h+feather); - nvgLineTo(ctx, x-feather, y+h+feather); - nvgClosePath(ctx); - - nvgFillPaint(ctx, nvgBoxGradient(ctx, - x - feather*0.5f,y - feather*0.5f, - w + feather,h+feather, - r+feather*0.5f, - feather, - nvgRGBAf(0,0,0,alpha*alpha), - nvgRGBAf(0,0,0,0))); - nvgFill(ctx); -} - -void 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) { - nvgBeginPath(ctx); - bndRoundedBox(ctx,x+1,y+1,w-2,h-3,bnd_fmaxf(0,cr0-1), - bnd_fmaxf(0,cr1-1),bnd_fmaxf(0,cr2-1),bnd_fmaxf(0,cr3-1)); - nvgFillPaint(ctx,((h-2)>w)? - nvgLinearGradient(ctx,x,y,x+w,y,shade_top,shade_down): - nvgLinearGradient(ctx,x,y,x,y+h,shade_top,shade_down)); - nvgFill(ctx); -} - -void bndOutlineBox(NVGcontext *ctx, float x, float y, float w, float h, - float cr0, float cr1, float cr2, float cr3, NVGcolor color) { - nvgBeginPath(ctx); - bndRoundedBox(ctx,x+0.5f,y+0.5f,w-1,h-2,cr0,cr1,cr2,cr3); - nvgStrokeColor(ctx,color); - nvgStrokeWidth(ctx,1); - nvgStroke(ctx); -} - -void bndSelectCorners(float *radiuses, float r, int flags) { - radiuses[0] = (flags & BND_CORNER_TOP_LEFT)?0:r; - radiuses[1] = (flags & BND_CORNER_TOP_RIGHT)?0:r; - radiuses[2] = (flags & BND_CORNER_DOWN_RIGHT)?0:r; - radiuses[3] = (flags & BND_CORNER_DOWN_LEFT)?0:r; -} - -void bndInnerColors( - NVGcolor *shade_top, NVGcolor *shade_down, - const BNDwidgetTheme *theme, BNDwidgetState state, int flipActive) { - - switch(state) { - default: - case BND_DEFAULT: { - *shade_top = bndOffsetColor(theme->innerColor, theme->shadeTop); - *shade_down = bndOffsetColor(theme->innerColor, theme->shadeDown); - } break; - case BND_HOVER: { - NVGcolor color = bndOffsetColor(theme->innerColor, BND_HOVER_SHADE); - *shade_top = bndOffsetColor(color, theme->shadeTop); - *shade_down = bndOffsetColor(color, theme->shadeDown); - } break; - case BND_ACTIVE: { - *shade_top = bndOffsetColor(theme->innerSelectedColor, - flipActive?theme->shadeDown:theme->shadeTop); - *shade_down = bndOffsetColor(theme->innerSelectedColor, - flipActive?theme->shadeTop:theme->shadeDown); - } break; - } -} - -NVGcolor bndTextColor(const BNDwidgetTheme *theme, BNDwidgetState state) { - return (state == BND_ACTIVE)?theme->textSelectedColor:theme->textColor; -} - -void 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) { - float pleft = BND_PAD_LEFT; - if (label) { - if (iconid >= 0) { - bndIcon(ctx,x+4,y+2,iconid); - pleft += BND_ICON_SHEET_RES; - } - - if (bnd_font < 0) return; - nvgFontFaceId(ctx, bnd_font); - nvgFontSize(ctx, fontsize); - nvgBeginPath(ctx); - nvgFillColor(ctx, color); - if (value) { - float label_width = nvgTextBounds(ctx, 1, 1, label, NULL, NULL); - float sep_width = nvgTextBounds(ctx, 1, 1, - BND_LABEL_SEPARATOR, NULL, NULL); - - nvgTextAlign(ctx, NVG_ALIGN_LEFT|NVG_ALIGN_BASELINE); - x += pleft; - if (align == BND_CENTER) { - float width = label_width + sep_width - + nvgTextBounds(ctx, 1, 1, value, NULL, NULL); - x += ((w-BND_PAD_RIGHT-pleft)-width)*0.5f; - } - y += BND_WIDGET_HEIGHT-BND_TEXT_PAD_DOWN; - nvgText(ctx, x, y, label, NULL); - x += label_width; - nvgText(ctx, x, y, BND_LABEL_SEPARATOR, NULL); - x += sep_width; - nvgText(ctx, x, y, value, NULL); - } else { - nvgTextAlign(ctx, - (align==BND_LEFT)?(NVG_ALIGN_LEFT|NVG_ALIGN_BASELINE): - (NVG_ALIGN_CENTER|NVG_ALIGN_BASELINE)); - nvgTextBox(ctx,x+pleft,y+BND_WIDGET_HEIGHT-BND_TEXT_PAD_DOWN, - w-BND_PAD_RIGHT-pleft,label, NULL); - } - } else if (iconid >= 0) { - bndIcon(ctx,x+2,y+2,iconid); - } -} - -void bndNodeIconLabel(NVGcontext *ctx, float x, float y, float w, float h, - int iconid, NVGcolor color, NVGcolor shadowColor, - int align, float fontsize, const char *label) { - if (label && (bnd_font >= 0)) { - nvgFontFaceId(ctx, bnd_font); - nvgFontSize(ctx, fontsize); - nvgBeginPath(ctx); - nvgTextAlign(ctx, NVG_ALIGN_LEFT|NVG_ALIGN_BASELINE); - nvgFillColor(ctx, shadowColor); - nvgFontBlur(ctx, BND_NODE_TITLE_FEATHER); - nvgTextBox(ctx,x+1,y+h+3-BND_TEXT_PAD_DOWN, - w,label, NULL); - nvgFillColor(ctx, color); - nvgFontBlur(ctx, 0); - nvgTextBox(ctx,x,y+h+2-BND_TEXT_PAD_DOWN, - w,label, NULL); - } - if (iconid >= 0) { - bndIcon(ctx,x+w-BND_ICON_SHEET_RES,y+3,iconid); - } -} - -int bndIconLabelTextPosition(NVGcontext *ctx, float x, float y, float w, float h, - int iconid, float fontsize, const char *label, int px, int py) { - float bounds[4]; - float pleft = BND_TEXT_RADIUS; - if (!label) return -1; - if (iconid >= 0) - pleft += BND_ICON_SHEET_RES; - - if (bnd_font < 0) return -1; - - x += pleft; - y += BND_WIDGET_HEIGHT - BND_TEXT_PAD_DOWN; - - nvgFontFaceId(ctx, bnd_font); - nvgFontSize(ctx, fontsize); - nvgTextAlign(ctx, NVG_ALIGN_LEFT | NVG_ALIGN_BASELINE); - - w -= BND_TEXT_RADIUS + pleft; - - float asc, desc, lh; - static NVGtextRow rows[BND_MAX_ROWS]; - int nrows = nvgTextBreakLines( - ctx, label, NULL, w, rows, BND_MAX_ROWS); - if (nrows == 0) return 0; - nvgTextBoxBounds(ctx, x, y, w, label, NULL, bounds); - nvgTextMetrics(ctx, &asc, &desc, &lh); - - // calculate vertical position - int row = bnd_clamp((int)((float)(py - bounds[1]) / lh), 0, nrows - 1); - // search horizontal position - static NVGglyphPosition glyphs[BND_MAX_GLYPHS]; - int nglyphs = nvgTextGlyphPositions( - ctx, x, y, rows[row].start, rows[row].end + 1, glyphs, BND_MAX_GLYPHS); - int col, p = 0; - for (col = 0; col < nglyphs && glyphs[col].x < px; ++col) - p = glyphs[col].str - label; - // see if we should move one character further - if (col > 0 && col < nglyphs && glyphs[col].x - px < px - glyphs[col - 1].x) - p = glyphs[col].str - label; - return p; -} - -static void bndCaretPosition(NVGcontext *ctx, float x, float y, - float desc, float lineHeight, const char *caret, NVGtextRow *rows,int nrows, - int *cr, float *cx, float *cy) { - static NVGglyphPosition glyphs[BND_MAX_GLYPHS]; - int i,r,nglyphs; - for (r=0; r < nrows && rows[r].end < caret; ++r); - *cr = r; - *cx = x; - *cy = y-lineHeight-desc + r*lineHeight; - if (nrows == 0) return; - *cx = rows[r].minx; - nglyphs = nvgTextGlyphPositions( - ctx, x, y, rows[r].start, rows[r].end+1, glyphs, BND_MAX_GLYPHS); - for (i=0; i < nglyphs; ++i) { - *cx=glyphs[i].x; - if (glyphs[i].str == caret) break; - } -} - -void 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) { - float pleft = BND_TEXT_RADIUS; - if (!label) return; - if (iconid >= 0) { - bndIcon(ctx,x+4,y+2,iconid); - pleft += BND_ICON_SHEET_RES; - } - - if (bnd_font < 0) return; - - x+=pleft; - y+=BND_WIDGET_HEIGHT-BND_TEXT_PAD_DOWN; - - nvgFontFaceId(ctx, bnd_font); - nvgFontSize(ctx, fontsize); - nvgTextAlign(ctx, NVG_ALIGN_LEFT|NVG_ALIGN_BASELINE); - - w -= BND_TEXT_RADIUS+pleft; - - if (cend >= cbegin) { - int c0r,c1r; - float c0x,c0y,c1x,c1y; - float desc,lh; - static NVGtextRow rows[BND_MAX_ROWS]; - int nrows = nvgTextBreakLines( - ctx, label, label+cend+1, w, rows, BND_MAX_ROWS); - nvgTextMetrics(ctx, NULL, &desc, &lh); - - bndCaretPosition(ctx, x, y, desc, lh, label+cbegin, - rows, nrows, &c0r, &c0x, &c0y); - bndCaretPosition(ctx, x, y, desc, lh, label+cend, - rows, nrows, &c1r, &c1x, &c1y); - - nvgBeginPath(ctx); - if (cbegin == cend) { - nvgFillColor(ctx, nvgRGBf(0.337,0.502,0.761)); - nvgRect(ctx, c0x-1, c0y, 2, lh+1); - } else { - nvgFillColor(ctx, caretcolor); - if (c0r == c1r) { - nvgRect(ctx, c0x-1, c0y, c1x-c0x+1, lh+1); - } else { - int blk=c1r-c0r-1; - nvgRect(ctx, c0x-1, c0y, x+w-c0x+1, lh+1); - nvgRect(ctx, x, c1y, c1x-x+1, lh+1); - - if (blk) - nvgRect(ctx, x, c0y+lh, w, blk*lh+1); - } - } - nvgFill(ctx); - } - - nvgBeginPath(ctx); - nvgFillColor(ctx, color); - nvgTextBox(ctx,x,y,w,label, NULL); -} - -void bndCheck(NVGcontext *ctx, float ox, float oy, NVGcolor color) { - nvgBeginPath(ctx); - nvgStrokeWidth(ctx,2); - nvgStrokeColor(ctx,color); - nvgLineCap(ctx,NVG_BUTT); - nvgLineJoin(ctx,NVG_MITER); - nvgMoveTo(ctx,ox+4,oy+5); - nvgLineTo(ctx,ox+7,oy+8); - nvgLineTo(ctx,ox+14,oy+1); - nvgStroke(ctx); -} - -void bndArrow(NVGcontext *ctx, float x, float y, float s, NVGcolor color) { - nvgBeginPath(ctx); - nvgMoveTo(ctx,x,y); - nvgLineTo(ctx,x-s,y+s); - nvgLineTo(ctx,x-s,y-s); - nvgClosePath(ctx); - nvgFillColor(ctx,color); - nvgFill(ctx); -} - -void bndUpDownArrow(NVGcontext *ctx, float x, float y, float s, NVGcolor color) { - float w; - - nvgBeginPath(ctx); - w = 1.1f*s; - nvgMoveTo(ctx,x,y-1); - nvgLineTo(ctx,x+0.5*w,y-s-1); - nvgLineTo(ctx,x+w,y-1); - nvgClosePath(ctx); - nvgMoveTo(ctx,x,y+1); - nvgLineTo(ctx,x+0.5*w,y+s+1); - nvgLineTo(ctx,x+w,y+1); - nvgClosePath(ctx); - nvgFillColor(ctx,color); - nvgFill(ctx); -} - -void bndNodeArrowDown(NVGcontext *ctx, float x, float y, float s, NVGcolor color) { - float w; - nvgBeginPath(ctx); - w = 1.0f*s; - nvgMoveTo(ctx,x,y); - nvgLineTo(ctx,x+0.5*w,y-s); - nvgLineTo(ctx,x-0.5*w,y-s); - nvgClosePath(ctx); - nvgFillColor(ctx,color); - nvgFill(ctx); -} - -void bndScrollHandleRect(float *x, float *y, float *w, float *h, - float offset, float size) { - size = bnd_clamp(size,0,1); - offset = bnd_clamp(offset,0,1); - if ((*h) > (*w)) { - float hs = bnd_fmaxf(size*(*h), (*w)+1); - *y = (*y) + ((*h)-hs)*offset; - *h = hs; - } else { - float ws = bnd_fmaxf(size*(*w), (*h)-1); - *x = (*x) + ((*w)-ws)*offset; - *w = ws; - } -} - -NVGcolor bndNodeWireColor(const BNDnodeTheme *theme, BNDwidgetState state) { - switch(state) { - default: - case BND_DEFAULT: return nvgRGBf(0.5f,0.5f,0.5f); - case BND_HOVER: return theme->wireSelectColor; - case BND_ACTIVE: return theme->activeNodeColor; - } -} - -//////////////////////////////////////////////////////////////////////////////// - -#ifdef BND_INLINE -#undef BND_INLINE -#endif - -#endif // BLENDISH_IMPLEMENTATION diff --git a/dgl/src/oui-blendish/oui.h b/dgl/src/oui-blendish/oui.h @@ -1,2025 +0,0 @@ -/* -OUI - A minimal semi-immediate GUI handling & layouting library - -Copyright (c) 2014 Leonard Ritter <leonard.ritter@duangle.com> - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - */ - -#ifndef _OUI_H_ -#define _OUI_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* -Revision 4 (2014-12-17) - -OUI (short for "Open UI", spoken like the french "oui" for "yes") is a -platform agnostic single-header C library for layouting GUI elements and -handling related user input. Together with a set of widget drawing and logic -routines it can be used to build complex user interfaces. - -OUI is a semi-immediate GUI. Widget declarations are persistent for the duration -of the setup and evaluation, but do not need to be kept around longer than one -frame. - -OUI has no widget types; instead, it provides only one kind of element, "Items", -which can be tailored to the application by the user and expanded with custom -buffers and event handlers to behave as containers, buttons, sliders, radio -buttons, and so on. - -OUI also does not draw anything; Instead it provides a set of functions to -iterate and query the layouted items in order to allow client code to render -each widget with its current state using a preferred graphics library. - -See example.cpp in the repository for a full usage example. - -A basic setup for OUI usage in C looks like this: -================================================= - -// a header for each widget -typedef struct Data { - int type; - UIhandler handler; -} Data; - -/// global event dispatch -void ui_handler(int item, UIevent event) { - Data *data = (Data *)uiGetHandle(item); - if (data && data->handler) { - data->handler(item, event); - } -} - -void app_main(...) { - UIcontext *context = uiCreateContext(4096, 1<<20); - uiMakeCurrent(context); - uiSetHandler(ui_handler); - - while (app_running()) { - // update position of mouse cursor; the ui can also be updated - // from received events. - uiSetCursor(app_get_mouse_x(), app_get_mouse_y()); - - // update button state - for (int i = 0; i < 3; ++i) - uiSetButton(i, app_get_button_state(i)); - - // you can also send keys and scroll events; see example.cpp for more - - // -------------- - // this section does not have to be regenerated on frame; a good - // policy is to invalidate it on events, as this usually alters - // structure and layout. - - // begin new UI declarations - uiBeginLayout(); - - // - UI setup code goes here - - app_setup_ui(); - - // layout UI - uiEndLayout(); - - // -------------- - - // draw UI, starting with the first item, index 0 - app_draw_ui(render_context,0); - - // update states and fire handlers - uiProcess(get_time_ms()); - } - - uiDestroyContext(context); -} - -Here's an example setup for a checkbox control: -=============================================== - -typedef struct CheckBoxData { - Data head; - const char *label; - bool *checked; -} CheckBoxData; - -// called when the item is clicked (see checkbox()) -void app_checkbox_handler(int item, UIevent event) { - // retrieve custom data (see checkbox()) - CheckBoxData *data = (CheckBoxData *)uiGetHandle(item); - - switch(event) { - default: break; - case UI_BUTTON0_DOWN: { - // toggle value - *data->checked = !(*data->checked); - } break; - } -} - -// creates a checkbox control for a pointer to a boolean -int checkbox(const char *label, bool *checked) { - - // create new ui item - int item = uiItem(); - - // set minimum size of wiget; horizontal size is dynamic, vertical is fixed - uiSetSize(item, 0, APP_WIDGET_HEIGHT); - - // store some custom data with the checkbox that we use for rendering - // and value changes. - CheckBoxData *data = (CheckBoxData *)uiAllocHandle(item, sizeof(CheckBoxData)); - - // assign a custom typeid to the data so the renderer knows how to - // render this control, and our event handler - data->head.type = APP_WIDGET_CHECKBOX; - data->head.handler = app_checkbox_handler; - data->label = label; - data->checked = checked; - - // set to fire as soon as the left button is - // pressed; UI_BUTTON0_HOT_UP is also a popular alternative. - uiSetEvents(item, UI_BUTTON0_DOWN); - - return item; -} - -A simple recursive drawing routine can look like this: -====================================================== - -void app_draw_ui(AppRenderContext *ctx, int item) { - // retrieve custom data and cast it to Data; we assume the first member - // of every widget data item to be a Data field. - Data *head = (Data *)uiGetHandle(item); - - // if a handle is set, this is a specialized widget - if (head) { - // get the widgets absolute rectangle - UIrect rect = uiGetRect(item); - - switch(head->type) { - default: break; - case APP_WIDGET_LABEL: { - // ... - } break; - case APP_WIDGET_BUTTON: { - // ... - } break; - case APP_WIDGET_CHECKBOX: { - // cast to the full data type - CheckBoxData *data = (CheckBoxData*)head; - - // get the widgets current state - int state = uiGetState(item); - - // if the value is set, the state is always active - if (*data->checked) - state = UI_ACTIVE; - - // draw the checkbox - app_draw_checkbox(ctx, rect, state, data->label); - } break; - } - } - - // iterate through all children and draw - int kid = uiFirstChild(item); - while (kid != -1) { - app_draw_ui(ctx, kid); - kid = uiNextSibling(kid); - } -} - -Layouting items works like this: -================================ - -void layout_window(int w, int h) { - // create root item; the first item always has index 0 - int parent = uiItem(); - // assign fixed size - uiSetSize(parent, w, h); - - // create column box and use as new parent - parent = uiInsert(parent, uiItem()); - // configure as column - uiSetBox(parent, UI_COLUMN); - // span horizontally, attach to top - uiSetLayout(parent, UI_HFILL | UI_TOP); - - // add a label - we're assuming custom control functions to exist - int item = uiInsert(parent, label("Hello World")); - // set a fixed height for the label - uiSetSize(item, 0, APP_WIDGET_HEIGHT); - // span the label horizontally - uiSetLayout(item, UI_HFILL); - - static bool checked = false; - - // add a checkbox to the same parent as item; this is faster than - // calling uiInsert on the same parent repeatedly. - item = uiAppend(item, checkbox("Checked:", &checked)); - // set a fixed height for the checkbox - uiSetSize(item, 0, APP_WIDGET_HEIGHT); - // span the checkbox in the same way as the label - uiSetLayout(item, UI_HFILL); -} - - - - */ - -// you can override this from the outside to pick -// the export level you need -#ifndef OUI_EXPORT -#define OUI_EXPORT -#endif - -// limits - -enum { - // maximum size in bytes of a single data buffer passed to uiAllocData(). - UI_MAX_DATASIZE = 4096, - // maximum depth of nested containers - UI_MAX_DEPTH = 64, - // maximum number of buffered input events - UI_MAX_INPUT_EVENTS = 64, - // consecutive click threshold in ms - UI_CLICK_THRESHOLD = 250, -}; - -typedef unsigned int UIuint; - -// opaque UI context -typedef struct UIcontext UIcontext; - -// item states as returned by uiGetState() - -typedef enum UIitemState { - // the item is inactive - UI_COLD = 0, - // the item is inactive, but the cursor is hovering over this item - UI_HOT = 1, - // the item is toggled, activated, focused (depends on item kind) - UI_ACTIVE = 2, - // the item is unresponsive - UI_FROZEN = 3, -} UIitemState; - -// container flags to pass to uiSetBox() -typedef enum UIboxFlags { - // flex-direction (bit 0+1) - - // left to right - UI_ROW = 0x002, - // top to bottom - UI_COLUMN = 0x003, - - // model (bit 1) - - // free layout - UI_LAYOUT = 0x000, - // flex model - UI_FLEX = 0x002, - - // flex-wrap (bit 2) - - // single-line - UI_NOWRAP = 0x000, - // multi-line, wrap left to right - UI_WRAP = 0x004, - - - // justify-content (start, end, center, space-between) - // at start of row/column - UI_START = 0x008, - // at center of row/column - UI_MIDDLE = 0x000, - // at end of row/column - UI_END = 0x010, - // insert spacing to stretch across whole row/column - UI_JUSTIFY = 0x018, - - // align-items - // can be implemented by putting a flex container in a layout container, - // then using UI_TOP, UI_DOWN, UI_VFILL, UI_VCENTER, etc. - // FILL is equivalent to stretch/grow - - // align-content (start, end, center, stretch) - // can be implemented by putting a flex container in a layout container, - // then using UI_TOP, UI_DOWN, UI_VFILL, UI_VCENTER, etc. - // FILL is equivalent to stretch; space-between is not supported. -} UIboxFlags; - -// child layout flags to pass to uiSetLayout() -typedef enum UIlayoutFlags { - // attachments (bit 5-8) - // fully valid when parent uses UI_LAYOUT model - // partially valid when in UI_FLEX model - - // anchor to left item or left side of parent - UI_LEFT = 0x020, - // anchor to top item or top side of parent - UI_TOP = 0x040, - // anchor to right item or right side of parent - UI_RIGHT = 0x080, - // anchor to bottom item or bottom side of parent - UI_DOWN = 0x100, - // anchor to both left and right item or parent borders - UI_HFILL = 0x0a0, - // anchor to both top and bottom item or parent borders - UI_VFILL = 0x140, - // center horizontally, with left margin as offset - UI_HCENTER = 0x000, - // center vertically, with top margin as offset - UI_VCENTER = 0x000, - // center in both directions, with left/top margin as offset - UI_CENTER = 0x000, - // anchor to all four directions - UI_FILL = 0x1e0, - // when wrapping, put this element on a new line - // wrapping layout code auto-inserts UI_BREAK flags, - // drawing routines can read them with uiGetLayout() - UI_BREAK = 0x200 -} UIlayoutFlags; - -// event flags -typedef enum UIevent { - // on button 0 down - UI_BUTTON0_DOWN = 0x0400, - // on button 0 up - // when this event has a handler, uiGetState() will return UI_ACTIVE as - // long as button 0 is down. - UI_BUTTON0_UP = 0x0800, - // on button 0 up while item is hovered - // when this event has a handler, uiGetState() will return UI_ACTIVE - // when the cursor is hovering the items rectangle; this is the - // behavior expected for buttons. - UI_BUTTON0_HOT_UP = 0x1000, - // item is being captured (button 0 constantly pressed); - // when this event has a handler, uiGetState() will return UI_ACTIVE as - // long as button 0 is down. - UI_BUTTON0_CAPTURE = 0x2000, - // on button 2 down (right mouse button, usually triggers context menu) - UI_BUTTON2_DOWN = 0x4000, - // item has received a scrollwheel event - // the accumulated wheel offset can be queried with uiGetScroll() - UI_SCROLL = 0x8000, - // item is focused and has received a key-down event - // the respective key can be queried using uiGetKey() and uiGetModifier() - UI_KEY_DOWN = 0x10000, - // item is focused and has received a key-up event - // the respective key can be queried using uiGetKey() and uiGetModifier() - UI_KEY_UP = 0x20000, - // item is focused and has received a character event - // the respective character can be queried using uiGetKey() - UI_CHAR = 0x40000, -} UIevent; - -enum { - // these bits, starting at bit 24, can be safely assigned by the - // application, e.g. as item types, other event types, drop targets, etc. - // they can be set and queried using uiSetFlags() and uiGetFlags() - UI_USERMASK = 0xff000000, - - // a special mask passed to uiFindItem() - UI_ANY = 0xffffffff, -}; - -// handler callback; event is one of UI_EVENT_* -typedef void (*UIhandler)(UIcontext* ui_context, int item, UIevent event); - -// for cursor positions, mainly -typedef struct UIvec2 { - union { - int v[2]; - struct { int x, y; }; - }; -} UIvec2; - -// layout rectangle -typedef struct UIrect { - union { - int v[4]; - struct { int x, y, w, h; }; - }; -} UIrect; - -// unless declared otherwise, all operations have the complexity O(1). - -// Context Management -// ------------------ - -// create a new UI context; call uiMakeCurrent() to make this context the -// current context. The context is managed by the client and must be released -// using uiDestroyContext() -// item_capacity is the maximum of number of items that can be declared. -// buffer_capacity is the maximum total size of bytes that can be allocated -// using uiAllocHandle(); you may pass 0 if you don't need to allocate -// handles. -// 4096 and (1<<20) are good starting values. -OUI_EXPORT UIcontext *uiCreateContext( - unsigned int item_capacity, - unsigned int buffer_capacity); - -// release the memory of an UI context created with uiCreateContext(); if the -// context is the current context, the current context will be set to NULL -OUI_EXPORT void uiDestroyContext(UIcontext *ctx); - -// User Data -OUI_EXPORT void uiSetContextHandle(UIcontext *ui_context, void *handle); -OUI_EXPORT void *uiGetContextHandle(UIcontext *ui_context); - -// Input Control -// ------------- - -// sets the current cursor position (usually belonging to a mouse) to the -// screen coordinates at (x,y) -OUI_EXPORT void uiSetCursor(UIcontext *ui_context, int x, int y); - -// returns the current cursor position in screen coordinates as set by -// uiSetCursor() -OUI_EXPORT UIvec2 uiGetCursor(UIcontext *ui_context); - -// returns the offset of the cursor relative to the last call to uiProcess() -OUI_EXPORT UIvec2 uiGetCursorDelta(UIcontext *ui_context); - -// returns the beginning point of a drag operation. -OUI_EXPORT UIvec2 uiGetCursorStart(UIcontext *ui_context); - -// returns the offset of the cursor relative to the beginning point of a drag -// operation. -OUI_EXPORT UIvec2 uiGetCursorStartDelta(UIcontext *ui_context); - -// sets a mouse or gamepad button as pressed/released -// button is in the range 0..63 and maps to an application defined input -// source. -// mod is an application defined set of flags for modifier keys -// enabled is 1 for pressed, 0 for released -OUI_EXPORT void uiSetButton(UIcontext *ui_context, unsigned int button, unsigned int mod, bool enabled); - -// returns the current state of an application dependent input button -// as set by uiSetButton(). -// the function returns 1 if the button has been set to pressed, 0 for released. -OUI_EXPORT int uiGetButton(UIcontext *ui_context, unsigned int button); - -// returns the number of chained clicks; 1 is a single click, -// 2 is a double click, etc. -OUI_EXPORT int uiGetClicks(UIcontext *ui_context); - -// sets a key as down/up; the key can be any application defined keycode -// mod is an application defined set of flags for modifier keys -// enabled is 1 for key down, 0 for key up -// all key events are being buffered until the next call to uiProcess() -OUI_EXPORT void uiSetKey(UIcontext *ui_context, unsigned int key, unsigned int mod, bool enabled); - -// sends a single character for text input; the character is usually in the -// unicode range, but can be application defined. -// all char events are being buffered until the next call to uiProcess() -OUI_EXPORT void uiSetChar(UIcontext *ui_context, unsigned int value); - -// accumulates scroll wheel offsets for the current frame -// all offsets are being accumulated until the next call to uiProcess() -OUI_EXPORT void uiSetScroll(UIcontext *ui_context, int x, int y); - -// returns the currently accumulated scroll wheel offsets for this frame -OUI_EXPORT UIvec2 uiGetScroll(UIcontext *ui_context); - - - - - -// Stages -// ------ - -// clear the item buffer; uiBeginLayout() should be called before the first -// UI declaration for this frame to avoid concatenation of the same UI multiple -// times. -// After the call, all previously declared item IDs are invalid, and all -// application dependent context data has been freed. -// uiBeginLayout() must be followed by uiEndLayout(). -OUI_EXPORT void uiBeginLayout(UIcontext *ui_context); - -// layout all added items starting from the root item 0. -// after calling uiEndLayout(), no further modifications to the item tree should -// be done until the next call to uiBeginLayout(). -// It is safe to immediately draw the items after a call to uiEndLayout(). -// this is an O(N) operation for N = number of declared items. -OUI_EXPORT void uiEndLayout(UIcontext *ui_context); - -// update the current hot item; this only needs to be called if items are kept -// for more than one frame and uiEndLayout() is not called -OUI_EXPORT void uiUpdateHotItem(UIcontext *ui_context); - -// update the internal state according to the current cursor position and -// button states, and call all registered handlers. -// timestamp is the time in milliseconds relative to the last call to uiProcess() -// and is used to estimate the threshold for double-clicks -// after calling uiProcess(), no further modifications to the item tree should -// be done until the next call to uiBeginLayout(). -// Items should be drawn before a call to uiProcess() -// this is an O(N) operation for N = number of declared items. -OUI_EXPORT void uiProcess(UIcontext *ui_context, int timestamp); - -// reset the currently stored hot/active etc. handles; this should be called when -// a re-declaration of the UI changes the item indices, to avoid state -// related glitches because item identities have changed. -OUI_EXPORT void uiClearState(UIcontext *ui_context); - -// UI Declaration -// -------------- - -// create a new UI item and return the new items ID. -OUI_EXPORT int uiItem(UIcontext *ui_context); - -// set an items state to frozen; the UI will not recurse into frozen items -// when searching for hot or active items; subsequently, frozen items and -// their child items will not cause mouse event notifications. -// The frozen state is not applied recursively; uiGetState() will report -// UI_COLD for child items. Upon encountering a frozen item, the drawing -// routine needs to handle rendering of child items appropriately. -// see example.cpp for a demonstration. -OUI_EXPORT void uiSetFrozen(UIcontext *ui_context, int item, bool enable); - -// set the application-dependent handle of an item. -// handle is an application defined 64-bit handle. If handle is NULL, the item -// will not be interactive. -OUI_EXPORT void uiSetHandle(UIcontext *ui_context, int item, void *handle); - -// allocate space for application-dependent context data and assign it -// as the handle to the item. -// The memory of the pointer is managed by the UI context and released -// upon the next call to uiBeginLayout() -OUI_EXPORT void *uiAllocHandle(UIcontext *ui_context, int item, unsigned int size); - -// set the global handler callback for interactive items. -// the handler will be called for each item whose event flags are set using -// uiSetEvents. -OUI_EXPORT void uiSetHandler(UIcontext *ui_context, UIhandler handler); - -// flags is a combination of UI_EVENT_* and designates for which events the -// handler should be called. -OUI_EXPORT void uiSetEvents(UIcontext *ui_context, int item, unsigned int flags); - -// flags is a user-defined set of flags defined by UI_USERMASK. -OUI_EXPORT void uiSetFlags(UIcontext *ui_context, int item, unsigned int flags); - -// assign an item to a container. -// an item ID of 0 refers to the root item. -// the function returns the child item ID -// if the container has already added items, the function searches -// for the last item and calls uiAppend() on it, which is an -// O(N) operation for N siblings. -// it is usually more efficient to call uiInsert() for the first child, -// then chain additional siblings using uiAppend(). -OUI_EXPORT int uiInsert(UIcontext *ui_context, int item, int child); - -// assign an item to the same container as another item -// sibling is inserted after item. -OUI_EXPORT int uiAppend(UIcontext *ui_context, int item, int sibling); - -// insert child into container item like uiInsert(), but prepend -// it to the first child item, effectively putting it in -// the background. -// it is efficient to call uiInsertBack() repeatedly -// in cases where drawing or layout order doesn't matter. -OUI_EXPORT int uiInsertBack(UIcontext *ui_context, int item, int child); - -// same as uiInsert() -OUI_EXPORT int uiInsertFront(UIcontext *ui_context, int item, int child); - -// set the size of the item; a size of 0 indicates the dimension to be -// dynamic; if the size is set, the item can not expand beyond that size. -OUI_EXPORT void uiSetSize(UIcontext *ui_context, int item, int w, int h); - -// set the anchoring behavior of the item to one or multiple UIlayoutFlags -OUI_EXPORT void uiSetLayout(UIcontext *ui_context, int item, unsigned int flags); - -// set the box model behavior of the item to one or multiple UIboxFlags -OUI_EXPORT void uiSetBox(UIcontext *ui_context, int item, unsigned int flags); - -// set the left, top, right and bottom margins of an item; when the item is -// anchored to the parent or another item, the margin controls the distance -// from the neighboring element. -OUI_EXPORT void uiSetMargins(UIcontext *ui_context, int item, short l, short t, short r, short b); - -// set item as recipient of all keyboard events; if item is -1, no item will -// be focused. -OUI_EXPORT void uiFocus(UIcontext *ui_context, int item); - -// Iteration -// --------- - -// returns the first child item of a container item. If the item is not -// a container or does not contain any items, -1 is returned. -// if item is 0, the first child item of the root item will be returned. -OUI_EXPORT int uiFirstChild(UIcontext *ui_context, int item); - -// returns an items next sibling in the list of the parent containers children. -// if item is 0 or the item is the last child item, -1 will be returned. -OUI_EXPORT int uiNextSibling(UIcontext *ui_context, int item); - -// Querying -// -------- - -// return the total number of allocated items -OUI_EXPORT int uiGetItemCount(UIcontext *ui_context); - -// return the total bytes that have been allocated by uiAllocHandle() -OUI_EXPORT unsigned int uiGetAllocSize(UIcontext *ui_context); - -// return the current state of the item. This state is only valid after -// a call to uiProcess(). -// The returned value is one of UI_COLD, UI_HOT, UI_ACTIVE, UI_FROZEN. -OUI_EXPORT UIitemState uiGetState(UIcontext *ui_context, int item); - -// return the application-dependent handle of the item as passed to uiSetHandle() -// or uiAllocHandle(). -OUI_EXPORT void *uiGetHandle(UIcontext *ui_context, int item); - -// return the item that is currently under the cursor or -1 for none -OUI_EXPORT int uiGetHotItem(UIcontext *ui_context); - -// return the item that is currently focused or -1 for none -OUI_EXPORT int uiGetFocusedItem(UIcontext *ui_context); - -// returns the topmost item containing absolute location (x,y), starting with -// item as parent, using a set of flags and masks as filter: -// if both flags and mask are UI_ANY, the first topmost item is returned. -// if mask is UI_ANY, the first topmost item matching *any* of flags is returned. -// otherwise the first item matching (item.flags & flags) == mask is returned. -// you may combine box, layout, event and user flags. -// frozen items will always be ignored. -OUI_EXPORT int uiFindItem(UIcontext *ui_context, int item, int x, int y, - unsigned int flags, unsigned int mask); - -// return the handler callback as passed to uiSetHandler() -OUI_EXPORT UIhandler uiGetHandler(UIcontext *ui_context); -// return the event flags for an item as passed to uiSetEvents() -OUI_EXPORT unsigned int uiGetEvents(UIcontext *ui_context, int item); -// return the user-defined flags for an item as passed to uiSetFlags() -OUI_EXPORT unsigned int uiGetFlags(UIcontext *ui_context, int item); - -// when handling a KEY_DOWN/KEY_UP event: the key that triggered this event -OUI_EXPORT unsigned int uiGetKey(UIcontext *ui_context); -// when handling a keyboard or mouse event: the active modifier keys -OUI_EXPORT unsigned int uiGetModifier(UIcontext *ui_context); - -// returns the items layout rectangle in absolute coordinates. If -// uiGetRect() is called before uiEndLayout(), the values of the returned -// rectangle are undefined. -OUI_EXPORT UIrect uiGetRect(UIcontext *ui_context, int item); - -// returns 1 if an items absolute rectangle contains a given coordinate -// otherwise 0 -OUI_EXPORT int uiContains(UIcontext *ui_context, int item, int x, int y); - -// return the width of the item as set by uiSetSize() -OUI_EXPORT int uiGetWidth(UIcontext *ui_context, int item); -// return the height of the item as set by uiSetSize() -OUI_EXPORT int uiGetHeight(UIcontext *ui_context, int item); - -// return the anchoring behavior as set by uiSetLayout() -OUI_EXPORT unsigned int uiGetLayout(UIcontext *ui_context, int item); -// return the box model as set by uiSetBox() -OUI_EXPORT unsigned int uiGetBox(UIcontext *ui_context, int item); - -// return the left margin of the item as set with uiSetMargins() -OUI_EXPORT short uiGetMarginLeft(UIcontext *ui_context, int item); -// return the top margin of the item as set with uiSetMargins() -OUI_EXPORT short uiGetMarginTop(UIcontext *ui_context, int item); -// return the right margin of the item as set with uiSetMargins() -OUI_EXPORT short uiGetMarginRight(UIcontext *ui_context, int item); -// return the bottom margin of the item as set with uiSetMargins() -OUI_EXPORT short uiGetMarginDown(UIcontext *ui_context, int item); - -// when uiBeginLayout() is called, the most recently declared items are retained. -// when uiEndLayout() completes, it matches the old item hierarchy to the new one -// and attempts to map old items to new items as well as possible. -// when passed an item Id from the previous frame, uiRecoverItem() returns the -// items new assumed Id, or -1 if the item could not be mapped. -// it is valid to pass -1 as item. -OUI_EXPORT int uiRecoverItem(UIcontext *ui_context, int olditem); - -// in cases where it is important to recover old state over changes in -// the view, and the built-in remapping fails, the UI declaration can manually -// remap old items to new IDs in cases where e.g. the previous item ID has been -// temporarily saved; uiRemapItem() would then be called after creating the -// new item using uiItem(). -OUI_EXPORT void uiRemapItem(UIcontext *ui_context, int olditem, int newitem); - -// returns the number if items that have been allocated in the last frame -OUI_EXPORT int uiGetLastItemCount(UIcontext *ui_context); - -#ifdef __cplusplus -}; -#endif - -#endif // _OUI_H_ - -#ifdef OUI_IMPLEMENTATION - -#include <assert.h> - -#ifdef _MSC_VER - #pragma warning (disable: 4996) // Switch off security warnings - #pragma warning (disable: 4100) // Switch off unreferenced formal parameter warnings - #pragma warning (disable: 4244) - #pragma warning (disable: 4305) - - #ifdef __cplusplus - #define UI_INLINE inline - #else - #define UI_INLINE - #endif -#else - #ifdef __clang__ - #define UI_INLINE static inline - #else - #define UI_INLINE inline - #endif -#endif - -#define UI_MAX_KIND 16 - -#define UI_ANY_BUTTON0_INPUT (UI_BUTTON0_DOWN \ - |UI_BUTTON0_UP \ - |UI_BUTTON0_HOT_UP \ - |UI_BUTTON0_CAPTURE) - -#define UI_ANY_BUTTON2_INPUT (UI_BUTTON2_DOWN) - -#define UI_ANY_MOUSE_INPUT (UI_ANY_BUTTON0_INPUT \ - |UI_ANY_BUTTON2_INPUT) - -#define UI_ANY_KEY_INPUT (UI_KEY_DOWN \ - |UI_KEY_UP \ - |UI_CHAR) - -#define UI_ANY_INPUT (UI_ANY_MOUSE_INPUT \ - |UI_ANY_KEY_INPUT) - -enum { - // extra item flags - - // bit 0-2 - UI_ITEM_BOX_MODEL_MASK = 0x000007, - // bit 0-4 - UI_ITEM_BOX_MASK = 0x00001F, - // bit 5-8 - UI_ITEM_LAYOUT_MASK = 0x0003E0, - // bit 9-18 - UI_ITEM_EVENT_MASK = 0x07FC00, - // item is frozen (bit 19) - UI_ITEM_FROZEN = 0x080000, - // item handle is pointer to data (bit 20) - UI_ITEM_DATA = 0x100000, - // item has been inserted (bit 21) - UI_ITEM_INSERTED = 0x200000, - // horizontal size has been explicitly set (bit 22) - UI_ITEM_HFIXED = 0x400000, - // vertical size has been explicitly set (bit 23) - UI_ITEM_VFIXED = 0x800000, - // bit 22-23 - UI_ITEM_FIXED_MASK = 0xC00000, - - // which flag bits will be compared - UI_ITEM_COMPARE_MASK = UI_ITEM_BOX_MODEL_MASK - | (UI_ITEM_LAYOUT_MASK & ~UI_BREAK) - | UI_ITEM_EVENT_MASK - | UI_USERMASK, -}; - -typedef struct UIitem { - // data handle - void *handle; - - // about 27 bits worth of flags - unsigned int flags; - - // index of first kid - // if old item: index of equivalent new item - int firstkid; - // index of next sibling with same parent - int nextitem; - - // margin offsets, interpretation depends on flags - // after layouting, the first two components are absolute coordinates - short margins[4]; - // size - short size[2]; -} UIitem; - -typedef enum UIstate { - UI_STATE_IDLE = 0, - UI_STATE_CAPTURE, -} UIstate; - -typedef enum UIstage { - UI_STAGE_LAYOUT = 0, - UI_STAGE_POST_LAYOUT, - UI_STAGE_PROCESS, -} UIstage; - -typedef struct UIhandleEntry { - unsigned int key; - int item; -} UIhandleEntry; - -typedef struct UIinputEvent { - unsigned int key; - unsigned int mod; - UIevent event; -} UIinputEvent; - -struct UIcontext { - unsigned int item_capacity; - unsigned int buffer_capacity; - - // handler - UIhandler handler; - // User data - void *handle; - - // button state in this frame - unsigned long long buttons; - // button state in the previous frame - unsigned long long last_buttons; - - // where the cursor was at the beginning of the active state - UIvec2 start_cursor; - // where the cursor was last frame - UIvec2 last_cursor; - // where the cursor is currently - UIvec2 cursor; - // accumulated scroll wheel offsets - UIvec2 scroll; - - int active_item; - int focus_item; - int last_hot_item; - int last_click_item; - int hot_item; - - UIstate state; - UIstage stage; - unsigned int active_key; - unsigned int active_modifier; - unsigned int active_button_modifier; - int last_timestamp; - int last_click_timestamp; - int clicks; - - int count; - int last_count; - int eventcount; - unsigned int datasize; - - UIitem *items; - unsigned char *data; - UIitem *last_items; - int *item_map; - UIinputEvent events[UI_MAX_INPUT_EVENTS]; -}; - -UI_INLINE int ui_max(int a, int b) { - return (a>b)?a:b; -} - -UI_INLINE int ui_min(int a, int b) { - return (a<b)?a:b; -} - -UI_INLINE float ui_maxf(float a, float b) { - return (a>b)?a:b; -} - -UI_INLINE float ui_minf(float a, float b) { - return (a<b)?a:b; -} - -void uiClear(UIcontext *ui_context) { - int i; - ui_context->last_count = ui_context->count; - ui_context->count = 0; - ui_context->datasize = 0; - ui_context->hot_item = -1; - // swap buffers - UIitem *items = ui_context->items; - ui_context->items = ui_context->last_items; - ui_context->last_items = items; - for (i = 0; i < ui_context->last_count; ++i) { - ui_context->item_map[i] = -1; - } -} - -static UIcontext *uiInitializeContext( - UIcontext *ctx, - unsigned int item_capacity, - unsigned int buffer_capacity) { - memset(ctx, 0, sizeof(UIcontext)); - ctx->item_capacity = item_capacity; - ctx->buffer_capacity = buffer_capacity; - ctx->stage = UI_STAGE_PROCESS; - ctx->items = (UIitem *)malloc(sizeof(UIitem) * item_capacity); - ctx->last_items = (UIitem *)malloc(sizeof(UIitem) * item_capacity); - ctx->item_map = (int *)malloc(sizeof(int) * item_capacity); - if (buffer_capacity) { - ctx->data = (unsigned char *)malloc(buffer_capacity); - } - return ctx; -} - -UIcontext *uiCreateContext( - unsigned int item_capacity, - unsigned int buffer_capacity) { - assert(item_capacity); - UIcontext *ctx = (UIcontext *)malloc(sizeof(UIcontext)); - uiInitializeContext(ctx, item_capacity, buffer_capacity); - uiClear(ctx); - uiClearState(ctx); - return ctx; -} - -void uiDestroyContext(UIcontext *ctx) { - free(ctx->items); - free(ctx->last_items); - free(ctx->item_map); - free(ctx->data); - free(ctx); -} - -void uiSetContextHandle(UIcontext *ui_context, void *handle) { - assert(ui_context); - ui_context->handle = handle; -} - -void *uiGetContextHandle(UIcontext *ui_context) { - assert(ui_context); - return ui_context->handle; -} - - -void uiSetButton(UIcontext *ui_context, unsigned int button, unsigned int mod, bool enabled) { - assert(ui_context); - unsigned long long mask = 1ull<<button; - // set new bit - ui_context->buttons = (enabled)? - (ui_context->buttons | mask): - (ui_context->buttons & ~mask); - ui_context->active_button_modifier = mod; -} - -static void uiAddInputEvent(UIcontext *ui_context, UIinputEvent event) { - assert(ui_context); - if (ui_context->eventcount == UI_MAX_INPUT_EVENTS) return; - ui_context->events[ui_context->eventcount++] = event; -} - -static void uiClearInputEvents(UIcontext *ui_context) { - assert(ui_context); - ui_context->eventcount = 0; - ui_context->scroll.x = 0; - ui_context->scroll.y = 0; -} - -void uiSetKey(UIcontext *ui_context, unsigned int key, unsigned int mod, bool enabled) { - assert(ui_context); - UIinputEvent event = { key, mod, enabled?UI_KEY_DOWN:UI_KEY_UP }; - uiAddInputEvent(ui_context, event); -} - -void uiSetChar(UIcontext *ui_context, unsigned int value) { - assert(ui_context); - UIinputEvent event = { value, 0, UI_CHAR }; - uiAddInputEvent(ui_context, event); -} - -void uiSetScroll(UIcontext *ui_context, int x, int y) { - assert(ui_context); - ui_context->scroll.x += x; - ui_context->scroll.y += y; -} - -UIvec2 uiGetScroll(UIcontext *ui_context) { - assert(ui_context); - return ui_context->scroll; -} - -int uiGetLastButton(UIcontext *ui_context, unsigned int button) { - assert(ui_context); - return (ui_context->last_buttons & (1ull<<button))?1:0; -} - -int uiGetButton(UIcontext *ui_context, unsigned int button) { - assert(ui_context); - return (ui_context->buttons & (1ull<<button))?1:0; -} - -int uiButtonPressed(UIcontext *ui_context, unsigned int button) { - assert(ui_context); - return !uiGetLastButton(ui_context, button) && uiGetButton(ui_context, button); -} - -int uiButtonReleased(UIcontext *ui_context, unsigned int button) { - assert(ui_context); - return uiGetLastButton(ui_context, button) && !uiGetButton(ui_context, button); -} - -void uiSetCursor(UIcontext *ui_context, int x, int y) { - assert(ui_context); - ui_context->cursor.x = x; - ui_context->cursor.y = y; -} - -UIvec2 uiGetCursor(UIcontext *ui_context) { - assert(ui_context); - return ui_context->cursor; -} - -UIvec2 uiGetCursorStart(UIcontext *ui_context) { - assert(ui_context); - return ui_context->start_cursor; -} - -UIvec2 uiGetCursorDelta(UIcontext *ui_context) { - assert(ui_context); - UIvec2 result = {{{ - ui_context->cursor.x - ui_context->last_cursor.x, - ui_context->cursor.y - ui_context->last_cursor.y - }}}; - return result; -} - -UIvec2 uiGetCursorStartDelta(UIcontext *ui_context) { - assert(ui_context); - UIvec2 result = {{{ - ui_context->cursor.x - ui_context->start_cursor.x, - ui_context->cursor.y - ui_context->start_cursor.y - }}}; - return result; -} - -unsigned int uiGetKey(UIcontext *ui_context) { - assert(ui_context); - return ui_context->active_key; -} - -unsigned int uiGetModifier(UIcontext *ui_context) { - assert(ui_context); - return ui_context->active_modifier; -} - -int uiGetItemCount(UIcontext *ui_context) { - assert(ui_context); - return ui_context->count; -} - -int uiGetLastItemCount(UIcontext *ui_context) { - assert(ui_context); - return ui_context->last_count; -} - -unsigned int uiGetAllocSize(UIcontext *ui_context) { - assert(ui_context); - return ui_context->datasize; -} - -UIitem *uiItemPtr(UIcontext *ui_context, int item) { - assert(ui_context && (item >= 0) && (item < ui_context->count)); - return ui_context->items + item; -} - -UIitem *uiLastItemPtr(UIcontext *ui_context, int item) { - assert(ui_context && (item >= 0) && (item < ui_context->last_count)); - return ui_context->last_items + item; -} - -int uiGetHotItem(UIcontext *ui_context) { - assert(ui_context); - return ui_context->hot_item; -} - -void uiFocus(UIcontext *ui_context, int item) { - assert(ui_context && (item >= -1) && (item < ui_context->count)); - assert(ui_context->stage != UI_STAGE_LAYOUT); - ui_context->focus_item = item; -} - -static void uiValidateStateItems(UIcontext *ui_context) { - assert(ui_context); - ui_context->last_hot_item = uiRecoverItem(ui_context, ui_context->last_hot_item); - ui_context->active_item = uiRecoverItem(ui_context, ui_context->active_item); - ui_context->focus_item = uiRecoverItem(ui_context, ui_context->focus_item); - ui_context->last_click_item = uiRecoverItem(ui_context, ui_context->last_click_item); -} - -int uiGetFocusedItem(UIcontext *ui_context) { - assert(ui_context); - return ui_context->focus_item; -} - - -void uiBeginLayout(UIcontext *ui_context) { - assert(ui_context); - assert(ui_context->stage == UI_STAGE_PROCESS); // must run uiEndLayout(), uiProcess() first - uiClear(ui_context); - ui_context->stage = UI_STAGE_LAYOUT; -} - -void uiClearState(UIcontext *ui_context) { - assert(ui_context); - ui_context->last_hot_item = -1; - ui_context->active_item = -1; - ui_context->focus_item = -1; - ui_context->last_click_item = -1; -} - -int uiItem(UIcontext *ui_context) { - assert(ui_context); - assert(ui_context->stage == UI_STAGE_LAYOUT); // must run between uiBeginLayout() and uiEndLayout() - assert(ui_context->count < (int)ui_context->item_capacity); - int idx = ui_context->count++; - UIitem *item = uiItemPtr(ui_context, idx); - memset(item, 0, sizeof(UIitem)); - item->firstkid = -1; - item->nextitem = -1; - return idx; -} - -void uiNotifyItem(UIcontext *ui_context, int item, UIevent event) { - assert(ui_context); - if (!ui_context->handler) - return; - assert((event & UI_ITEM_EVENT_MASK) == event); - UIitem *pitem = uiItemPtr(ui_context, item); - if (pitem->flags & event) { - ui_context->handler(ui_context, item, event); - } -} - -UI_INLINE int uiLastChild(UIcontext *ui_context, int item) { - item = uiFirstChild(ui_context, item); - if (item < 0) - return -1; - while (true) { - int nextitem = uiNextSibling(ui_context, item); - if (nextitem < 0) - return item; - item = nextitem; - } -} - -int uiAppend(UIcontext *ui_context, int item, int sibling) { - assert(sibling > 0); - UIitem *pitem = uiItemPtr(ui_context, item); - UIitem *psibling = uiItemPtr(ui_context, sibling); - assert(!(psibling->flags & UI_ITEM_INSERTED)); - psibling->nextitem = pitem->nextitem; - psibling->flags |= UI_ITEM_INSERTED; - pitem->nextitem = sibling; - return sibling; -} - -int uiInsert(UIcontext *ui_context, int item, int child) { - assert(child > 0); - UIitem *pparent = uiItemPtr(ui_context, item); - UIitem *pchild = uiItemPtr(ui_context, child); - assert(!(pchild->flags & UI_ITEM_INSERTED)); - if (pparent->firstkid < 0) { - pparent->firstkid = child; - pchild->flags |= UI_ITEM_INSERTED; - } else { - uiAppend(ui_context, uiLastChild(ui_context, item), child); - } - return child; -} - -int uiInsertFront(UIcontext *ui_context, int item, int child) { - return uiInsert(ui_context, item, child); -} - -int uiInsertBack(UIcontext *ui_context, int item, int child) { - assert(child > 0); - UIitem *pparent = uiItemPtr(ui_context, item); - UIitem *pchild = uiItemPtr(ui_context, child); - assert(!(pchild->flags & UI_ITEM_INSERTED)); - pchild->nextitem = pparent->firstkid; - pparent->firstkid = child; - pchild->flags |= UI_ITEM_INSERTED; - return child; -} - -void uiSetFrozen(UIcontext *ui_context, int item, bool enable) { - UIitem *pitem = uiItemPtr(ui_context, item); - if (enable) - pitem->flags |= UI_ITEM_FROZEN; - else - pitem->flags &= ~UI_ITEM_FROZEN; -} - -void uiSetSize(UIcontext *ui_context, int item, int w, int h) { - UIitem *pitem = uiItemPtr(ui_context, item); - pitem->size[0] = w; - pitem->size[1] = h; - if (!w) - pitem->flags &= ~UI_ITEM_HFIXED; - else - pitem->flags |= UI_ITEM_HFIXED; - if (!h) - pitem->flags &= ~UI_ITEM_VFIXED; - else - pitem->flags |= UI_ITEM_VFIXED; -} - -int uiGetWidth(UIcontext *ui_context, int item) { - return uiItemPtr(ui_context, item)->size[0]; -} - -int uiGetHeight(UIcontext *ui_context, int item) { - return uiItemPtr(ui_context, item)->size[1]; -} - -void uiSetLayout(UIcontext *ui_context, int item, unsigned int flags) { - UIitem *pitem = uiItemPtr(ui_context, item); - assert((flags & UI_ITEM_LAYOUT_MASK) == (unsigned int)flags); - pitem->flags &= ~UI_ITEM_LAYOUT_MASK; - pitem->flags |= flags & UI_ITEM_LAYOUT_MASK; -} - -unsigned int uiGetLayout(UIcontext *ui_context, int item) { - return uiItemPtr(ui_context, item)->flags & UI_ITEM_LAYOUT_MASK; -} - -void uiSetBox(UIcontext *ui_context, int item, unsigned int flags) { - UIitem *pitem = uiItemPtr(ui_context, item); - assert((flags & UI_ITEM_BOX_MASK) == (unsigned int)flags); - pitem->flags &= ~UI_ITEM_BOX_MASK; - pitem->flags |= flags & UI_ITEM_BOX_MASK; -} - -unsigned int uiGetBox(UIcontext *ui_context, int item) { - return uiItemPtr(ui_context, item)->flags & UI_ITEM_BOX_MASK; -} - -void uiSetMargins(UIcontext *ui_context, int item, short l, short t, short r, short b) { - UIitem *pitem = uiItemPtr(ui_context, item); - pitem->margins[0] = l; - pitem->margins[1] = t; - pitem->margins[2] = r; - pitem->margins[3] = b; -} - -short uiGetMarginLeft(UIcontext *ui_context, int item) { - return uiItemPtr(ui_context, item)->margins[0]; -} -short uiGetMarginTop(UIcontext *ui_context, int item) { - return uiItemPtr(ui_context, item)->margins[1]; -} -short uiGetMarginRight(UIcontext *ui_context, int item) { - return uiItemPtr(ui_context, item)->margins[2]; -} -short uiGetMarginDown(UIcontext *ui_context, int item) { - return uiItemPtr(ui_context, item)->margins[3]; -} - -// compute bounding box of all items super-imposed -UI_INLINE void uiComputeImposedSize(UIcontext *ui_context, UIitem *pitem, int dim) { - int wdim = dim+2; - // largest size is required size - short need_size = 0; - int kid = pitem->firstkid; - while (kid >= 0) { - UIitem *pkid = uiItemPtr(ui_context, kid); - - // width = start margin + calculated width + end margin - int kidsize = pkid->margins[dim] + pkid->size[dim] + pkid->margins[wdim]; - need_size = ui_max(need_size, kidsize); - kid = uiNextSibling(ui_context, kid); - } - pitem->size[dim] = need_size; -} - -// compute bounding box of all items stacked -UI_INLINE void uiComputeStackedSize(UIcontext *ui_context, UIitem *pitem, int dim) { - int wdim = dim+2; - short need_size = 0; - int kid = pitem->firstkid; - while (kid >= 0) { - UIitem *pkid = uiItemPtr(ui_context, kid); - // width += start margin + calculated width + end margin - need_size += pkid->margins[dim] + pkid->size[dim] + pkid->margins[wdim]; - kid = uiNextSibling(ui_context, kid); - } - pitem->size[dim] = need_size; -} - -// compute bounding box of all items stacked, repeating when breaking -UI_INLINE void uiComputeWrappedStackedSize(UIcontext *ui_context, UIitem *pitem, int dim) { - int wdim = dim+2; - - short need_size = 0; - short need_size2 = 0; - int kid = pitem->firstkid; - while (kid >= 0) { - UIitem *pkid = uiItemPtr(ui_context, kid); - - // if next position moved back, we assume a new line - if (pkid->flags & UI_BREAK) { - need_size2 = ui_max(need_size2, need_size); - // newline - need_size = 0; - } - - // width = start margin + calculated width + end margin - need_size += pkid->margins[dim] + pkid->size[dim] + pkid->margins[wdim]; - kid = uiNextSibling(ui_context, kid); - } - pitem->size[dim] = ui_max(need_size2, need_size); -} - -// compute bounding box of all items stacked + wrapped -UI_INLINE void uiComputeWrappedSize(UIcontext *ui_context, UIitem *pitem, int dim) { - int wdim = dim+2; - - short need_size = 0; - short need_size2 = 0; - int kid = pitem->firstkid; - while (kid >= 0) { - UIitem *pkid = uiItemPtr(ui_context, kid); - - // if next position moved back, we assume a new line - if (pkid->flags & UI_BREAK) { - need_size2 += need_size; - // newline - need_size = 0; - } - - // width = start margin + calculated width + end margin - int kidsize = pkid->margins[dim] + pkid->size[dim] + pkid->margins[wdim]; - need_size = ui_max(need_size, kidsize); - kid = uiNextSibling(ui_context, kid); - } - pitem->size[dim] = need_size2 + need_size; -} - -static void uiComputeSize(UIcontext *ui_context, int item, int dim) { - UIitem *pitem = uiItemPtr(ui_context, item); - - // children expand the size - int kid = pitem->firstkid; - while (kid >= 0) { - uiComputeSize(ui_context, kid, dim); - kid = uiNextSibling(ui_context, kid); - } - - if (pitem->size[dim]) - return; - switch(pitem->flags & UI_ITEM_BOX_MODEL_MASK) { - case UI_COLUMN|UI_WRAP: { - // flex model - if (dim) // direction - uiComputeStackedSize(ui_context, pitem, 1); - else - uiComputeImposedSize(ui_context, pitem, 0); - } break; - case UI_ROW|UI_WRAP: { - // flex model - if (!dim) // direction - uiComputeWrappedStackedSize(ui_context, pitem, 0); - else - uiComputeWrappedSize(ui_context, pitem, 1); - } break; - case UI_COLUMN: - case UI_ROW: { - // flex model - if ((pitem->flags & 1) == (unsigned int)dim) // direction - uiComputeStackedSize(ui_context, pitem, dim); - else - uiComputeImposedSize(ui_context, pitem, dim); - } break; - default: { - // layout model - uiComputeImposedSize(ui_context, pitem, dim); - } break; - } -} - -// stack all items according to their alignment -UI_INLINE void uiArrangeStacked(UIcontext *ui_context, UIitem *pitem, int dim, bool wrap) { - int wdim = dim+2; - - short space = pitem->size[dim]; - float max_x2 = (float)pitem->margins[dim] + (float)space; - - int start_kid = pitem->firstkid; - while (start_kid >= 0) { - short used = 0; - - int count = 0; // count of fillers - int squeezed_count = 0; // count of squeezable elements - int total = 0; - bool hardbreak = false; - // first pass: count items that need to be expanded, - // and the space that is used - int kid = start_kid; - int end_kid = -1; - while (kid >= 0) { - UIitem *pkid = uiItemPtr(ui_context, kid); - int flags = (pkid->flags & UI_ITEM_LAYOUT_MASK) >> dim; - int fflags = (pkid->flags & UI_ITEM_FIXED_MASK) >> dim; - short extend = used; - if ((flags & UI_HFILL) == UI_HFILL) { // grow - count++; - extend += pkid->margins[dim] + pkid->margins[wdim]; - } else { - if ((fflags & UI_ITEM_HFIXED) != UI_ITEM_HFIXED) - squeezed_count++; - extend += pkid->margins[dim] + pkid->size[dim] + pkid->margins[wdim]; - } - // wrap on end of line or manual flag - if (wrap && (total && ((extend > space) || (pkid->flags & UI_BREAK)))) { - end_kid = kid; - hardbreak = ((pkid->flags & UI_BREAK) == UI_BREAK); - // add marker for subsequent queries - pkid->flags |= UI_BREAK; - break; - } else { - used = extend; - kid = uiNextSibling(ui_context, kid); - } - total++; - } - - int extra_space = space - used; - float filler = 0.0f; - float spacer = 0.0f; - float extra_margin = 0.0f; - float eater = 0.0f; - - if (extra_space > 0) { - if (count) { - filler = (float)extra_space / (float)count; - } else if (total) { - switch(pitem->flags & UI_JUSTIFY) { - default: { - extra_margin = extra_space / 2.0f; - } break; - case UI_JUSTIFY: { - // justify when not wrapping or not in last line, - // or not manually breaking - if (!wrap || ((end_kid != -1) && !hardbreak)) - spacer = (float)extra_space / (float)(total-1); - } break; - case UI_START: { - } break; - case UI_END: { - extra_margin = extra_space; - } break; - } - } - } else if (!wrap && (extra_space < 0)) { - eater = (float)extra_space / (float)squeezed_count; - } - - // distribute width among items - float x = (float)pitem->margins[dim]; - float x1; - // second pass: distribute and rescale - kid = start_kid; - while (kid != end_kid) { - short ix0,ix1; - UIitem *pkid = uiItemPtr(ui_context, kid); - int flags = (pkid->flags & UI_ITEM_LAYOUT_MASK) >> dim; - int fflags = (pkid->flags & UI_ITEM_FIXED_MASK) >> dim; - - x += (float)pkid->margins[dim] + extra_margin; - if ((flags & UI_HFILL) == UI_HFILL) { // grow - x1 = x+filler; - } else if ((fflags & UI_ITEM_HFIXED) == UI_ITEM_HFIXED) { - x1 = x+(float)pkid->size[dim]; - } else { - // squeeze - x1 = x+ui_maxf(0.0f,(float)pkid->size[dim]+eater); - } - ix0 = (short)x; - if (wrap) - ix1 = (short)ui_minf(max_x2-(float)pkid->margins[wdim], x1); - else - ix1 = (short)x1; - pkid->margins[dim] = ix0; - pkid->size[dim] = ix1-ix0; - x = x1 + (float)pkid->margins[wdim]; - - kid = uiNextSibling(ui_context, kid); - extra_margin = spacer; - } - - start_kid = end_kid; - } -} - -// superimpose all items according to their alignment -UI_INLINE void uiArrangeImposedRange(UIcontext *ui_context, UIitem *pitem, int dim, - int start_kid, int end_kid, short offset, short space) { - int wdim = dim+2; - - int kid = start_kid; - while (kid != end_kid) { - UIitem *pkid = uiItemPtr(ui_context, kid); - - int flags = (pkid->flags & UI_ITEM_LAYOUT_MASK) >> dim; - - switch(flags & UI_HFILL) { - default: break; - case UI_HCENTER: { - pkid->margins[dim] += (space-pkid->size[dim])/2 - pkid->margins[wdim]; - } break; - case UI_RIGHT: { - pkid->margins[dim] = space-pkid->size[dim]-pkid->margins[wdim]; - } break; - case UI_HFILL: { - pkid->size[dim] = ui_max(0,space-pkid->margins[dim]-pkid->margins[wdim]); - } break; - } - pkid->margins[dim] += offset; - - kid = uiNextSibling(ui_context, kid); - } -} - -UI_INLINE void uiArrangeImposed(UIcontext *ui_context, UIitem *pitem, int dim) { - uiArrangeImposedRange(ui_context, pitem, dim, pitem->firstkid, -1, pitem->margins[dim], pitem->size[dim]); -} - -// superimpose all items according to their alignment, -// squeeze items that expand the available space -UI_INLINE void uiArrangeImposedSqueezedRange(UIcontext *ui_context, UIitem *pitem, int dim, - int start_kid, int end_kid, short offset, short space) { - int wdim = dim+2; - - int kid = start_kid; - while (kid != end_kid) { - UIitem *pkid = uiItemPtr(ui_context, kid); - - int flags = (pkid->flags & UI_ITEM_LAYOUT_MASK) >> dim; - - short min_size = ui_max(0,space-pkid->margins[dim]-pkid->margins[wdim]); - switch(flags & UI_HFILL) { - default: { - pkid->size[dim] = ui_min(pkid->size[dim], min_size); - } break; - case UI_HCENTER: { - pkid->size[dim] = ui_min(pkid->size[dim], min_size); - pkid->margins[dim] += (space-pkid->size[dim])/2 - pkid->margins[wdim]; - } break; - case UI_RIGHT: { - pkid->size[dim] = ui_min(pkid->size[dim], min_size); - pkid->margins[dim] = space-pkid->size[dim]-pkid->margins[wdim]; - } break; - case UI_HFILL: { - pkid->size[dim] = min_size; - } break; - } - pkid->margins[dim] += offset; - - kid = uiNextSibling(ui_context, kid); - } -} - -UI_INLINE void uiArrangeImposedSqueezed(UIcontext *ui_context, UIitem *pitem, int dim) { - uiArrangeImposedSqueezedRange(ui_context, pitem, dim, pitem->firstkid, -1, pitem->margins[dim], pitem->size[dim]); -} - -// superimpose all items according to their alignment -UI_INLINE short uiArrangeWrappedImposedSqueezed(UIcontext *ui_context, UIitem *pitem, int dim) { - int wdim = dim+2; - - short offset = pitem->margins[dim]; - - short need_size = 0; - int kid = pitem->firstkid; - int start_kid = kid; - while (kid >= 0) { - UIitem *pkid = uiItemPtr(ui_context, kid); - - if (pkid->flags & UI_BREAK) { - uiArrangeImposedSqueezedRange(ui_context, pitem, dim, start_kid, kid, offset, need_size); - offset += need_size; - start_kid = kid; - // newline - need_size = 0; - } - - // width = start margin + calculated width + end margin - int kidsize = pkid->margins[dim] + pkid->size[dim] + pkid->margins[wdim]; - need_size = ui_max(need_size, kidsize); - kid = uiNextSibling(ui_context, kid); - } - - uiArrangeImposedSqueezedRange(ui_context, pitem, dim, start_kid, -1, offset, need_size); - offset += need_size; - return offset; -} - -static void uiArrange(UIcontext *ui_context, int item, int dim) { - UIitem *pitem = uiItemPtr(ui_context, item); - - switch(pitem->flags & UI_ITEM_BOX_MODEL_MASK) { - case UI_COLUMN|UI_WRAP: { - // flex model, wrapping - if (dim) { // direction - uiArrangeStacked(ui_context, pitem, 1, true); - // this retroactive resize will not effect parent widths - short offset = uiArrangeWrappedImposedSqueezed(ui_context, pitem, 0); - pitem->size[0] = offset - pitem->margins[0]; - } - } break; - case UI_ROW|UI_WRAP: { - // flex model, wrapping - if (!dim) { // direction - uiArrangeStacked(ui_context, pitem, 0, true); - } else { - uiArrangeWrappedImposedSqueezed(ui_context, pitem, 1); - } - } break; - case UI_COLUMN: - case UI_ROW: { - // flex model - if ((pitem->flags & 1) == (unsigned int)dim) // direction - uiArrangeStacked(ui_context, pitem, dim, false); - else - uiArrangeImposedSqueezed(ui_context, pitem, dim); - } break; - default: { - // layout model - uiArrangeImposed(ui_context, pitem, dim); - } break; - } - - int kid = uiFirstChild(ui_context, item); - while (kid >= 0) { - uiArrange(ui_context, kid, dim); - kid = uiNextSibling(ui_context, kid); - } -} - -UI_INLINE bool uiCompareItems(UIcontext *ui_context, UIitem *item1, UIitem *item2) { - return ((item1->flags & UI_ITEM_COMPARE_MASK) == (item2->flags & UI_ITEM_COMPARE_MASK)); - -} - -static bool uiMapItems(UIcontext *ui_context, int item1, int item2) { - UIitem *pitem1 = uiLastItemPtr(ui_context, item1); - if (item2 == -1) { - return false; - } - - UIitem *pitem2 = uiItemPtr(ui_context, item2); - if (!uiCompareItems(ui_context, pitem1, pitem2)) { - return false; - } - - int count = 0; - int failed = 0; - int kid1 = pitem1->firstkid; - int kid2 = pitem2->firstkid; - while (kid1 != -1) { - UIitem *pkid1 = uiLastItemPtr(ui_context, kid1); - count++; - if (!uiMapItems(ui_context, kid1, kid2)) { - failed = count; - break; - } - kid1 = pkid1->nextitem; - if (kid2 != -1) { - kid2 = uiItemPtr(ui_context, kid2)->nextitem; - } - } - - if (count && (failed == 1)) { - return false; - } - - ui_context->item_map[item1] = item2; - return true; -} - -int uiRecoverItem(UIcontext *ui_context, int olditem) { - assert(ui_context); - assert((olditem >= -1) && (olditem < ui_context->last_count)); - if (olditem == -1) return -1; - return ui_context->item_map[olditem]; -} - -void uiRemapItem(UIcontext *ui_context, int olditem, int newitem) { - assert(ui_context); - assert((olditem >= 0) && (olditem < ui_context->last_count)); - assert((newitem >= -1) && (newitem < ui_context->count)); - ui_context->item_map[olditem] = newitem; -} - -void uiEndLayout(UIcontext *ui_context) { - assert(ui_context); - assert(ui_context->stage == UI_STAGE_LAYOUT); // must run uiBeginLayout() first - - if (ui_context->count) { - uiComputeSize(ui_context, 0, 0); - uiArrange(ui_context, 0, 0); - uiComputeSize(ui_context, 0, 1); - uiArrange(ui_context, 0, 1); - - if (ui_context->last_count) { - // map old item id to new item id - uiMapItems(ui_context, 0, 0); - } - } - - uiValidateStateItems(ui_context); - if (ui_context->count) { - // drawing routines may require this to be set already - uiUpdateHotItem(ui_context); - } - - ui_context->stage = UI_STAGE_POST_LAYOUT; -} - -UIrect uiGetRect(UIcontext *ui_context, int item) { - UIitem *pitem = uiItemPtr(ui_context, item); - UIrect rc = {{{ - pitem->margins[0], pitem->margins[1], - pitem->size[0], pitem->size[1] - }}}; - return rc; -} - -int uiFirstChild(UIcontext *ui_context, int item) { - return uiItemPtr(ui_context, item)->firstkid; -} - -int uiNextSibling(UIcontext *ui_context, int item) { - return uiItemPtr(ui_context, item)->nextitem; -} - -void *uiAllocHandle(UIcontext *ui_context, int item, unsigned int size) { - assert((size > 0) && (size < UI_MAX_DATASIZE)); - UIitem *pitem = uiItemPtr(ui_context, item); - assert(pitem->handle == NULL); - assert((ui_context->datasize+size) <= ui_context->buffer_capacity); - pitem->handle = ui_context->data + ui_context->datasize; - pitem->flags |= UI_ITEM_DATA; - ui_context->datasize += size; - return pitem->handle; -} - -void uiSetHandle(UIcontext *ui_context, int item, void *handle) { - UIitem *pitem = uiItemPtr(ui_context, item); - assert(pitem->handle == NULL); - pitem->handle = handle; -} - -void *uiGetHandle(UIcontext *ui_context, int item) { - return uiItemPtr(ui_context, item)->handle; -} - -void uiSetHandler(UIcontext *ui_context, UIhandler handler) { - assert(ui_context); - ui_context->handler = handler; -} - -UIhandler uiGetHandler(UIcontext *ui_context) { - assert(ui_context); - return ui_context->handler; -} - -void uiSetEvents(UIcontext *ui_context, int item, unsigned int flags) { - UIitem *pitem = uiItemPtr(ui_context, item); - pitem->flags &= ~UI_ITEM_EVENT_MASK; - pitem->flags |= flags & UI_ITEM_EVENT_MASK; -} - -unsigned int uiGetEvents(UIcontext *ui_context, int item) { - return uiItemPtr(ui_context, item)->flags & UI_ITEM_EVENT_MASK; -} - -void uiSetFlags(UIcontext *ui_context, int item, unsigned int flags) { - UIitem *pitem = uiItemPtr(ui_context, item); - pitem->flags &= ~UI_USERMASK; - pitem->flags |= flags & UI_USERMASK; -} - -unsigned int uiGetFlags(UIcontext *ui_context, int item) { - return uiItemPtr(ui_context, item)->flags & UI_USERMASK; -} - -int uiContains(UIcontext *ui_context, int item, int x, int y) { - UIrect rect = uiGetRect(ui_context, item); - x -= rect.x; - y -= rect.y; - if ((x>=0) - && (y>=0) - && (x<rect.w) - && (y<rect.h)) return 1; - return 0; -} - -int uiFindItem(UIcontext *ui_context, int item, int x, int y, unsigned int flags, unsigned int mask) { - UIitem *pitem = uiItemPtr(ui_context, item); - if (pitem->flags & UI_ITEM_FROZEN) return -1; - if (uiContains(ui_context, item, x, y)) { - int best_hit = -1; - int kid = uiFirstChild(ui_context, item); - while (kid >= 0) { - int hit = uiFindItem(ui_context, kid, x, y, flags, mask); - if (hit >= 0) { - best_hit = hit; - } - kid = uiNextSibling(ui_context, kid); - } - if (best_hit >= 0) { - return best_hit; - } - if (((mask == UI_ANY) && ((flags == UI_ANY) - || (pitem->flags & flags))) - || ((pitem->flags & flags) == mask)) { - return item; - } - } - return -1; -} - -void uiUpdateHotItem(UIcontext *ui_context) { - assert(ui_context); - if (!ui_context->count) return; - ui_context->hot_item = uiFindItem(ui_context, 0, - ui_context->cursor.x, ui_context->cursor.y, - UI_ANY_MOUSE_INPUT, UI_ANY); -} - -int uiGetClicks(UIcontext *ui_context) { - return ui_context->clicks; -} - -void uiProcess(UIcontext *ui_context, int timestamp) { - assert(ui_context); - - assert(ui_context->stage != UI_STAGE_LAYOUT); // must run uiBeginLayout(), uiEndLayout() first - - if (ui_context->stage == UI_STAGE_PROCESS) { - uiUpdateHotItem(ui_context); - } - ui_context->stage = UI_STAGE_PROCESS; - - if (!ui_context->count) { - uiClearInputEvents(ui_context); - return; - } - - int hot_item = ui_context->last_hot_item; - int active_item = ui_context->active_item; - int focus_item = ui_context->focus_item; - - // send all keyboard events - if (focus_item >= 0) { - int i; - for (i = 0; i < ui_context->eventcount; ++i) { - ui_context->active_key = ui_context->events[i].key; - ui_context->active_modifier = ui_context->events[i].mod; - uiNotifyItem(ui_context, focus_item, ui_context->events[i].event); - } - } else { - ui_context->focus_item = -1; - } - if (ui_context->scroll.x || ui_context->scroll.y) { - int scroll_item = uiFindItem(ui_context, 0, - ui_context->cursor.x, ui_context->cursor.y, - UI_SCROLL, UI_ANY); - if (scroll_item >= 0) { - uiNotifyItem(ui_context, scroll_item, UI_SCROLL); - } - } - - uiClearInputEvents(ui_context); - - int hot = ui_context->hot_item; - - switch(ui_context->state) { - default: - case UI_STATE_IDLE: { - ui_context->start_cursor = ui_context->cursor; - if (uiGetButton(ui_context, 0)) { - hot_item = -1; - active_item = hot; - - if (active_item != focus_item) { - focus_item = -1; - ui_context->focus_item = -1; - } - - if (active_item >= 0) { - if ( - ((timestamp - ui_context->last_click_timestamp) > UI_CLICK_THRESHOLD) - || (ui_context->last_click_item != active_item)) { - ui_context->clicks = 0; - } - ui_context->clicks++; - - ui_context->last_click_timestamp = timestamp; - ui_context->last_click_item = active_item; - ui_context->active_modifier = ui_context->active_button_modifier; - uiNotifyItem(ui_context, active_item, UI_BUTTON0_DOWN); - } - ui_context->state = UI_STATE_CAPTURE; - } else if (uiGetButton(ui_context, 2) && !uiGetLastButton(ui_context, 2)) { - hot_item = -1; - hot = uiFindItem(ui_context, 0, ui_context->cursor.x, ui_context->cursor.y, - UI_BUTTON2_DOWN, UI_ANY); - if (hot >= 0) { - ui_context->active_modifier = ui_context->active_button_modifier; - uiNotifyItem(ui_context, hot, UI_BUTTON2_DOWN); - } - } else { - hot_item = hot; - } - } break; - case UI_STATE_CAPTURE: { - if (!uiGetButton(ui_context, 0)) { - if (active_item >= 0) { - ui_context->active_modifier = ui_context->active_button_modifier; - uiNotifyItem(ui_context, active_item, UI_BUTTON0_UP); - if (active_item == hot) { - uiNotifyItem(ui_context, active_item, UI_BUTTON0_HOT_UP); - } - } - active_item = -1; - ui_context->state = UI_STATE_IDLE; - } else { - if (active_item >= 0) { - ui_context->active_modifier = ui_context->active_button_modifier; - uiNotifyItem(ui_context, active_item, UI_BUTTON0_CAPTURE); - } - if (hot == active_item) - hot_item = hot; - else - hot_item = -1; - } - } break; - } - - ui_context->last_cursor = ui_context->cursor; - ui_context->last_hot_item = hot_item; - ui_context->active_item = active_item; - - ui_context->last_timestamp = timestamp; - ui_context->last_buttons = ui_context->buttons; -} - -static int uiIsActive(UIcontext *ui_context, int item) { - assert(ui_context); - return ui_context->active_item == item; -} - -static int uiIsHot(UIcontext *ui_context, int item) { - assert(ui_context); - return ui_context->last_hot_item == item; -} - -static int uiIsFocused(UIcontext *ui_context, int item) { - assert(ui_context); - return ui_context->focus_item == item; -} - -UIitemState uiGetState(UIcontext *ui_context, int item) { - UIitem *pitem = uiItemPtr(ui_context, item); - if (pitem->flags & UI_ITEM_FROZEN) return UI_FROZEN; - if (uiIsFocused(ui_context, item)) { - if (pitem->flags & (UI_KEY_DOWN|UI_CHAR|UI_KEY_UP)) return UI_ACTIVE; - } - if (uiIsActive(ui_context, item)) { - if (pitem->flags & (UI_BUTTON0_CAPTURE|UI_BUTTON0_UP)) return UI_ACTIVE; - if ((pitem->flags & UI_BUTTON0_HOT_UP) - && uiIsHot(ui_context, item)) return UI_ACTIVE; - return UI_COLD; - } else if (uiIsHot(ui_context, item)) { - return UI_HOT; - } - return UI_COLD; -} - -#endif // OUI_IMPLEMENTATION