DrawableImageParser: now supports "icon" and "glyph" functions.

StyleSheetSpecification: Added "background-tint" and "foreground-tint" (tints the "background-image" and "foreground-image" respectively).
FunctionString: minor fix and now stores if the parameters was parsed as a string.
This commit is contained in:
Martín Lucas Golini
2022-08-07 02:09:52 -03:00
parent 46dad2ac63
commit 220cf0f510
19 changed files with 209 additions and 21 deletions

View File

@@ -507,6 +507,8 @@ TabWidget {
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='90' height='45'%3E%3Cpath d='M10 10h60' stroke='%2300F' stroke-width='5'/%3E%3Cpath d='M10 20h60' stroke='%230F0' stroke-width='5'/%3E%3Cpath d='M10 30h60' stroke='red' stroke-width='5'/%3E%3C/svg%3E");
background-repeat: none;
background-position: 0 0, 64dp 0dp;
foreground-image: glyph("monospace", 24dp, "@"), icon("quit", 24dp);
foreground-position: right center, right top;
}
@media screen and (max-width: 1024px) {

View File

@@ -307,6 +307,16 @@ Read [background-repeat](https://developer.mozilla.org/en-US/docs/Web/CSS/backgr
---
### background-tint
Sets the tint color of the background image.
* Applicable to: Any element
* Data Type: [color](#color-data-type)
* Default value: `white`
---
### background-size
Read [background-size](https://developer.mozilla.org/en-US/docs/Web/CSS/background-size) documentation.
@@ -635,6 +645,16 @@ Same as [background-size](#background-size) but for the foreground.
---
### foreground-tint
Sets the tint color of the foreground image.
* Applicable to: Any element
* Data Type: [color](#color-data-type)
* Default value: `white`
---
### gravity
Sets the horizontal and vertical align of the inner elements/contents of a widget (for example the
@@ -2328,13 +2348,14 @@ url(data:image/format,url-encoded-data);
drawable_resource_name; /** same as doing: @drawable/drawable_resource_name */
linear-gradient(from_color, to_color);
linear-gradient(direction, from_color, to_color); /** valid directions are (without quotes): "to bottom", "to left", "to right", "to top". */
circle(type, color); /** type (optional) can be (without quotes): "fill" or "solid" (filled), or "line" (lined). */
circle(radius, color, type); /** type (optional) can be (without quotes): "fill" or "solid" (filled), or "line" (lined). */
rectangle(type, color, rotation, radius); /** type (optional) can be (without quotes): "fill" or "solid" (filled), or "line" (lined). rotation (optional) is a number in degress: "0º" (without quotes). radius (optional), must be the last parameter. */
triangle(type, color, "point_1.x point1.y, point_2.x point2.y, point_3.x point3.y") /** type can be (without quotes): "fill" or "solid" (filled), or "line" (lined). */
poly(type, color, "point_1.x point1.y, point_2.x point2.y, ...") /** polygon. type (optional) can be (without quotes): "fill" or "solid" (filled), or "line" (lined). */
icon(name, size) /** icons usually come from font glyphs, size is the font glyph size */
glyph(font_name, font_size, codepoint)
```
---
### string (data-type)

View File

@@ -1,8 +1,9 @@
import os
import sys
import datetime
project = 'eepp'
copyright = '2020, Martín Lucas Golini'
copyright = datetime.date.today().strftime("%Y") + ', Martín Lucas Golini'
author = 'Martín Lucas Golini'
sys.path.insert(1, os.path.abspath('./sphinx'))

View File

@@ -54,7 +54,7 @@ class EE_API Drawable {
void setColor( const Color& color );
Color getColor() const;
const Color& getColor() const;
void setColorFilter( const Color& color );

View File

@@ -12,11 +12,22 @@ namespace EE { namespace Scene { namespace Actions {
class EE_API Tint : public Action {
public:
enum TintType { Background, Foreground, Skin, Border, Text, TextShadow, TextOutline };
enum TintType {
Background,
Foreground,
Skin,
Border,
Text,
TextShadow,
TextOutline,
BackgroundTint,
ForegroundTint
};
static Tint* New( const Color& start, const Color& end, const bool& interpolateAlpha,
const Time& duration, const Ease::Interpolation& type = Ease::Linear,
const TintType& colorInterpolationType = Background );
const TintType& colorInterpolationType = Background,
const Uint32& elemIndex = 0 );
void start() override;
@@ -52,7 +63,8 @@ class EE_API Tint : public Action {
protected:
Tint( const Color& start, const Color& end, const bool& interpolateAlpha, const Time& duration,
const Ease::Interpolation& type, const TintType& colorInterpolationType );
const Ease::Interpolation& type, const TintType& colorInterpolationType,
const Uint32& elemIndex );
void onStart() override;
@@ -66,6 +78,7 @@ class EE_API Tint : public Action {
Interpolation1d mInterpolationA;
TintType mColorInterpolationType;
bool mInterpolateAlpha;
Uint32 mIndex;
};
}}} // namespace EE::Scene::Actions

View File

@@ -11,18 +11,22 @@ class EE_API FunctionString {
public:
static FunctionString parse( const std::string& function );
FunctionString( const std::string& name, const std::vector<std::string>& parameters );
FunctionString( const std::string& name, const std::vector<std::string>& parameters,
const std::vector<bool>& typeStringData );
const std::string& getName() const;
const std::vector<std::string>& getParameters() const;
bool parameterWasString( const Uint32& index ) const;
bool isEmpty() const;
protected:
std::string name;
std::vector<std::string> parameters;
std::vector<bool> typeStringData;
};
}} // namespace EE::System

View File

@@ -15,11 +15,13 @@ enum class PropertyId : Uint32 {
Height = String::hash( "height" ),
BackgroundColor = String::hash( "background-color" ),
BackgroundImage = String::hash( "background-image" ),
BackgroundTint = String::hash( "background-tint" ),
BackgroundPositionX = String::hash( "background-position-x" ),
BackgroundPositionY = String::hash( "background-position-y" ),
BackgroundRepeat = String::hash( "background-repeat" ),
BackgroundSize = String::hash( "background-size" ),
ForegroundColor = String::hash( "foreground-color" ),
ForegroundTint = String::hash( "foreground-tint" ),
ForegroundImage = String::hash( "foreground-image" ),
ForegroundPositionX = String::hash( "foreground-position-x" ),
ForegroundPositionY = String::hash( "foreground-position-y" ),

View File

@@ -101,6 +101,8 @@ class EE_API UINode : public Node {
UINode* setBackgroundColor( const Color& color );
UINode* setBackgroundTint( const Color& color, int index );
UINode* setBackgroundPositionX( const std::string& positionX, int index = 0 );
UINode* setBackgroundPositionY( const std::string& positionY, int index = 0 );
@@ -111,6 +113,8 @@ class EE_API UINode : public Node {
Color getBackgroundColor() const;
Color getBackgroundTint( int index = 0 ) const;
UINode* setBorderRadius( const unsigned int& corners );
UINode* setTopLeftRadius( const std::string& radius );
@@ -131,6 +135,8 @@ class EE_API UINode : public Node {
UINode* setForegroundColor( const Color& color );
UINode* setForegroundTint( const Color& color, int index );
UINode* setForegroundPositionX( const std::string& positionX, int index = 0 );
UINode* setForegroundPositionY( const std::string& positionY, int index = 0 );
@@ -141,6 +147,8 @@ class EE_API UINode : public Node {
Color getForegroundColor() const;
Color getForegroundTint( int index ) const;
UINode* setForegroundRadius( const unsigned int& corners );
Uint32 getForegroundRadius() const;
@@ -165,8 +173,12 @@ class EE_API UINode : public Node {
UINodeDrawable* getBackground() const;
bool hasBackground() const;
UINodeDrawable* getForeground() const;
bool hasForeground() const;
UIBorderDrawable* getBorder() const;
void setThemeByName( const std::string& Theme );

View File

@@ -102,6 +102,8 @@ class EE_API UINodeDrawable : public Drawable {
virtual void onPositionChange();
virtual void onColorFilterChange();
void update();
Drawable* createDrawable( const std::string& value, const Sizef& size, bool& ownIt );
@@ -151,6 +153,8 @@ class EE_API UINodeDrawable : public Drawable {
void setDrawableSize( int index, const std::string& sizeEq );
void setDrawableColor( int index, const Color& color );
void setBackgroundColor( const Color& color );
Color getBackgroundColor() const;
@@ -161,7 +165,7 @@ class EE_API UINodeDrawable : public Drawable {
void invalidate();
UINode* getOwner() const { return mOwner; }
UINode* getOwner() const;
UIBackgroundDrawable& getBackgroundDrawable();

View File

@@ -113,6 +113,7 @@ class EE_API UISceneNode : public SceneNode {
UIIcon* findIcon( const std::string& iconName );
/** @param drawableSize Size in pixels */
Drawable* findIconDrawable( const std::string& iconName, const size_t& drawableSize );
typedef std::function<void()> KeyBindingCommand;

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 7.0.2, 2022-07-24T21:29:54. -->
<!-- Written by QtCreator 8.0.0, 2022-08-06T21:54:17. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
@@ -109,7 +109,7 @@
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{388e5431-b31b-42b3-b9ad-9002d279d75d}</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">10</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">15</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">19</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">../../make/linux</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">

View File

@@ -29,7 +29,7 @@ void Drawable::setColor( const Color& color ) {
}
}
Color Drawable::getColor() const {
const Color& Drawable::getColor() const {
return mColor;
}

View File

@@ -1,4 +1,5 @@
#include <eepp/scene/actions/tint.hpp>
#include <eepp/ui/uinodedrawable.hpp>
#include <eepp/ui/uitextview.hpp>
#include <eepp/ui/uiwidget.hpp>
using namespace EE::UI;
@@ -7,8 +8,9 @@ namespace EE { namespace Scene { namespace Actions {
Tint* Tint::New( const Color& start, const Color& end, const bool& interpolateAlpha,
const Time& duration, const Ease::Interpolation& type,
const TintType& colorInterpolationType ) {
return eeNew( Tint, ( start, end, interpolateAlpha, duration, type, colorInterpolationType ) );
const TintType& colorInterpolationType, const Uint32& elemIndex ) {
return eeNew(
Tint, ( start, end, interpolateAlpha, duration, type, colorInterpolationType, elemIndex ) );
}
Tint::Tint() {}
@@ -47,8 +49,10 @@ void Tint::setInterpolationR( const Interpolation1d& interpolationR ) {
Tint::Tint( const Color& start, const Color& end, const bool& interpolateAlpha,
const Time& duration, const Ease::Interpolation& type,
const TintType& colorInterpolationType ) :
mColorInterpolationType( colorInterpolationType ), mInterpolateAlpha( interpolateAlpha ) {
const TintType& colorInterpolationType, const Uint32& elemIndex ) :
mColorInterpolationType( colorInterpolationType ),
mInterpolateAlpha( interpolateAlpha ),
mIndex( elemIndex ) {
mInterpolationR.clear().add( start.r, duration ).add( end.r ).setType( type );
mInterpolationG.clear().add( start.g, duration ).add( end.g ).setType( type );
mInterpolationB.clear().add( start.b, duration ).add( end.b ).setType( type );
@@ -197,6 +201,23 @@ void Tint::onUpdate( const Time& ) {
break;
}
case BackgroundTint: {
widget->setBackgroundTint(
Color( mInterpolationR.getPosition(), mInterpolationG.getPosition(),
mInterpolationB.getPosition(),
mInterpolateAlpha ? mInterpolationA.getPosition() : 255 ),
mIndex );
break;
}
case ForegroundTint: {
widget->setForegroundTint(
Color( mInterpolationR.getPosition(), mInterpolationG.getPosition(),
mInterpolationB.getPosition(),
mInterpolateAlpha ? mInterpolationA.getPosition() : 255 ),
mIndex );
break;
}
}
}
}

View File

@@ -1,3 +1,4 @@
#include <eepp/core/debug.hpp>
#include <eepp/core/string.hpp>
#include <eepp/system/functionstring.hpp>
@@ -8,6 +9,7 @@ FunctionString FunctionString::parse( const std::string& function ) {
size_t posFuncEnd = function.find_last_of( ')' );
std::string funcName;
std::vector<std::string> parameters;
std::vector<bool> typeStringData;
if ( std::string::npos != posFuncStart && std::string::npos != posFuncEnd && posFuncStart > 1 &&
posFuncStart + 1 < function.size() ) {
@@ -31,10 +33,12 @@ FunctionString FunctionString::parse( const std::string& function ) {
if ( !curParameter.empty() ) {
parameters.push_back( curParameter );
typeStringData.push_back( false );
curParameter = "";
}
} else if ( '"' == curChar ) {
parsingString = true;
curParameter = "";
} else {
curParameter += curChar;
}
@@ -44,6 +48,7 @@ FunctionString FunctionString::parse( const std::string& function ) {
if ( !curParameter.empty() ) {
parameters.push_back( curParameter );
typeStringData.push_back( true );
curParameter = "";
}
} else {
@@ -57,17 +62,19 @@ FunctionString FunctionString::parse( const std::string& function ) {
curParameter = String::trim( curParameter );
if ( !curParameter.empty() )
if ( !curParameter.empty() ) {
parameters.push_back( curParameter );
typeStringData.push_back( false );
}
}
}
return FunctionString( funcName, parameters );
return FunctionString( funcName, parameters, typeStringData );
}
FunctionString::FunctionString( const std::string& name,
const std::vector<std::string>& parameters ) :
name( name ), parameters( parameters ) {}
FunctionString::FunctionString( const std::string& name, const std::vector<std::string>& parameters,
const std::vector<bool>& typeStringData ) :
name( name ), parameters( parameters ), typeStringData( typeStringData ) {}
const std::string& FunctionString::getName() const {
return name;
@@ -77,6 +84,12 @@ const std::vector<std::string>& FunctionString::getParameters() const {
return parameters;
}
bool FunctionString::parameterWasString( const Uint32& index ) const {
eeASSERT( index < parameters.size() );
eeASSERT( index < typeStringData.size() );
return typeStringData[index];
}
bool FunctionString::isEmpty() const {
return name.empty();
}

View File

@@ -2,10 +2,16 @@
#include <eepp/graphics/convexshapedrawable.hpp>
#include <eepp/graphics/drawable.hpp>
#include <eepp/graphics/drawablesearcher.hpp>
#include <eepp/graphics/fontmanager.hpp>
#include <eepp/graphics/rectangledrawable.hpp>
#include <eepp/graphics/triangledrawable.hpp>
#include <eepp/scene/scenemanager.hpp>
#include <eepp/ui/css/drawableimageparser.hpp>
#include <eepp/ui/uiiconthememanager.hpp>
#include <eepp/ui/uinode.hpp>
#include <eepp/ui/uiscenenode.hpp>
using namespace EE::Scene;
namespace EE { namespace UI { namespace CSS {
@@ -314,6 +320,42 @@ void DrawableImageParser::registerBaseParsers() {
return DrawableSearcher::searchByName( functionType.getParameters().at( 0 ) );
};
mFuncs["icon"] = []( const FunctionString& functionType, const Sizef& size, bool&,
UINode* node ) -> Drawable* {
auto* uiScene = SceneManager::instance()->getUISceneNode();
const auto& params = functionType.getParameters();
if ( params.size() < 2 )
return nullptr;
CSS::StyleSheetLength length( params[1] );
return uiScene->findIconDrawable( params[0],
node->convertLength( length, size.getWidth() ) );
};
mFuncs["glyph"] = []( const FunctionString& functionType, const Sizef& size, bool&,
UINode* node ) -> Drawable* {
const auto& params = functionType.getParameters();
if ( params.size() < 3 )
return nullptr;
Font* font = FontManager::instance()->getByName( params[0] );
if ( font == nullptr )
return nullptr;
Uint32 codePoint = 0;
std::string buffer( params[1] );
Uint32 value;
if ( functionType.parameterWasString( 2 ) ) {
String unicodeChar = String::fromUtf8( params[2] );
if ( !unicodeChar.empty() )
codePoint = unicodeChar[0];
} else if ( String::startsWith( buffer, "0x" ) ) {
if ( String::fromString( value, buffer, std::hex ) )
codePoint = value;
} else if ( String::fromString( value, buffer ) ) {
codePoint = value;
}
return font->getGlyphDrawable( codePoint,
node->convertLength( params[1], size.getWidth() ) );
};
}
}}} // namespace EE::UI::CSS

View File

@@ -89,6 +89,7 @@ void StyleSheetSpecification::registerDefaultProperties() {
.setRelativeTarget( PropertyRelativeTarget::ContainingBlockHeight );
registerProperty( "background-color", "" ).setType( PropertyType::Color );
registerProperty( "background-image", "none" ).setIndexed();
registerProperty( "background-tint", "" ).setIndexed().setType( PropertyType::Color );
registerProperty( "background-position-x", "center" )
.setRelativeTarget( PropertyRelativeTarget::BackgroundWidth )
.setType( PropertyType::NumberLength )
@@ -103,6 +104,7 @@ void StyleSheetSpecification::registerDefaultProperties() {
.setIndexed();
registerProperty( "foreground-color", "" ).setType( PropertyType::Color );
registerProperty( "foreground-image", "none" ).setIndexed();
registerProperty( "foreground-tint", "" ).setIndexed().setType( PropertyType::Color );
registerProperty( "foreground-position-x", "center" )
.setRelativeTarget( PropertyRelativeTarget::ForegroundWidth )
.setType( PropertyType::NumberLength )

View File

@@ -742,6 +742,11 @@ UINode* UINode::setBackgroundColor( const Color& color ) {
return this;
}
UINode* UINode::setBackgroundTint( const Color& color, int index ) {
setBackgroundFillEnabled( true )->setDrawableColor( index, color );
return this;
}
UINode* UINode::setBackgroundPositionX( const std::string& positionX, int index ) {
setBackgroundFillEnabled( true )->setDrawablePositionX( index, positionX );
return this;
@@ -766,6 +771,10 @@ Color UINode::getBackgroundColor() const {
return NULL != mBackground ? mBackground->getBackgroundColor() : Color::Transparent;
}
Color UINode::getBackgroundTint( int index ) const {
return mBackground ? mBackground->getLayer( index )->getColor() : Color::White;
}
UINode* UINode::setBorderRadius( const unsigned int& corners ) {
setBorderEnabled( true )->setRadius( corners );
setBackgroundFillEnabled( true )->setBorderRadius( corners );
@@ -826,11 +835,20 @@ Color UINode::getForegroundColor() const {
return NULL != mForeground ? mForeground->getBackgroundColor() : Color::Transparent;
}
Color UINode::getForegroundTint( int index ) const {
return mForeground ? mForeground->getLayer( index )->getColor() : Color::White;
}
UINode* UINode::setForegroundColor( const Color& color ) {
setForegroundFillEnabled( true )->setBackgroundColor( color );
return this;
}
UINode* UINode::setForegroundTint( const Color& color, int index ) {
setForegroundFillEnabled( true )->setDrawableColor( index, color );
return this;
}
UINode* UINode::setForegroundPositionX( const std::string& positionX, int index ) {
setForegroundFillEnabled( true )->setDrawablePositionX( index, positionX );
return this;
@@ -1085,6 +1103,10 @@ UINodeDrawable* UINode::getBackground() const {
return mBackground;
}
bool UINode::hasBackground() const {
return mBackground != nullptr;
}
UINodeDrawable* UINode::getForeground() const {
if ( NULL == mForeground ) {
mForeground = UINodeDrawable::New( const_cast<UINode*>( this ) );
@@ -1093,6 +1115,10 @@ UINodeDrawable* UINode::getForeground() const {
return mForeground;
}
bool UINode::hasForeground() const {
return mForeground != nullptr;
}
UIBorderDrawable* UINode::getBorder() const {
if ( NULL == mBorder ) {
mBorder = UIBorderDrawable::New( this );

View File

@@ -7,6 +7,7 @@
#include <eepp/ui/css/stylesheetspecification.hpp>
#include <eepp/ui/uinode.hpp>
#include <eepp/ui/uinodedrawable.hpp>
#include <eepp/ui/uiwidget.hpp>
using namespace EE::Math::easing;
namespace EE { namespace UI {
@@ -103,6 +104,10 @@ void UINodeDrawable::setDrawableSize( int index, const std::string& sizeEq ) {
getLayer( index )->setSizeEq( sizeEq );
}
void UINodeDrawable::setDrawableColor( int index, const Color& color ) {
getLayer( index )->setColor( color );
}
void UINodeDrawable::setBackgroundColor( const Color& color ) {
mBackgroundColor.setColor( color );
}
@@ -124,6 +129,10 @@ void UINodeDrawable::invalidate() {
mBackgroundColor.invalidate();
}
UINode* UINodeDrawable::getOwner() const {
return mOwner;
}
UIBackgroundDrawable& UINodeDrawable::getBackgroundDrawable() {
return mBackgroundColor;
}
@@ -301,6 +310,7 @@ void UINodeDrawable::LayerDrawable::draw( const Vector2f& position, const Sizef&
if ( mNeedsUpdate )
update();
mDrawable->setColorFilter( getColor() );
mDrawable->setAlpha( getAlpha() );
switch ( mRepeat ) {
@@ -628,6 +638,10 @@ void UINodeDrawable::LayerDrawable::onPositionChange() {
invalidate();
}
void UINodeDrawable::LayerDrawable::onColorFilterChange() {
invalidate();
}
void UINodeDrawable::LayerDrawable::update() {
if ( mDrawable == NULL )
return;

View File

@@ -1145,8 +1145,12 @@ std::string UIWidget::getPropertyString( const PropertyDefinition* propertyDef,
return String::fromFloat( getPadding().Bottom, "dp" );
case PropertyId::BackgroundColor:
return getBackgroundColor().toHexString();
case PropertyId::BackgroundTint:
return getBackgroundTint( propertyIndex ).toHexString();
case PropertyId::ForegroundColor:
return getForegroundColor().toHexString();
case PropertyId::ForegroundTint:
return getForegroundTint( propertyIndex ).toHexString();
case PropertyId::ForegroundRadius:
return String::toString( getForegroundRadius() );
case PropertyId::BorderType:
@@ -1294,6 +1298,9 @@ bool UIWidget::applyProperty( const StyleSheetProperty& attribute ) {
case PropertyId::BackgroundColor:
setBackgroundColor( attribute.asColor() );
break;
case PropertyId::BackgroundTint:
setBackgroundTint( attribute.asColor(), attribute.getIndex() );
break;
case PropertyId::BackgroundImage:
setBackgroundDrawable( attribute.getValue(), attribute.getIndex() );
break;
@@ -1306,6 +1313,9 @@ bool UIWidget::applyProperty( const StyleSheetProperty& attribute ) {
case PropertyId::ForegroundColor:
setForegroundColor( attribute.asColor() );
break;
case PropertyId::ForegroundTint:
setForegroundTint( attribute.asColor(), attribute.getIndex() );
break;
case PropertyId::ForegroundImage:
setForegroundDrawable( attribute.getValue(), attribute.getIndex() );
break;