Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/7thFACTOR/horus_ui
Browse files Browse the repository at this point in the history
# Conflicts:
#	themes/psd/rotaryslider_mark.psd
  • Loading branch information
nekitu committed Sep 29, 2018
2 parents f9d0ef7 + cecd948 commit db2eb6f
Show file tree
Hide file tree
Showing 20 changed files with 184 additions and 184 deletions.
2 changes: 1 addition & 1 deletion examples/widget_showroom/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1304,7 +1304,7 @@ struct MyViewHandler : hui::ViewHandler
hui::label("Far Plane:", HAlignType::Right);
hui::nextColumn();
hui::pushPadding(0);
hui::getContextSettings().sliderAllowAnyDragDirection = true;
hui::getContextSettings().sliderDragDirection = hui::SliderDragDirection::Any;
hui::getContextSettings().sliderInvertVerticalDragAmount = false;

hui::comboSliderFloat(slideVal, 1);
Expand Down
16 changes: 12 additions & 4 deletions include/horus.h
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,14 @@ enum class TextCachePruneMode
Frames
};

/// Slider drag direction modes
enum class SliderDragDirection
{
Any,
HorizontalOnly,
VerticalOnly
};

/// Docking modes for the view panes
enum class DockType
{
Expand Down Expand Up @@ -1410,8 +1418,8 @@ struct ContextSettings
f32 textCachePruneMaxFrames = 500; /// after this frame count, if a unicode text is not accessed, it's discarded from cache, textCachePruneMode must be Frames
f32 textCachePruneIntervalSec = 5; /// after each interval has passed, the pruning of unused texts is executed, will delete the texts that were not used for the last textCachePruneMaxTimeMs or textCachePruneMaxFrames, depending on the prune mode
u32 defaultAtlasSize = 4096; /// default atlas textures size in pixels
bool sliderAllowAnyDragDirection = false; /// allows to change slider value from any direction drag, vertical or horizontal
bool sliderInvertVerticalDragAmount = false;
SliderDragDirection sliderDragDirection = SliderDragDirection::Any; /// allows to change slider value from any direction drag, vertical or horizontal
bool sliderInvertVerticalDragAmount = false; /// if true and vertical sliding allowed, it will invert the drag amount
f32 dragStartDistance = 3; /// the max distance after which a dragging operation starts to occur when mouse down and moved, in pixels
};

Expand Down Expand Up @@ -2076,7 +2084,7 @@ HORUS_API bool sliderFloat(f32 minVal, f32 maxVal, f32& value, bool useStep = fa

HORUS_API bool comboSliderFloat(f32& value, f32 stepsPerPixel = 1.0f, f32 arrowStep = 1.0f);
HORUS_API bool comboSliderFloatRanged(f32& value, f32 minVal, f32 maxVal, f32 stepsPerPixel = 1.0f, f32 arrowStep = 1.0f);
HORUS_API bool rotarySliderFloat(const char* label, f32& value, f32 minVal, f32 maxVal, f32 step);
HORUS_API bool rotarySliderFloat(const char* label, f32& value, f32 minVal, f32 maxVal, f32 step, bool twoSide = false);

/// Draw a image widget
/// \param image the image to draw
Expand Down Expand Up @@ -2426,7 +2434,7 @@ HORUS_API void drawTextInBox(const char* text, const Rect& rect, HAlignType hori
HORUS_API Point getTextSize(const char* text);

///
HORUS_API void drawImage(Image image, const Point& position);
HORUS_API void drawImage(Image image, const Point& position, f32 scale);

///
HORUS_API void drawStretchedImage(Image image, const Rect& rect);
Expand Down
3 changes: 2 additions & 1 deletion src/check_widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ bool check(const char* labelText, bool checked)
}, ctx->globalScale);
}

const f32 bulletTextSpacing = ctx->theme->settings.checkBulletTextSpacing * ctx->globalScale;
const f32 bulletTextSpacingParam = checkBodyElem.currentStyle->getParameterValue("bulletTextSpacing", 5);
const f32 bulletTextSpacing = bulletTextSpacingParam * ctx->globalScale;

