743 lines
23 KiB
C++
743 lines
23 KiB
C++
// This file is part of VSTGUI. It is subject to the license terms
|
|
// in the LICENSE file found in the top-level directory of this
|
|
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
|
|
|
|
#include "../../lib/cbitmap.h"
|
|
#include "../../lib/cfont.h"
|
|
#include "../../lib/cgradient.h"
|
|
#include "../../lib/platform/platformfactory.h"
|
|
#include "../base64codec.h"
|
|
#include "../cstream.h"
|
|
#include "../uiattributes.h"
|
|
#include "../uiviewcreator.h"
|
|
#include "locale.h"
|
|
#include "parsecolor.h"
|
|
#include "scalefactorutils.h"
|
|
#include "uinode.h"
|
|
#include <list>
|
|
#include <string>
|
|
#include <sstream>
|
|
|
|
namespace VSTGUI {
|
|
namespace Detail {
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
UINode::UINode (const std::string& _name, const SharedPointer<UIAttributes>& _attributes,
|
|
bool needsFastChildNameAttributeLookup)
|
|
: name (_name), attributes (_attributes), flags (0)
|
|
{
|
|
if (needsFastChildNameAttributeLookup)
|
|
children = makeOwned<UIDescListWithFastFindAttributeNameChild> ();
|
|
else
|
|
children = makeOwned<UIDescList> ();
|
|
if (attributes == nullptr)
|
|
attributes = makeOwned<UIAttributes> ();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
UINode::UINode (const std::string& _name, const SharedPointer<UIDescList>& _children,
|
|
const SharedPointer<UIAttributes>& _attributes)
|
|
: name (_name), attributes (_attributes), children (_children), flags (0)
|
|
{
|
|
vstgui_assert (children != nullptr);
|
|
if (attributes == nullptr)
|
|
attributes = makeOwned<UIAttributes> ();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
UINode::UINode (const UINode& n)
|
|
: name (n.name)
|
|
, data (n.data)
|
|
, attributes (makeOwned<UIAttributes> (*n.attributes))
|
|
, children (makeOwned<UIDescList> (*n.children))
|
|
, flags (n.flags)
|
|
{
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
UINode::~UINode () noexcept
|
|
{
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool UINode::hasChildren () const
|
|
{
|
|
return !children->empty ();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void UINode::childAttributeChanged (UINode* child, const char* attributeName,
|
|
const char* oldAttributeValue)
|
|
{
|
|
children->nodeAttributeChanged (child, attributeName, oldAttributeValue);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void UINode::sortChildren ()
|
|
{
|
|
children->sort ();
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
void UINode::setData (DataStorage&& newData)
|
|
{
|
|
data = std::move (newData);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
UICommentNode::UICommentNode (const std::string& comment) : UINode ("comment")
|
|
{
|
|
data = comment;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
UIVariableNode::UIVariableNode (const std::string& name,
|
|
const SharedPointer<UIAttributes>& attributes)
|
|
: UINode (name, attributes), type (kUnknown), number (0)
|
|
{
|
|
const std::string* typeStr = attributes->getAttributeValue ("type");
|
|
const std::string* valueStr = attributes->getAttributeValue ("value");
|
|
if (typeStr)
|
|
{
|
|
if (*typeStr == "number")
|
|
type = kNumber;
|
|
else if (*typeStr == "string")
|
|
type = kString;
|
|
}
|
|
if (valueStr)
|
|
{
|
|
Detail::Locale localeResetter;
|
|
|
|
const char* strPtr = valueStr->c_str ();
|
|
if (type == kUnknown)
|
|
{
|
|
char* endPtr = nullptr;
|
|
double numberCheck = strtod (strPtr, &endPtr);
|
|
if (endPtr == strPtr + strlen (strPtr))
|
|
{
|
|
number = numberCheck;
|
|
type = kNumber;
|
|
}
|
|
else
|
|
type = kString;
|
|
}
|
|
else if (type == kNumber)
|
|
{
|
|
number = strtod (strPtr, nullptr);
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
UIVariableNode::Type UIVariableNode::getType () const
|
|
{
|
|
return type;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
double UIVariableNode::getNumber () const
|
|
{
|
|
return number;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
const std::string& UIVariableNode::getString () const
|
|
{
|
|
const std::string* value = attributes->getAttributeValue ("value");
|
|
if (value)
|
|
return *value;
|
|
static std::string kEmpty;
|
|
return kEmpty;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
UIControlTagNode::UIControlTagNode (const std::string& name,
|
|
const SharedPointer<UIAttributes>& attributes)
|
|
: UINode (name, attributes), tag (-1)
|
|
{
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
int32_t UIControlTagNode::getTag ()
|
|
{
|
|
if (tag == -1)
|
|
{
|
|
const std::string* tagStr = attributes->getAttributeValue ("tag");
|
|
if (tagStr)
|
|
{
|
|
if (tagStr->size () == 6 && (*tagStr)[0] == '\'' && (*tagStr)[5] == '\'')
|
|
{
|
|
char c1 = (*tagStr)[1];
|
|
char c2 = (*tagStr)[2];
|
|
char c3 = (*tagStr)[3];
|
|
char c4 = (*tagStr)[4];
|
|
tag = ((((int32_t)c1) << 24) | (((int32_t)c2) << 16) | (((int32_t)c3) << 8) |
|
|
(((int32_t)c4) << 0));
|
|
}
|
|
else
|
|
{
|
|
char* endPtr = nullptr;
|
|
tag = (int32_t)strtol (tagStr->c_str (), &endPtr, 10);
|
|
if (endPtr != tagStr->c_str () + tagStr->length ())
|
|
tag = -1;
|
|
}
|
|
}
|
|
}
|
|
return tag;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void UIControlTagNode::setTag (int32_t newTag)
|
|
{
|
|
tag = newTag;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
const std::string* UIControlTagNode::getTagString () const
|
|
{
|
|
return attributes->getAttributeValue ("tag");
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void UIControlTagNode::setTagString (const std::string& str)
|
|
{
|
|
attributes->setAttribute ("tag", str);
|
|
tag = -1;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
UIBitmapNode::UIBitmapNode (const std::string& name, const SharedPointer<UIAttributes>& attributes)
|
|
: UINode (name, attributes), bitmap (nullptr), filterProcessed (false), scaledBitmapsAdded (false)
|
|
{
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
UIBitmapNode::~UIBitmapNode () noexcept
|
|
{
|
|
if (bitmap)
|
|
bitmap->forget ();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void UIBitmapNode::freePlatformResources ()
|
|
{
|
|
if (bitmap)
|
|
bitmap->forget ();
|
|
bitmap = nullptr;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool UIBitmapNode::imagesEqual (IPlatformBitmap* b1, IPlatformBitmap* b2)
|
|
{
|
|
if (b1 == b2)
|
|
return true;
|
|
if (b1->getSize () != b2->getSize () || b1->getScaleFactor () != b2->getScaleFactor ())
|
|
return false;
|
|
auto ac1 = b1->lockPixels (true);
|
|
if (!ac1)
|
|
return false;
|
|
auto ac2 = b2->lockPixels (true);
|
|
if (!ac2)
|
|
return false;
|
|
auto rowBytes = ac1->getBytesPerRow ();
|
|
if (rowBytes != ac2->getBytesPerRow ())
|
|
return false;
|
|
if (ac1->getPixelFormat () != ac2->getPixelFormat ())
|
|
return false;
|
|
auto adr1 = ac1->getAddress ();
|
|
if (!adr1)
|
|
return false;
|
|
auto adr2 = ac2->getAddress ();
|
|
if (!adr2)
|
|
return false;
|
|
uint32_t rows = static_cast<uint32_t> (b1->getSize ().y);
|
|
for (uint32_t y = 0; y < rows; ++y, adr1 += rowBytes, adr2 += rowBytes)
|
|
{
|
|
if (memcmp (adr1, adr2, rowBytes) != 0)
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool UIBitmapNode::hasXMLData () const
|
|
{
|
|
return getChildren ().findChildNode ("data") != nullptr;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void UIBitmapNode::createXMLData (const std::string& pathHint)
|
|
{
|
|
UINode* node = getChildren ().findChildNode ("data");
|
|
if (node)
|
|
{
|
|
if (node->getData ().empty ())
|
|
{
|
|
getChildren ().remove (node);
|
|
node = nullptr;
|
|
}
|
|
else if (auto bm = getBitmap (pathHint))
|
|
{
|
|
if (auto platformBitmap = bm->getPlatformBitmap ())
|
|
{
|
|
if (auto dataBitmap = createBitmapFromDataNode ())
|
|
{
|
|
if (!imagesEqual (platformBitmap, dataBitmap))
|
|
{
|
|
removeXMLData ();
|
|
node = nullptr;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (node == nullptr)
|
|
{
|
|
if (auto bm = getBitmap (pathHint))
|
|
{
|
|
if (auto platformBitmap = bm->getPlatformBitmap ())
|
|
{
|
|
auto buffer =
|
|
getPlatformFactory ().createBitmapMemoryPNGRepresentation (platformBitmap);
|
|
if (!buffer.empty ())
|
|
{
|
|
auto result = Base64Codec::encode (buffer.data (),
|
|
static_cast<uint32_t> (buffer.size ()));
|
|
UINode* dataNode = new UINode ("data");
|
|
dataNode->getAttributes ()->setAttribute ("encoding", "base64");
|
|
dataNode->getData ().append (reinterpret_cast<const char*> (result.data.get ()),
|
|
static_cast<std::streamsize> (result.dataSize));
|
|
getChildren ().add (dataNode);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void UIBitmapNode::removeXMLData ()
|
|
{
|
|
UINode* node = getChildren ().findChildNode ("data");
|
|
if (node)
|
|
getChildren ().remove (node);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
CBitmap* UIBitmapNode::createBitmap (const std::string& str, const BitmapVariant& variant) const
|
|
{
|
|
|
|
if (auto partDesc = std::get_if<CNinePartTiledDescription> (&variant))
|
|
return new CNinePartTiledBitmap (CResourceDescription (str.data ()), *partDesc);
|
|
else if (auto multiFrameDesc = std::get_if<CMultiFrameBitmapDescription> (&variant))
|
|
return new CMultiFrameBitmap (CResourceDescription (str.data ()), *multiFrameDesc);
|
|
return new CBitmap (CResourceDescription (str.c_str ()));
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
UINode* UIBitmapNode::dataNode () const
|
|
{
|
|
UINode* node = getChildren ().findChildNode ("data");
|
|
return (node && !node->getData ().empty ()) ? node : nullptr;
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
PlatformBitmapPtr UIBitmapNode::createBitmapFromDataNode () const
|
|
{
|
|
if (auto node = dataNode ())
|
|
{
|
|
auto codecStr = node->getAttributes ()->getAttributeValue ("encoding");
|
|
if (codecStr && *codecStr == "base64")
|
|
{
|
|
auto result = Base64Codec::decode (node->getData ());
|
|
if (auto platformBitmap = getPlatformFactory ().createBitmapFromMemory (
|
|
result.data.get (), result.dataSize))
|
|
{
|
|
double scaleFactor = 1.;
|
|
if (attributes->getDoubleAttribute ("scale-factor", scaleFactor))
|
|
platformBitmap->setScaleFactor (scaleFactor);
|
|
return platformBitmap;
|
|
}
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
CBitmap* UIBitmapNode::getBitmap (const std::string& pathHint)
|
|
{
|
|
if (bitmap == nullptr)
|
|
{
|
|
const std::string* path = attributes->getAttributeValue ("path");
|
|
if (path)
|
|
{
|
|
BitmapVariant bitmapVariant;
|
|
int32_t tmpValue {};
|
|
CRect offsets;
|
|
if (attributes->getRectAttribute ("nineparttiled-offsets", offsets))
|
|
{
|
|
bitmapVariant = CNinePartTiledDescription (offsets.left, offsets.top, offsets.right,
|
|
offsets.bottom);
|
|
}
|
|
else if (attributes->getIntegerAttribute ("multiframe-num-frames", tmpValue))
|
|
{
|
|
CMultiFrameBitmapDescription multiFrameDesc {};
|
|
multiFrameDesc.numFrames = static_cast<uint16_t> (tmpValue);
|
|
if (attributes->getIntegerAttribute ("mulitframe-frames-per-row", tmpValue))
|
|
multiFrameDesc.framesPerRow = static_cast<uint16_t> (tmpValue);
|
|
attributes->getPointAttribute ("multiframe-size", multiFrameDesc.frameSize);
|
|
bitmapVariant = multiFrameDesc;
|
|
}
|
|
bitmap = createBitmap (*path, bitmapVariant);
|
|
if (bitmap->getPlatformBitmap () == nullptr && pathIsAbsolute (pathHint))
|
|
{
|
|
std::string absPath = pathHint;
|
|
if (removeLastPathComponent (absPath))
|
|
{
|
|
absPath += "/" + *path;
|
|
if (auto platformBitmap =
|
|
getPlatformFactory ().createBitmapFromPath (absPath.c_str ()))
|
|
{
|
|
bitmap->setPlatformBitmap (platformBitmap);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (bitmap && bitmap->getPlatformBitmap () == nullptr)
|
|
{
|
|
if (auto platformBitmap = createBitmapFromDataNode ())
|
|
bitmap->setPlatformBitmap (platformBitmap);
|
|
}
|
|
if (bitmap && path && bitmap->getPlatformBitmap () &&
|
|
bitmap->getPlatformBitmap ()->getScaleFactor () == 1.)
|
|
{
|
|
double scaleFactor = 1.;
|
|
if (Detail::decodeScaleFactorFromName (*path, scaleFactor))
|
|
{
|
|
bitmap->getPlatformBitmap ()->setScaleFactor (scaleFactor);
|
|
attributes->setDoubleAttribute ("scale-factor", scaleFactor);
|
|
}
|
|
}
|
|
}
|
|
return bitmap;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void UIBitmapNode::setBitmap (UTF8StringPtr bitmapName)
|
|
{
|
|
std::string name (bitmapName);
|
|
attributes->setAttribute ("path", name);
|
|
if (bitmap)
|
|
bitmap->forget ();
|
|
bitmap = nullptr;
|
|
double scaleFactor = 1.;
|
|
if (Detail::decodeScaleFactorFromName (name, scaleFactor))
|
|
attributes->setDoubleAttribute ("scale-factor", scaleFactor);
|
|
removeXMLData ();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void UIBitmapNode::setMultiFrameDesc (const CMultiFrameBitmapDescription* desc)
|
|
{
|
|
if (bitmap)
|
|
{
|
|
if (auto mfb = dynamic_cast<CMultiFrameBitmap*> (bitmap); mfb && desc)
|
|
{
|
|
mfb->setMultiFrameDesc (*desc);
|
|
}
|
|
else
|
|
{
|
|
bitmap->forget ();
|
|
bitmap = nullptr;
|
|
}
|
|
}
|
|
if (desc)
|
|
{
|
|
attributes->setPointAttribute ("multiframe-size", desc->frameSize);
|
|
attributes->setIntegerAttribute ("multiframe-num-frames", desc->numFrames);
|
|
attributes->setIntegerAttribute ("mulitframe-frames-per-row", desc->framesPerRow);
|
|
}
|
|
else
|
|
{
|
|
attributes->removeAttribute ("multiframe-size");
|
|
attributes->removeAttribute ("multiframe-num-frames");
|
|
attributes->removeAttribute ("mulitframe-frames-per-row");
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void UIBitmapNode::setNinePartTiledOffset (const CRect* offsets)
|
|
{
|
|
if (bitmap)
|
|
{
|
|
auto* tiledBitmap = dynamic_cast<CNinePartTiledBitmap*> (bitmap);
|
|
if (offsets && tiledBitmap)
|
|
{
|
|
tiledBitmap->setPartOffsets (CNinePartTiledDescription (
|
|
offsets->left, offsets->top, offsets->right, offsets->bottom));
|
|
}
|
|
else
|
|
{
|
|
bitmap->forget ();
|
|
bitmap = nullptr;
|
|
}
|
|
}
|
|
if (offsets)
|
|
attributes->setRectAttribute ("nineparttiled-offsets", *offsets);
|
|
else
|
|
attributes->removeAttribute ("nineparttiled-offsets");
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void UIBitmapNode::invalidBitmap ()
|
|
{
|
|
if (bitmap)
|
|
bitmap->forget ();
|
|
bitmap = nullptr;
|
|
filterProcessed = false;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
UIFontNode::UIFontNode (const std::string& name, const SharedPointer<UIAttributes>& attributes)
|
|
: UINode (name, attributes), font (nullptr)
|
|
{
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
UIFontNode::~UIFontNode () noexcept
|
|
{
|
|
if (font)
|
|
font->forget ();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void UIFontNode::freePlatformResources ()
|
|
{
|
|
if (font)
|
|
font->forget ();
|
|
font = nullptr;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
CFontRef UIFontNode::getFont ()
|
|
{
|
|
if (font == nullptr)
|
|
{
|
|
const std::string* nameAttr = attributes->getAttributeValue ("font-name");
|
|
const std::string* sizeAttr = attributes->getAttributeValue ("size");
|
|
const std::string* boldAttr = attributes->getAttributeValue ("bold");
|
|
const std::string* italicAttr = attributes->getAttributeValue ("italic");
|
|
const std::string* underlineAttr = attributes->getAttributeValue ("underline");
|
|
const std::string* strikethroughAttr = attributes->getAttributeValue ("strike-through");
|
|
if (nameAttr)
|
|
{
|
|
int32_t size = 12;
|
|
if (sizeAttr)
|
|
size = (int32_t)strtol (sizeAttr->c_str (), nullptr, 10);
|
|
int32_t fontStyle = 0;
|
|
if (boldAttr && *boldAttr == "true")
|
|
fontStyle |= kBoldFace;
|
|
if (italicAttr && *italicAttr == "true")
|
|
fontStyle |= kItalicFace;
|
|
if (underlineAttr && *underlineAttr == "true")
|
|
fontStyle |= kUnderlineFace;
|
|
if (strikethroughAttr && *strikethroughAttr == "true")
|
|
fontStyle |= kStrikethroughFace;
|
|
if (attributes->hasAttribute ("alternative-font-names"))
|
|
{
|
|
std::list<std::string> fontNames;
|
|
getPlatformFactory ().getAllFontFamilies ([&fontNames] (const std::string& name) {
|
|
fontNames.push_back (name);
|
|
return true;
|
|
});
|
|
if (std::find (fontNames.begin (), fontNames.end (), *nameAttr) == fontNames.end ())
|
|
{
|
|
std::vector<std::string> alternativeFontNames;
|
|
attributes->getStringArrayAttribute ("alternative-font-names",
|
|
alternativeFontNames);
|
|
for (auto& alternateFontName : alternativeFontNames)
|
|
{
|
|
auto trimmedString = trim (UTF8String (alternateFontName));
|
|
if (std::find (fontNames.begin (), fontNames.end (),
|
|
trimmedString.getString ()) != fontNames.end ())
|
|
{
|
|
font = new CFontDesc (trimmedString.data (), size, fontStyle);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (font == nullptr)
|
|
font = new CFontDesc (nameAttr->c_str (), size, fontStyle);
|
|
}
|
|
}
|
|
return font;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void UIFontNode::setFont (CFontRef newFont)
|
|
{
|
|
if (font)
|
|
font->forget ();
|
|
font = newFont;
|
|
font->remember ();
|
|
|
|
std::string name (*attributes->getAttributeValue ("name"));
|
|
std::string alternativeNames;
|
|
getAlternativeFontNames (alternativeNames);
|
|
|
|
attributes->removeAll ();
|
|
attributes->setAttribute ("name", name);
|
|
attributes->setAttribute ("font-name", newFont->getName ().getString ());
|
|
std::stringstream str;
|
|
str << newFont->getSize ();
|
|
attributes->setAttribute ("size", str.str ());
|
|
if (newFont->getStyle () & kBoldFace)
|
|
attributes->setAttribute ("bold", "true");
|
|
if (newFont->getStyle () & kItalicFace)
|
|
attributes->setAttribute ("italic", "true");
|
|
if (newFont->getStyle () & kUnderlineFace)
|
|
attributes->setAttribute ("underline", "true");
|
|
if (newFont->getStyle () & kStrikethroughFace)
|
|
attributes->setAttribute ("strike-through", "true");
|
|
|
|
setAlternativeFontNames (alternativeNames.c_str ());
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void UIFontNode::setAlternativeFontNames (UTF8StringPtr fontNames)
|
|
{
|
|
if (fontNames && fontNames[0] != 0)
|
|
{
|
|
attributes->setAttribute ("alternative-font-names", fontNames);
|
|
}
|
|
else
|
|
{
|
|
attributes->removeAttribute ("alternative-font-names");
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool UIFontNode::getAlternativeFontNames (std::string& fontNames)
|
|
{
|
|
const std::string* value = attributes->getAttributeValue ("alternative-font-names");
|
|
if (value)
|
|
{
|
|
fontNames = *value;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
UIColorNode::UIColorNode (const std::string& name, const SharedPointer<UIAttributes>& attributes)
|
|
: UINode (name, attributes)
|
|
{
|
|
color.alpha = 255;
|
|
const std::string* red = attributes->getAttributeValue ("red");
|
|
const std::string* green = attributes->getAttributeValue ("green");
|
|
const std::string* blue = attributes->getAttributeValue ("blue");
|
|
const std::string* alpha = attributes->getAttributeValue ("alpha");
|
|
const std::string* rgb = attributes->getAttributeValue ("rgb");
|
|
const std::string* rgba = attributes->getAttributeValue ("rgba");
|
|
if (red)
|
|
color.red = (uint8_t)strtol (red->c_str (), nullptr, 10);
|
|
if (green)
|
|
color.green = (uint8_t)strtol (green->c_str (), nullptr, 10);
|
|
if (blue)
|
|
color.blue = (uint8_t)strtol (blue->c_str (), nullptr, 10);
|
|
if (alpha)
|
|
color.alpha = (uint8_t)strtol (alpha->c_str (), nullptr, 10);
|
|
if (rgb)
|
|
parseColor (*rgb, color);
|
|
if (rgba)
|
|
parseColor (*rgba, color);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void UIColorNode::setColor (const CColor& newColor)
|
|
{
|
|
std::string name (*attributes->getAttributeValue ("name"));
|
|
attributes->removeAll ();
|
|
attributes->setAttribute ("name", name);
|
|
|
|
std::string colorString;
|
|
UIViewCreator::colorToString (newColor, colorString, nullptr);
|
|
attributes->setAttribute ("rgba", colorString);
|
|
color = newColor;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
UIGradientNode::UIGradientNode (const std::string& name,
|
|
const SharedPointer<UIAttributes>& attributes)
|
|
: UINode (name, attributes)
|
|
{
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void UIGradientNode::freePlatformResources ()
|
|
{
|
|
gradient = nullptr;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
CGradient* UIGradientNode::getGradient ()
|
|
{
|
|
if (gradient == nullptr)
|
|
{
|
|
GradientColorStopMap colorStops;
|
|
double start;
|
|
CColor color;
|
|
for (auto& colorNode : getChildren ())
|
|
{
|
|
if (colorNode->getName () == "color-stop")
|
|
{
|
|
const std::string* rgba = colorNode->getAttributes ()->getAttributeValue ("rgba");
|
|
if (rgba == nullptr ||
|
|
colorNode->getAttributes ()->getDoubleAttribute ("start", start) == false)
|
|
continue;
|
|
if (parseColor (*rgba, color) == false)
|
|
continue;
|
|
colorStops.emplace (start, color);
|
|
}
|
|
}
|
|
if (colorStops.size () > 1)
|
|
gradient = owned (CGradient::create (colorStops));
|
|
}
|
|
return gradient;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void UIGradientNode::setGradient (CGradient* g)
|
|
{
|
|
gradient = g;
|
|
getChildren ().removeAll ();
|
|
if (gradient == nullptr)
|
|
return;
|
|
|
|
const GradientColorStopMap colorStops = gradient->getColorStops ();
|
|
for (const auto& colorStop : colorStops)
|
|
{
|
|
UINode* node = new UINode ("color-stop");
|
|
node->getAttributes ()->setDoubleAttribute ("start", colorStop.first);
|
|
std::string colorString;
|
|
UIViewCreator::colorToString (colorStop.second, colorString, nullptr);
|
|
node->getAttributes ()->setAttribute ("rgba", colorString);
|
|
getChildren ().add (node);
|
|
}
|
|
}
|
|
|
|
} // Detail
|
|
} // VSTGUI
|