diff --git a/include/eepp/core/string.hpp b/include/eepp/core/string.hpp index da2de94e8..ca80b893f 100644 --- a/include/eepp/core/string.hpp +++ b/include/eepp/core/string.hpp @@ -402,7 +402,7 @@ class EE_API String { ** @return The character at position pos in the string. */ StringBaseType at( std::size_t index ) const; - + /** @brief clear the string ** This function removes all the characters from the string. ** @see empty, erase @@ -414,7 +414,7 @@ class EE_API String { ** @see empty **/ std::size_t size() const; - + /** @see size() */ std::size_t length() const; @@ -432,7 +432,6 @@ class EE_API String { **/ void erase(std::size_t position, std::size_t count = 1); - /** @brief Insert one or more characters into the string ** This function inserts the characters of \a str ** into the string, starting from \a position. @@ -454,8 +453,7 @@ class EE_API String { void insert ( Iterator p, std::size_t n, char c ); template - void insert ( Iterator p, InputIterator first, InputIterator last ) - { + void insert ( Iterator p, InputIterator first, InputIterator last ) { mString.insert( p, first, last ); } @@ -482,7 +480,7 @@ class EE_API String { ** @return Read-only pointer to the array of characters **/ const StringBaseType* c_str() const; - + /** @brief Get string data ** Notice that no terminating null character is appended (see member c_str for such a functionality). ** The returned array points to an internal location which should not be modified directly in the program. @@ -520,7 +518,7 @@ class EE_API String { ** @see begin **/ ConstIterator end() const; - + /** @brief Return an reverse iterator to the beginning of the string ** @return Read-write reverse iterator to the beginning of the string characters ** @see end @@ -550,28 +548,28 @@ class EE_API String { ** @see begin **/ ConstReverseIterator rend() const; - + /** @brief Resize String */ void resize ( std::size_t n, StringBaseType c ); - + /** @brief Resize String */ void resize ( std::size_t n ); - + /** @return Maximum size of string */ std::size_t max_size() const; - + /** @brief Request a change in capacity */ void reserve ( size_t res_arg=0 ); - + /** @return Size of allocated storage */ std::size_t capacity() const; /** @brief Append character to string */ void push_back( StringBaseType c ); - + /** @brief Swap contents with another string */ void swap ( String& str ); - + String& assign ( const String& str ); String& assign ( const String& str, std::size_t pos, std::size_t n ); @@ -583,8 +581,7 @@ class EE_API String { String& assign ( std::size_t n, char c ); template - String& assign ( InputIterator first, InputIterator last ) - { + String& assign ( InputIterator first, InputIterator last ) { mString.assign( first, last ); return *this; } @@ -602,8 +599,7 @@ class EE_API String { String& append ( std::size_t n, StringBaseType c ); template - String& append ( InputIterator first, InputIterator last ) - { + String& append ( InputIterator first, InputIterator last ) { mString.append( first, last ); return *this; } @@ -627,8 +623,7 @@ class EE_API String { String& replace ( Iterator i1, Iterator i2, std::size_t n2, char c ); template - String& replace ( Iterator i1, Iterator i2, InputIterator j1, InputIterator j2 ) - { + String& replace ( Iterator i1, Iterator i2, InputIterator j1, InputIterator j2 ) { mString.replace( i1, i2, j1, j2 ); return *this; } @@ -689,8 +684,8 @@ class EE_API String { std::size_t find_last_not_of ( StringBaseType c, std::size_t pos = StringType::npos ) const; private : - friend EE_API bool operator ==(const String& left, const String& right); - friend EE_API bool operator <(const String& left, const String& right); + friend EE_API bool operator ==(const String& left, const String& right); + friend EE_API bool operator <(const String& left, const String& right); StringType mString; ///< Internal string of UTF-32 characters }; diff --git a/include/eepp/scene/nodeattribute.hpp b/include/eepp/scene/nodeattribute.hpp index ea8856b40..7e99586fb 100644 --- a/include/eepp/scene/nodeattribute.hpp +++ b/include/eepp/scene/nodeattribute.hpp @@ -18,59 +18,6 @@ namespace EE { namespace Scene { class NodeAttribute { public: - enum AttributeType - { - TypeString, - TypeInt, - TypeUint, - TypeDouble, - TypeFloat, - TypeLongLong, - TypeULongLong, - TypeBoolean, - TypeDimension, - TypeDimensionInt, - TypeOriginPoint, - TypeBlendMode, - TypeVector, - TypeRect, - TypeRectf - }; - - class Info { - public: - Info( AttributeType type, const std::string& name ); - - Info( AttributeType type, const std::vector& names ); - - bool isName( const std::string& name ); - - const AttributeType& getType() const; - - const std::vector& getNames() const; - protected: - AttributeType type; - - std::vector names; - }; - - class FunctionType { - public: - static FunctionType parse( const std::string& function ); - - FunctionType( const std::string& name, const std::vector& parameters ); - - const std::string& getName() const; - - const std::vector& getParameters() const; - - bool isEmpty() const; - protected: - std::string name; - - std::vector parameters; - }; - NodeAttribute(); NodeAttribute( std::string name, std::string value, bool isVolatile = false ); diff --git a/include/eepp/system.hpp b/include/eepp/system.hpp index 3939bf625..174af4ad1 100644 --- a/include/eepp/system.hpp +++ b/include/eepp/system.hpp @@ -38,5 +38,6 @@ #include #include #include +#include #endif diff --git a/include/eepp/system/color.hpp b/include/eepp/system/color.hpp index b113076fa..24764183e 100755 --- a/include/eepp/system/color.hpp +++ b/include/eepp/system/color.hpp @@ -216,9 +216,9 @@ class EE_API Color : public tColor { Color( const Uint32& Col ); - Color toHsv(); + Colorf toHsv(); - static Color fromHsv( const Color& hsv ); + static Color fromHsv( const Colorf& hsv ); Colorf toHsl(); diff --git a/include/eepp/system/functionstring.hpp b/include/eepp/system/functionstring.hpp new file mode 100644 index 000000000..55168379e --- /dev/null +++ b/include/eepp/system/functionstring.hpp @@ -0,0 +1,28 @@ +#ifndef EE_SYSTEM_FUNCTIONSTRING_HPP +#define EE_SYSTEM_FUNCTIONSTRING_HPP + +#include +#include + +namespace EE { namespace System { + +class FunctionString { + public: + static FunctionString parse( const std::string& function ); + + FunctionString( const std::string& name, const std::vector& parameters ); + + const std::string& getName() const; + + const std::vector& getParameters() const; + + bool isEmpty() const; + protected: + std::string name; + + std::vector parameters; +}; + +}} + +#endif diff --git a/projects/linux/ee.files b/projects/linux/ee.files index c66ab6d52..21aaf3a57 100644 --- a/projects/linux/ee.files +++ b/projects/linux/ee.files @@ -230,6 +230,7 @@ ../../include/eepp/system/directorypack.hpp ../../include/eepp/system/filesystem.hpp ../../include/eepp/system.hpp +../../include/eepp/system/functionstring.hpp ../../include/eepp/system/inifile.hpp ../../include/eepp/system/iostreamdeflate.hpp ../../include/eepp/system/iostreamfile.hpp @@ -659,6 +660,7 @@ ../../src/eepp/system/condition.cpp ../../src/eepp/system/directorypack.cpp ../../src/eepp/system/filesystem.cpp +../../src/eepp/system/functionstring.cpp ../../src/eepp/system/inifile.cpp ../../src/eepp/system/iostreamdeflate.cpp ../../src/eepp/system/iostreamfile.cpp diff --git a/src/eepp/scene/nodeattribute.cpp b/src/eepp/scene/nodeattribute.cpp index 051677b71..dea54a665 100644 --- a/src/eepp/scene/nodeattribute.cpp +++ b/src/eepp/scene/nodeattribute.cpp @@ -8,28 +8,6 @@ using namespace EE::Graphics; namespace EE { namespace Scene { -NodeAttribute::Info::Info( NodeAttribute::AttributeType type, const std::string& name ) : - type( type ), - names( { name } ) -{} - -NodeAttribute::Info::Info( AttributeType type, const std::vector& names ) : - type( type ), - names( names ) -{} - -bool NodeAttribute::Info::isName( const std::string& name ) { - return std::find(names.begin(), names.end(), name) != names.end(); -} - -const NodeAttribute::AttributeType& NodeAttribute::Info::getType() const { - return type; -} - -const std::vector& NodeAttribute::Info::getNames() const { - return names; -} - NodeAttribute::NodeAttribute() : mVolatile( false ) {} @@ -302,81 +280,4 @@ Ease::Interpolation NodeAttribute::asInterpolation( const Ease::Interpolation& d return Ease::fromName( mValue, defaultInterpolation ); } -NodeAttribute::FunctionType NodeAttribute::FunctionType::parse( const std::string& function ) { - size_t posFuncStart = function.find_first_of( '(' ); - size_t posFuncEnd = function.find_last_of( ')' ); - std::string funcName; - std::vector parameters; - - if ( std::string::npos != posFuncStart && std::string::npos != posFuncEnd && posFuncStart > 1 && posFuncStart + 1 < function.size() ) { - funcName = function.substr( 0, posFuncStart ); - - if ( !funcName.empty() ) { - std::string funcParameters = function.substr( posFuncStart + 1, posFuncEnd - posFuncStart - 1 ); - std::string curParameter = ""; - bool parsingString = false; - bool lastWasBackslash = false; - - funcParameters = String::trim( funcParameters ); - - for ( size_t i = 0; i < funcParameters.size(); i++ ) { - const char& curChar = funcParameters.at(i); - - if ( !parsingString ) { - if ( ',' == curChar ) { - curParameter = String::trim( curParameter ); - - if ( !curParameter.empty() ) { - parameters.push_back( curParameter ); - curParameter = ""; - } - } else if ( '"' == curChar ) { - parsingString = true; - } else { - curParameter += curChar; - } - } else { - if ( '"' == curChar && !lastWasBackslash ) { - parsingString = false; - - if ( !curParameter.empty() ) { - parameters.push_back( curParameter ); - curParameter = ""; - } - } else { - if ( '\\' == curChar ) - lastWasBackslash = !lastWasBackslash; - - curParameter += curChar; - } - } - } - - curParameter = String::trim( curParameter ); - - if ( !curParameter.empty() ) - parameters.push_back( curParameter ); - } - } - - return NodeAttribute::FunctionType( funcName, parameters ); -} - -NodeAttribute::FunctionType::FunctionType( const std::string& name, const std::vector& parameters ) : - name( name ), - parameters( parameters ) -{} - -const std::string& NodeAttribute::FunctionType::getName() const { - return name; -} - -const std::vector& NodeAttribute::FunctionType::getParameters() const { - return parameters; -} - -bool NodeAttribute::FunctionType::isEmpty() const { - return name.empty(); -} - }} diff --git a/src/eepp/system/color.cpp b/src/eepp/system/color.cpp index e9152910d..2f51c6bfe 100644 --- a/src/eepp/system/color.cpp +++ b/src/eepp/system/color.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -126,92 +127,118 @@ Color::Color( const Uint32& Col ) : tColor( Col ) {} -Color Color::toHsv() { - Color hsv; - Color rgb( *this ); - unsigned char rgbMin, rgbMax; - - rgbMin = rgb.r < rgb.g ? (rgb.r < rgb.b ? rgb.r : rgb.b) : (rgb.g < rgb.b ? rgb.g : rgb.b); - rgbMax = rgb.r > rgb.g ? (rgb.r > rgb.b ? rgb.r : rgb.b) : (rgb.g > rgb.b ? rgb.g : rgb.b); - - hsv.hsv.a = rgb.a; +Colorf Color::toHsv() { + Colorf hsv; + Colorf rgba( this->r / 255.f, this->g / 255.f, this->b / 255.f, this->a / 255.f ); + Float rgbMax = eemax( rgba.r, eemax( rgba.g, rgba.b ) ); + Float rgbMin = eemin( rgba.r, eemin( rgba.g, rgba.b ) ); + Float delta = (rgbMax - rgbMin); hsv.hsv.v = rgbMax; + hsv.hsv.a = rgba.a; + if (hsv.hsv.v == 0){ hsv.hsv.h = 0; hsv.hsv.s = 0; return hsv; } - hsv.hsv.s = 255 * long(rgbMax - rgbMin) / hsv.hsv.v; + hsv.hsv.s = delta / rgbMax; if (hsv.hsv.s == 0) { hsv.hsv.h = 0; return hsv; } - if (rgbMax == rgb.r) - hsv.hsv.h = 0 + 43 * (rgb.g - rgb.b) / (rgbMax - rgbMin); - else if (rgbMax == rgb.g) - hsv.hsv.h = 85 + 43 * (rgb.b - rgb.r) / (rgbMax - rgbMin); - else - hsv.hsv.h = 171 + 43 * (rgb.r - rgb.g) / (rgbMax - rgbMin); + if (delta == 0) { + hsv.hsv.h = 0; + return hsv; + } else if ( rgba.r == rgbMax ) { + hsv.hsv.h = ( rgba.g - rgba.b ) / delta; + } else if ( rgba.g == rgbMax ) { + hsv.hsv.h = 2.f + ( rgba.b - rgba.r ) / delta; + } else { + hsv.hsv.h = 4.f + ( rgba.r - rgba.g ) / delta; + } + + hsv.hsv.h *= 60.f; + + if( hsv.hsv.h < 0.f ) + hsv.hsv.h += 360.f; return hsv; } -Color Color::fromHsv(const Color & hsv) { - Color rgb; - unsigned char region, remainder, p, q, t; +Color Color::fromHsv(const Colorf& hsv) { + Color rgba(Color::Transparent); + Float remainder, p, q, t; + int region; - rgb.a = hsv.hsv.a; + rgba.a = static_cast( hsv.hsv.a * 255.f + 0.5f ); if (hsv.hsv.s == 0) { - rgb.r = hsv.hsv.v; - rgb.g = hsv.hsv.v; - rgb.b = hsv.hsv.v; - return rgb; + rgba.r = hsv.hsv.v; + rgba.g = hsv.hsv.v; + rgba.b = hsv.hsv.v; + return rgba; } - region = hsv.hsv.h / 43; - remainder = (hsv.hsv.h - (region * 43)) * 6; + region = int(hsv.hsv.h / 60) % 6; + remainder = (hsv.hsv.h / 60.f) - region; - p = (hsv.hsv.v * (255 - hsv.hsv.s)) >> 8; - q = (hsv.hsv.v * (255 - ((hsv.hsv.s * remainder) >> 8))) >> 8; - t = (hsv.hsv.v * (255 - ((hsv.hsv.s * (255 - remainder)) >> 8))) >> 8; + p = hsv.hsv.v * (1 - hsv.hsv.s); + q = hsv.hsv.v * (1 - hsv.hsv.s * remainder); + t = hsv.hsv.v * (1 - (hsv.hsv.s * (1 - remainder))); + + Uint8 brightness = static_cast( hsv.hsv.v * 255.f + 0.5f ); + p = static_cast( p * 255.f + 0.5f ); + q = static_cast( q * 255.f + 0.5f ); + t = static_cast( t * 255.f + 0.5f ); switch (region) { case 0: - rgb.r = hsv.hsv.v; rgb.g = t; rgb.b = p; + rgba.r = brightness; + rgba.g = t; + rgba.b = p; break; case 1: - rgb.r = q; rgb.g = hsv.hsv.v; rgb.b = p; + rgba.r = q; + rgba.g = brightness; + rgba.b = p; break; case 2: - rgb.r = p; rgb.g = hsv.hsv.v; rgb.b = t; + rgba.r = p; + rgba.g = brightness; + rgba.b = t; break; case 3: - rgb.r = p; rgb.g = q; rgb.b = hsv.hsv.v; + rgba.r = p; + rgba.g = q; + rgba.b = brightness; break; case 4: - rgb.r = t; rgb.g = p; rgb.b = hsv.hsv.v; + rgba.r = t; + rgba.g = p; + rgba.b = brightness; break; default: - rgb.r = hsv.hsv.v; rgb.g = p; rgb.b = q; + rgba.r = brightness; + rgba.g = p; + rgba.b = q; break; } - return rgb; + return rgba; } Colorf Color::toHsl() { Colorf hsl; - float r = this->r / 255.f; - float g = this->g / 255.f; - float b = this->b / 255.f; - float a = this->a / 255.f; - float max = eemax(r, eemax( g, b ) ); - float min = eemin(r, eemin( g, b ) ); - float h, s, l = (max + min) / 2.f; + Float r = this->r / 255.f; + Float g = this->g / 255.f; + Float b = this->b / 255.f; + Float a = this->a / 255.f; + Float max = eemax(r, eemax( g, b ) ); + Float min = eemin(r, eemin( g, b ) ); + Float h, s, l = (max + min) / 2.f; if ( max == min ) { h = s = 0; // achromatic @@ -245,7 +272,7 @@ std::string Color::toHexString() const { return stream.str(); } -static Float hue2rgb( Float p, Float q, Float t) { +static Float hue2rgb( Float p, Float q, Float t ) { if(t < 0.f) t += 1.f; if(t > 1.f) t -= 1.f; if(t < 1.f/6.f) return p + (q - p) * 6.f * t; @@ -304,7 +331,7 @@ Color Color::fromString( std::string str ) { std::size_t size = str.size(); if ( 0 == size ) - return Color::White; + return Color::Transparent; if ( str[0] == '#' ) { str = str.substr(1); @@ -312,7 +339,161 @@ Color Color::fromString( std::string str ) { size = str.size(); if ( 0 == size ) - return Color::White; + return Color::Transparent; + + if ( size < 6 ) { + for ( std::size_t i = size; i < 6; i++ ) + str += str[ size - 1 ]; + + size = 6; + } + + if ( 6 == size ) + str += "FF"; + + return Color( std::strtoul( str.c_str(), NULL, 16 ) ); + } else if ( String::startsWith( str, "rgba(" ) || String::startsWith( str, "rgb(" ) ) { + FunctionString functionString = FunctionString::parse( str ); + + if ( ( functionString.getName() == "rgba" && functionString.getParameters().size() >= 4 ) || + ( functionString.getName() == "rgb" && functionString.getParameters().size() >= 3 ) ) { + Color color(Color::Transparent); + + for ( int i = 0; i < 3; i++ ) { + Float val = 0; + if ( String::fromString( val, functionString.getParameters().at(i) ) ) { + switch (i) { + case 0: color.r = static_cast( eemax( eemin( 255.f, val ), 0.f ) ); break; + case 1: color.g = static_cast( eemax( eemin( 255.f, val ), 0.f ) ); break; + case 2: color.b = static_cast( eemax( eemin( 255.f, val ), 0.f ) ); break; + default: break; + } + } else { + return Color::Transparent; + } + } + + Float val = 255; + if ( functionString.getParameters().size() >= 4 ) { + if ( String::fromString( val, functionString.getParameters().at(3) ) ) { + color.a = static_cast( eemax( eemin( 1.f, val ), 0.f ) * 255.f + 0.5f ); + } else { + return Color::Transparent; + } + } else { + color.a = val; + } + + return color; + } else { + return Color::Transparent; + } + } else if ( String::startsWith( str, "hsla(" ) || String::startsWith( str, "hsl(" ) ) { + FunctionString functionString = FunctionString::parse( str ); + + if ( ( functionString.getName() == "hsla" && functionString.getParameters().size() >= 4 ) || + ( functionString.getName() == "hsl" && functionString.getParameters().size() >= 3 ) ) { + Colorf color; + + Float hueVal, saturationVal, lightnessVal; + + int hueIntVal; + if ( String::fromString( hueIntVal, functionString.getParameters().at(0) ) && hueIntVal >= 0 && hueIntVal <= 360 ) { + hueVal = hueIntVal / 360.f; + } else { + return Color::Transparent; + } + + Float saturationFloatVal; + std::string saturationString( functionString.getParameters().at(1) ); + String::replaceAll( saturationString, "%", "" ); + if ( String::fromString( saturationFloatVal, saturationString ) && saturationFloatVal >= 0 && saturationFloatVal <= 100 ) { + saturationVal = saturationFloatVal / 100.f; + } else { + return Color::Transparent; + } + + Float lightnessFloatVal; + std::string lightnessString( functionString.getParameters().at(2) ); + String::replaceAll( lightnessString, "%", "" ); + if ( String::fromString( lightnessFloatVal, lightnessString ) && lightnessFloatVal >= 0 && lightnessFloatVal <= 100 ) { + lightnessVal = lightnessFloatVal / 100.f; + } else { + return Color::Transparent; + } + + Float alphaVal = 1; + + if ( functionString.getParameters().size() >= 4 ) { + if ( String::fromString( alphaVal, functionString.getParameters().at(3) ) ) { + alphaVal = eemax( eemin( 1.f, alphaVal ), 0.f ); + } else { + return Color::Transparent; + } + } + + color.hsl.h = hueVal; + color.hsl.s = saturationVal; + color.hsl.l = lightnessVal; + color.hsl.a = alphaVal; + + return Color::fromHsl( color ); + } else { + return Color::Transparent; + } + } else if ( String::startsWith( str, "hsva(" ) || String::startsWith( str, "hsv(" ) ) { + FunctionString functionString = FunctionString::parse( str ); + + if ( ( functionString.getName() == "hsva" && functionString.getParameters().size() >= 4 ) || + ( functionString.getName() == "hsv" && functionString.getParameters().size() >= 3 ) ) { + Colorf color; + + Float hueVal, saturationVal, valueVal; + + int hueIntVal; + if ( String::fromString( hueIntVal, functionString.getParameters().at(0) ) && hueIntVal >= 0 && hueIntVal <= 360 ) { + hueVal = hueIntVal; + } else { + return Color::Transparent; + } + + Float saturationFloatVal; + std::string saturationString( functionString.getParameters().at(1) ); + String::replaceAll( saturationString, "%", "" ); + if ( String::fromString( saturationFloatVal, saturationString ) && saturationFloatVal >= 0 && saturationFloatVal <= 100 ) { + saturationVal = saturationFloatVal / 100.f; + } else { + return Color::Transparent; + } + + Float valueFloatVal; + std::string valueString( functionString.getParameters().at(2) ); + String::replaceAll( valueString, "%", "" ); + if ( String::fromString( valueFloatVal, valueString ) && valueFloatVal >= 0 && valueFloatVal <= 100 ) { + valueVal = valueFloatVal / 100.f; + } else { + return Color::Transparent; + } + + Float alphaVal = 1; + + if ( functionString.getParameters().size() >= 4 ) { + if ( String::fromString( alphaVal, functionString.getParameters().at(3) ) ) { + alphaVal = eemax( eemin( 1.f, alphaVal ), 0.f ); + } else { + return Color::Transparent; + } + } + + color.hsv.h = hueVal; + color.hsv.s = saturationVal; + color.hsv.v = valueVal; + color.hsv.a = alphaVal; + + return Color::fromHsv( color ); + } else { + return Color::Transparent; + } } else if ( String::startsWith( str, "@color/" ) ) { std::string colorName( String::toLower( str.substr(7) ) ); const auto& it = sColors.find( colorName ); @@ -341,19 +522,18 @@ Color Color::fromString( std::string str ) { else if ( "blue" == str ) return Color::Blue; else if ( "teal" == str ) return Color::Teal; else if ( "aqua" == str ) return Color::Aqua; + } else { + String::toLowerInPlace( str ); + const auto& it = sColors.find( str ); + + if ( it != sColors.end() ) { + return it->second; + } else { + return Color::Transparent; + } } - if ( size < 6 ) { - for ( std::size_t i = size; i < 6; i++ ) - str += str[ size - 1 ]; - - size = 6; - } - - if ( 6 == size ) - str += "FF"; - - return Color( std::strtoul( str.c_str(), NULL, 16 ) ); + return Color::Transparent; } bool Color::isColorString( std::string str ) { @@ -381,6 +561,14 @@ bool Color::isColorString( std::string str ) { else if ( "blue" == str ) return true; else if ( "teal" == str ) return true; else if ( "aqua" == str ) return true; + else if ( String::startsWith( str, "rgb(" ) ) return true; + else if ( String::startsWith( str, "rgba(" ) ) return true; + else if ( String::startsWith( str, "hsl(" ) ) return true; + else if ( String::startsWith( str, "hsla(" ) ) return true; + else if ( String::startsWith( str, "hsv(" ) ) return true; + else if ( String::startsWith( str, "hsva(" ) ) return true; + else if ( String::startsWith( str, "@color/" ) ) return true; + else if ( sColors.find( str ) != sColors.end() ) return true; return false; } diff --git a/src/eepp/system/functionstring.cpp b/src/eepp/system/functionstring.cpp new file mode 100644 index 000000000..20edf49a3 --- /dev/null +++ b/src/eepp/system/functionstring.cpp @@ -0,0 +1,84 @@ +#include +#include + +namespace EE { namespace System { + +FunctionString FunctionString::parse( const std::string& function ) { + size_t posFuncStart = function.find_first_of( '(' ); + size_t posFuncEnd = function.find_last_of( ')' ); + std::string funcName; + std::vector parameters; + + if ( std::string::npos != posFuncStart && std::string::npos != posFuncEnd && posFuncStart > 1 && posFuncStart + 1 < function.size() ) { + funcName = function.substr( 0, posFuncStart ); + + if ( !funcName.empty() ) { + std::string funcParameters = function.substr( posFuncStart + 1, posFuncEnd - posFuncStart - 1 ); + std::string curParameter = ""; + bool parsingString = false; + bool lastWasBackslash = false; + + funcParameters = String::trim( funcParameters ); + + for ( size_t i = 0; i < funcParameters.size(); i++ ) { + const char& curChar = funcParameters.at(i); + + if ( !parsingString ) { + if ( ',' == curChar ) { + curParameter = String::trim( curParameter ); + + if ( !curParameter.empty() ) { + parameters.push_back( curParameter ); + curParameter = ""; + } + } else if ( '"' == curChar ) { + parsingString = true; + } else { + curParameter += curChar; + } + } else { + if ( '"' == curChar && !lastWasBackslash ) { + parsingString = false; + + if ( !curParameter.empty() ) { + parameters.push_back( curParameter ); + curParameter = ""; + } + } else { + if ( '\\' == curChar ) + lastWasBackslash = !lastWasBackslash; + + curParameter += curChar; + } + } + } + + curParameter = String::trim( curParameter ); + + if ( !curParameter.empty() ) + parameters.push_back( curParameter ); + } + } + + return FunctionString( funcName, parameters ); +} + +FunctionString::FunctionString( const std::string& name, const std::vector& parameters ) : + name( name ), + parameters( parameters ) +{} + +const std::string& FunctionString::getName() const { + return name; +} + +const std::vector& FunctionString::getParameters() const { + return parameters; +} + +bool FunctionString::isEmpty() const { + return name.empty(); +} + + +}} diff --git a/src/eepp/ui/uiwidget.cpp b/src/eepp/ui/uiwidget.cpp index 88e120f28..865ca5696 100644 --- a/src/eepp/ui/uiwidget.cpp +++ b/src/eepp/ui/uiwidget.cpp @@ -2,12 +2,13 @@ #include #include #include +#include +#include #include #include -#include #include +#include #include -#include #include namespace EE { namespace UI { @@ -1256,7 +1257,7 @@ std::string UIWidget::getFlagsString() const { } bool UIWidget::drawablePropertySet(const std::string& propertyName, const std::string& value, std::function funcSet) { - NodeAttribute::FunctionType functionType = NodeAttribute::FunctionType::parse( value ); + FunctionString functionType = FunctionString::parse( value ); Drawable * res = NULL; bool attributeSet = true; diff --git a/src/examples/empty_window/empty_window.cpp b/src/examples/empty_window/empty_window.cpp index 8d75d0b4f..ddbc83113 100644 --- a/src/examples/empty_window/empty_window.cpp +++ b/src/examples/empty_window/empty_window.cpp @@ -6,8 +6,7 @@ EE::Window::Window * win = NULL; -void mainLoop() -{ +void mainLoop() { // Clear the screen buffer win->clear(); @@ -34,8 +33,7 @@ void mainLoop() } // EE_MAIN_FUNC is needed by some platforms to be able to find the real application main -EE_MAIN_FUNC int main (int argc, char * argv []) -{ +EE_MAIN_FUNC int main (int argc, char * argv []) { // Create a new window with vsync enabled win = Engine::instance()->createWindow( WindowSettings( 960, 640, "eepp - Empty Window" ), ContextSettings( true ) );