ctx->renderer->cmdSetColor(checkBodyElemState->textColor);
ctx->renderer->cmdSetFont(checkBodyElemState->font);
Expand Down
31 changes: 19 additions & 12 deletions src/comboslider_widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "ui_context.h"
#include "util.h"
#include <algorithm>
#include <string.h> // memset

namespace hui
{
Expand Down Expand Up @@ -48,22 +49,23 @@ bool comboSliderInternal(f32& value, f32 minVal, f32 maxVal, bool useRange, f32
bool arrowHoveredLeft = false;
bool arrowHoveredRight = false;

if (isHovered() && ctx->event.mouse.point.x <= ctx->widget.rect.x + ctx->theme->settings.comboSliderArrowClickSize)
if (isHovered() && ctx->event.mouse.point.x <= ctx->widget.rect.x + leftArrowElem.normalState().image->width)
{
arrowHoveredLeft = true;
}
else if (isHovered() && ctx->event.mouse.point.x >= ctx->widget.rect.right() - ctx->theme->settings.comboSliderArrowClickSize)
else if (isHovered() && ctx->event.mouse.point.x >= ctx->widget.rect.right() - rightArrowElem.normalState().image->width)
{
arrowHoveredRight = true;
}

if (isClicked() && ctx->event.mouse.point.x <= ctx->widget.rect.x + ctx->theme->settings.comboSliderArrowClickSize)
if (isClicked()
&& ctx->event.mouse.point.x <= ctx->widget.rect.x + leftArrowElem.normalState().image->width)
{
value -= arrowStep;
arrowStepped = true;
if (useRange) wasModified = clampValue(value, minVal, maxVal);
}
else if (isClicked() && ctx->event.mouse.point.x >= ctx->widget.rect.right() - ctx->theme->settings.comboSliderArrowClickSize)
else if (isClicked() && ctx->event.mouse.point.x >= ctx->widget.rect.right() - rightArrowElem.normalState().image->width)
{
value += arrowStep;
arrowStepped = true;
Expand Down Expand Up @@ -134,16 +136,20 @@ bool comboSliderInternal(f32& value, f32 minVal, f32 maxVal, bool useRange, f32
dragLastMousePos = ctx->event.mouse.point;
f32 deltaValue = 0;

if (ctx->settings.sliderAllowAnyDragDirection)
switch (ctx->settings.sliderDragDirection)
{
case SliderDragDirection::Any:
if (fabsf(delta.x) > fabsf(delta.y))
deltaValue = delta.x;
else
deltaValue = ctx->settings.sliderInvertVerticalDragAmount ? delta.y : -delta.y;
}
else
{
break;
case SliderDragDirection::VerticalOnly:
deltaValue = delta.y;
break;
case SliderDragDirection::HorizontalOnly:
deltaValue = delta.x;
break;
}

if (useRange)
Expand All @@ -161,7 +167,8 @@ bool comboSliderInternal(f32& value, f32 minVal, f32 maxVal, bool useRange, f32

if (ctx->event.type == InputEvent::Type::MouseUp
&& (dragging || mouseWasDown)
&& ctx->isActiveLayer()&&comboSliderWidgetId == ctx->currentWidgetId)
&& ctx->isActiveLayer()
&& comboSliderWidgetId == ctx->currentWidgetId)
{
dragging = false;
mouseWasDown = false;
Expand Down Expand Up @@ -225,7 +232,7 @@ bool comboSliderInternal(f32& value, f32 minVal, f32 maxVal, bool useRange, f32

ctx->renderer->cmdDrawImage(leftArrowElemState->image,
{
ctx->widget.rect.x + bodyElemState->border + (ctx->theme->settings.comboSliderArrowSideSpacing + (ctx->widget.pressed ? 1.0f : 0.0f)) * ctx->globalScale,
ctx->widget.rect.x + bodyElemState->border + (ctx->widget.pressed ? 1.0f : 0.0f) * ctx->globalScale,
ctx->widget.rect.top() + arrowY,
leftArrowElemState->image->rect.width * ctx->globalScale,
leftArrowElemState->image->rect.height * ctx->globalScale
Expand All @@ -238,7 +245,7 @@ bool comboSliderInternal(f32& value, f32 minVal, f32 maxVal, bool useRange, f32

ctx->renderer->cmdDrawImage(rightArrowElemState->image,
{
ctx->widget.rect.right() - bodyElemState->border - (ctx->theme->settings.comboSliderArrowSideSpacing + rightArrowElemState->image->rect.width - (ctx->widget.pressed ? 1.0f : 0.0f)) * ctx->globalScale,
ctx->widget.rect.right() - bodyElemState->border - (rightArrowElemState->image->rect.width - (ctx->widget.pressed ? 1.0f : 0.0f)) * ctx->globalScale,
ctx->widget.rect.top() + arrowY,
rightArrowElemState->image->rect.width * ctx->globalScale,
rightArrowElemState->image->rect.height * ctx->globalScale
Expand All @@ -265,4 +272,4 @@ bool comboSliderFloatRanged(f32& value, f32 minVal, f32 maxVal, f32 stepsPerPixe
return comboSliderInternal(value, minVal, maxVal, true, stepsPerPixel, arrowStep);
}

}
}
4 changes: 2 additions & 2 deletions src/custom_widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,10 @@ void drawTextInBox(const char* text, const Rect& rect, HAlignType horizontalAlig
horizontalAlign, verticalAlign);
}

void drawImage(Image image, const Point& position)
void drawImage(Image image, const Point& position, f32 scale)
{
UiImage* img = (UiImage*)image;
ctx->renderer->cmdDrawImage(img, Point(position.x, position.y));
ctx->renderer->cmdDrawImage(img, Point(position.x, position.y), scale);
}

void drawStretchedImage(Image image, const Rect& rect)
Expand Down
193 changes: 96 additions & 97 deletions src/horus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1379,116 +1379,115 @@ Theme loadTheme(const char* filename)
{
auto widgetName = widgetNames[i];
auto widget = widgets.get(widgetName.c_str(), Json::Value());

WidgetType wtype = getWidgetTypeFromName(widgetName);
WidgetType widgetType = getWidgetTypeFromName(widgetName);
auto widgetMemberNames = widget.getMemberNames();
auto styles = widget.get("styles", Json::Value());

// read all widgets
for (size_t j = 0; j < widgetMemberNames.size(); j++)
auto readElements = [theme, themePath, widgetType](const std::string& styleName, Json::Value& parentElem)
{
auto elemName = widgetMemberNames[j];
auto elem = widget.get(elemName.c_str(), Json::Value());
auto elemType = getWidgetElementFromName(elemName);
auto width = elem.get("width", 0).asInt();
auto height = elem.get("height", 0).asInt();

// if its a builtin widget
if (wtype != WidgetType::None)
auto elementNames = parentElem.getMemberNames();
// read all widget elements
for (size_t l = 0; l < elementNames.size(); l++)
{
// if we have styles for this widget
if (elemName == "styles")
{
auto styles = widget.get("styles", Json::Value());
printf("Loading %d %s styles\n", styles.getMemberNames().size(), widgetName.c_str());
auto styleNames = styles.getMemberNames();

// read all styles
for (size_t k = 0; k < styleNames.size(); k++)
{
auto styleName = styleNames[k];
auto styleElem = styles.get(styleName.c_str(), Json::Value());
printf("\tStyle '%s'\n", styleName.c_str());
auto elementNames = styleElem.getMemberNames();

// read all widget elements
for (size_t l = 0; l < elementNames.size(); l++)
{
auto elemType = getWidgetElementFromName(elementNames[l]);
auto elem = styleElem.get(elementNames[j], Json::Value());
width = elem.get("width", width).asInt();
height = elem.get("height", height).asInt();
auto elemStates = elem.getMemberNames();

for (size_t m = 0; m < elemStates.size(); m++)
{
auto& stateName = elemStates[m];
auto elemState = elem.get(stateName, Json::Value());
auto widgetStateType = WidgetStateType::None;

if (stateName == "normal")
widgetStateType = WidgetStateType::Normal;
else if (stateName == "pressed")
widgetStateType = WidgetStateType::Pressed;
else if (stateName == "hovered")
widgetStateType = WidgetStateType::Hovered;
else if (stateName == "disabled")
widgetStateType = WidgetStateType::Disabled;

if (widgetStateType != WidgetStateType::None)
setThemeElement(theme, themePath, styleName.c_str(), wtype, elemType, widgetStateType, elemState, width, height);
else
theme->elements[(u32)elemType].styles[styleName].parameters[stateName] = elemState.asFloat();
}
}
}
}
else
auto elemType = getWidgetElementFromName(elementNames[l]);
auto elem = parentElem.get(elementNames[l], Json::Value());
auto width = elem.get("width", 0).asInt();
auto height = elem.get("height", 0).asInt();
auto elemStates = elem.getMemberNames();

for (size_t m = 0; m < elemStates.size(); m++)
{
setThemeElement(theme, themePath, "default", wtype, elemType, WidgetStateType::Normal, elem.get("normal", Json::Value()), width, height);
setThemeElement(theme, themePath, "default", wtype, elemType, WidgetStateType::Hovered, elem.get("hovered", Json::Value()), width, height);
setThemeElement(theme, themePath, "default", wtype, elemType, WidgetStateType::Pressed, elem.get("pressed", Json::Value()), width, height);
setThemeElement(theme, themePath, "default", wtype, elemType, WidgetStateType::Focused, elem.get("focused", Json::Value()), width, height);
setThemeElement(theme, themePath, "default", wtype, elemType, WidgetStateType::Disabled, elem.get("disabled", Json::Value()), width, height);
auto& stateName = elemStates[m];
auto elemState = elem.get(stateName, Json::Value());
auto widgetStateType = WidgetStateType::None;

if (stateName == "normal")
widgetStateType = WidgetStateType::Normal;
else if (stateName == "focused")
widgetStateType = WidgetStateType::Focused;
else if (stateName == "pressed")
widgetStateType = WidgetStateType::Pressed;
else if (stateName == "hovered")
widgetStateType = WidgetStateType::Hovered;
else if (stateName == "disabled")
widgetStateType = WidgetStateType::Disabled;

if (widgetStateType != WidgetStateType::None)
setThemeElement(theme, themePath, styleName.c_str(), widgetType, elemType, widgetStateType, elemState, width, height);
else if (elemState.isDouble())
theme->elements[(u32)elemType].styles[styleName].parameters[stateName] = elemState.asFloat();
else if (elemState.isInt())
theme->elements[(u32)elemType].styles[styleName].parameters[stateName] = elemState.asInt();
}
}
else
};

auto readUserElements = [theme, themePath, widgetName](const std::string& styleName, Json::Value& parentElem)
{
auto elementNames = parentElem.getMemberNames();

// read all widget elements
for (size_t l = 0; l < elementNames.size(); l++)
{
// if we have styles for this widget
if (elemName == "styles")
auto& elementName = elementNames[l];
auto elem = parentElem.get(elementName, Json::Value());
auto width = elem.get("width", 0).asInt();
auto height = elem.get("height", 0).asInt();
auto elemStates = elem.getMemberNames();

for (size_t m = 0; m < elemStates.size(); m++)
{
auto styles = widget.get("styles", Json::Value());
auto styleNames = styles.getMemberNames();

for (size_t k = 0; k < styleNames.size(); k++)
{
auto& styleName = styleNames[k];
auto styleElem = styles.get(styleName.c_str(), Json::Value());
auto elementNames = styleElem.getMemberNames();
width = styleElem.get("width", width).asInt();
height = styleElem.get("height", height).asInt();

for (size_t l = 0; l < elementNames.size(); l++)
{
auto& elemName = elementNames[l];
auto elem = styleElem.get(elemName, Json::Value());
setUserElement(theme, themePath, styleName.c_str(), widgetName, elemName, WidgetStateType::Normal, elem.get("normal", Json::Value()), width, height);
setUserElement(theme, themePath, styleName.c_str(), widgetName, elemName, WidgetStateType::Hovered, elem.get("hovered", Json::Value()), width, height);
setUserElement(theme, themePath, styleName.c_str(), widgetName, elemName, WidgetStateType::Pressed, elem.get("pressed", Json::Value()), width, height);
setUserElement(theme, themePath, styleName.c_str(), widgetName, elemName, WidgetStateType::Focused, elem.get("focused", Json::Value()), width, height);
setUserElement(theme, themePath, styleName.c_str(), widgetName, elemName, WidgetStateType::Disabled, elem.get("disabled", Json::Value()), width, height);
}
}
auto& stateName = elemStates[m];
auto elemState = elem.get(stateName, Json::Value());
auto widgetStateType = WidgetStateType::None;

if (stateName == "normal")
widgetStateType = WidgetStateType::Normal;
else if (stateName == "focused")
widgetStateType = WidgetStateType::Focused;
else if (stateName == "pressed")
widgetStateType = WidgetStateType::Pressed;
else if (stateName == "hovered")
widgetStateType = WidgetStateType::Hovered;
else if (stateName == "disabled")
widgetStateType = WidgetStateType::Disabled;

if (!theme->userElements[elementName])
theme->userElements[elementName] = new UiThemeElement();

if (widgetStateType != WidgetStateType::None)
setUserElement(theme, themePath, styleName.c_str(), widgetName, elementName, widgetStateType, elemState, width, height);
else if (elemState.isDouble())
theme->userElements[elementName]->styles[styleName].parameters[stateName] = elemState.asFloat();
else if (elemState.isInt())
theme->userElements[elementName]->styles[styleName].parameters[stateName] = elemState.asInt();
}
}
};

if (styles.isObject())
{
auto styleNames = styles.getMemberNames();

// read all styles
for (size_t k = 0; k < styleNames.size(); k++)
{
auto styleName = styleNames[k];
auto styleElem = styles.get(styleName, Json::Value());

if (widgetType != WidgetType::None)
readElements(styleName, styleElem);
else
{
setUserElement(theme, themePath, "default", widgetName, elemName, WidgetStateType::Normal, elem.get("normal", Json::Value()), width, height);
setUserElement(theme, themePath, "default", widgetName, elemName, WidgetStateType::Hovered, elem.get("hovered", Json::Value()), width, height);
setUserElement(theme, themePath, "default", widgetName, elemName, WidgetStateType::Pressed, elem.get("pressed", Json::Value()), width, height);
setUserElement(theme, themePath, "default", widgetName, elemName, WidgetStateType::Focused, elem.get("focused", Json::Value()), width, height);
setUserElement(theme, themePath, "default", widgetName, elemName, WidgetStateType::Disabled, elem.get("disabled", Json::Value()), width, height);
}
readUserElements(styleName, styleElem);
}
}
else
{
if (widgetType != WidgetType::None)
readElements("default", widget);
else
readUserElements("default", widget);
}
}

buildTheme(theme);
Expand Down
3 changes: 2 additions & 1 deletion src/radio_widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ bool radio(const char* labelText, bool checked)
}, ctx->globalScale);
}

const f32 bulletTextSpacing = ctx->theme->settings.radioBulletTextSpacing * ctx->globalScale;
const f32 bulletTextSpacingParam = radioBodyElem.currentStyle->getParameterValue("bulletTextSpacing", 5);
const f32 bulletTextSpacing = bulletTextSpacingParam * ctx->globalScale;

ctx->renderer->cmdSetColor(radioBodyElemState->textColor);
ctx->renderer->cmdSetFont(radioBodyElemState->font);
Expand Down
Loading

0 comments on commit db2eb6f

Please sign in to comment.