From 54a6fd63e98c93478d9eb49a436b5873b185e9e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Tue, 17 Jan 2023 23:13:08 -0300 Subject: [PATCH] eepp: Implemented CSS properties: text-shadow-offset and hint-shadow-offset. Renamed shadow-color to text-shadow-color. Added shorthand text-shadow and hint-shadow. Improved tooltip positioning. ecode: Closes SpartanJ/ecode#2 (Fixes fullscreen window on Windows). Closes SpartanJ/ecode#14 (Fixes folder rename, allows deleting folders). Closes SpartanJ/ecode#15 (Fixes folder doesn't automatically expand when creating a new file after being closed). --- bin/assets/layouts/test.css | 4 +- bin/assets/ui/breeze.css | 1 - bin/assets/ui/uitheme.css | 2 +- docs/articles/cssspecification.md | 72 +++++++++++++---- include/eepp/graphics/fontstyleconfig.hpp | 6 ++ include/eepp/graphics/text.hpp | 8 +- include/eepp/system/filesystem.hpp | 3 + include/eepp/ui/css/propertydefinition.hpp | 4 +- include/eepp/ui/uicodeeditor.hpp | 4 + include/eepp/ui/uiconsole.hpp | 4 + include/eepp/ui/uifontstyleconfig.hpp | 8 +- include/eepp/ui/uitextinput.hpp | 4 + include/eepp/ui/uitextview.hpp | 4 + include/eepp/ui/uitooltip.hpp | 8 +- src/eepp/graphics/text.cpp | 26 ++++-- src/eepp/system/filesystem.cpp | 24 +++--- src/eepp/ui/css/stylesheetspecification.cpp | 45 ++++++++++- src/eepp/ui/uicodeeditor.cpp | 51 +++++++----- src/eepp/ui/uicombobox.cpp | 12 ++- src/eepp/ui/uiconsole.cpp | 33 ++++++-- src/eepp/ui/uipushbutton.cpp | 9 ++- src/eepp/ui/uispinbox.cpp | 60 +++++++++++++- src/eepp/ui/uitextinput.cpp | 40 +++++++-- src/eepp/ui/uitextview.cpp | 47 +++++++++-- src/eepp/ui/uitooltip.cpp | 56 +++++++++++-- src/tools/ecode/appconfig.cpp | 22 +++-- src/tools/ecode/appconfig.hpp | 2 +- src/tools/ecode/ecode.cpp | 81 +++++++++++++++---- src/tools/ecode/ecode.hpp | 2 +- .../ecode/plugins/lsp/lspclientplugin.cpp | 1 + 30 files changed, 516 insertions(+), 127 deletions(-) diff --git a/bin/assets/layouts/test.css b/bin/assets/layouts/test.css index 5e0a45b5c..d4513c4cb 100644 --- a/bin/assets/layouts/test.css +++ b/bin/assets/layouts/test.css @@ -13,7 +13,7 @@ /* Global rules */ * { color: #E6E6E6FF; - shadow-color: #32323296; + text-shadow-color: #32323296; selection-color: #000; selection-back-color: #969696FF; } @@ -174,7 +174,7 @@ CheckBox:checked { border-color: #1d1f1fd7; border-radius: 3; cursor: hand; - shadow-color: black; + text-shadow-color: black; padding: 12dp 100dp 12dp 18dp; } diff --git a/bin/assets/ui/breeze.css b/bin/assets/ui/breeze.css index b56578c94..468e68540 100644 --- a/bin/assets/ui/breeze.css +++ b/bin/assets/ui/breeze.css @@ -389,7 +389,6 @@ Tooltip { border-color: var(--button-border); border-radius: var(--button-radius); border-width: var(--border-width); - font-style: shadow; } Slider { diff --git a/bin/assets/ui/uitheme.css b/bin/assets/ui/uitheme.css index 8df34232a..4d3a9b907 100644 --- a/bin/assets/ui/uitheme.css +++ b/bin/assets/ui/uitheme.css @@ -1,7 +1,7 @@ /* Global rules */ * { color: #E6E6E6FF; - shadow-color: #32323296; + text-shadow-color: #32323296; selection-color: #000; selection-back-color: #969696FF; } diff --git a/docs/articles/cssspecification.md b/docs/articles/cssspecification.md index 79f25405a..a8631439e 100644 --- a/docs/articles/cssspecification.md +++ b/docs/articles/cssspecification.md @@ -785,6 +785,20 @@ Sets the hint font stroke (the outline) color. --- +### hint-shadow-offset + +Sets the hint font shadow offset. + +* Applicable to: EE::UI::UITextView (TextView) and any element that holds inside text or extends from a + TextView. EE::UI::UICheckBox (CheckBox), EE::UI::UIRadioButton (RadioButton), EE::UI::UITextInput + (TextInput), EE::UI::UIListBoxItem (ListBox::item), EE::UI::UIDropDownList (DropDownList), + EE::UI::UITextInputPassword (TextInputPassword), EE::UI::UIPushButton (PushButton), EE::UI::UIToolti + (Tooltip) +* Data Type: [vector2-number](#vector2-number-data-type) +* Default offset: `1dp 1dp` + +--- + ### hint-stroke-width Sets the hint font stroke (the outline) width. @@ -1549,20 +1563,6 @@ Enables the selection state toggle on element click. --- -### shadow-color - -Sets the text shadow color. - -* Applicable to: EE::UI::UITextView (TextView) and any element that holds inside text or extends from a - TextView. EE::UI::UICheckBox (CheckBox), EE::UI::UIRadioButton (RadioButton), EE::UI::UITextInput - (TextInput), EE::UI::UIListBoxItem (ListBox::item), EE::UI::UIDropDownList (DropDownList), - EE::UI::UITextInputPassword (TextInputPassword), EE::UI::UIPushButton (PushButton), EE::UI::UIToolti - (Tooltip) -* Data Type: [color](#color-data-type) -* Default color: `#323232E6` - ---- - ### skin Sets the skin (a.k.a. decoration) to an element. Element skins are automatically applied if there's a specific skin for the element @@ -1746,6 +1746,34 @@ Enables/disables text selection in any element that contains text. --- +### text-shadow-color + +Sets the text shadow color. + +* Applicable to: EE::UI::UITextView (TextView) and any element that holds inside text or extends from a + TextView. EE::UI::UICheckBox (CheckBox), EE::UI::UIRadioButton (RadioButton), EE::UI::UITextInput + (TextInput), EE::UI::UIListBoxItem (ListBox::item), EE::UI::UIDropDownList (DropDownList), + EE::UI::UITextInputPassword (TextInputPassword), EE::UI::UIPushButton (PushButton), EE::UI::UIToolti + (Tooltip) +* Data Type: [color](#color-data-type) +* Default color: `#323232E6` + +--- + +### text-shadow-offset + +Sets the text shadow offset. + +* Applicable to: EE::UI::UITextView (TextView) and any element that holds inside text or extends from a + TextView. EE::UI::UICheckBox (CheckBox), EE::UI::UIRadioButton (RadioButton), EE::UI::UITextInput + (TextInput), EE::UI::UIListBoxItem (ListBox::item), EE::UI::UIDropDownList (DropDownList), + EE::UI::UITextInputPassword (TextInputPassword), EE::UI::UIPushButton (PushButton), EE::UI::UIToolti + (Tooltip) +* Data Type: [vector2-number](#vector2-number-data-type) +* Default offset: `1dp 1dp` + +--- + ### text-stroke-color Sets the text stroke (also known as text outline) color. @@ -2167,6 +2195,16 @@ Same as the [border-radius](#border-radius) but for the foreground of the node. --- +### hint-shadow + +The hint text shadow, same as text-shadow but for hints. + +Read [text-shadow](https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow) documentation. + +blur-radius is not supported. + +--- + ### margin Read [margin](https://developer.mozilla.org/en-US/docs/Web/CSS/margin) documentation. @@ -2228,6 +2266,12 @@ scale-origin-point: 100% 0%; Read [transition](https://developer.mozilla.org/en-US/docs/Web/CSS/transition) documentation. +### text-shadow + +Read [text-shadow](https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow) documentation. + +blur-radius is not supported. + --- ## At-rules diff --git a/include/eepp/graphics/fontstyleconfig.hpp b/include/eepp/graphics/fontstyleconfig.hpp index 973edcffb..72e1c9ef3 100644 --- a/include/eepp/graphics/fontstyleconfig.hpp +++ b/include/eepp/graphics/fontstyleconfig.hpp @@ -2,6 +2,8 @@ #define EE_GRAPHICS_FONTSTYLECONFIG_HPP #include +#include +#include #include using namespace EE::System; @@ -25,6 +27,8 @@ class FontStyleConfig { const Color& getOutlineColor() const { return OutlineColor; } + const Vector2f& getFontShadowOffset() const { return ShadowOffset; } + FontStyleConfig() {} virtual void updateFontStyleConfig( const FontStyleConfig& fontStyleConfig ) { @@ -33,6 +37,7 @@ class FontStyleConfig { CharacterSize = fontStyleConfig.CharacterSize; FontColor = fontStyleConfig.FontColor; ShadowColor = fontStyleConfig.ShadowColor; + ShadowOffset = fontStyleConfig.ShadowOffset; OutlineThickness = fontStyleConfig.OutlineThickness; OutlineColor = fontStyleConfig.OutlineColor; } @@ -42,6 +47,7 @@ class FontStyleConfig { Uint32 Style = 0; Color FontColor = Color( 255, 255, 255, 255 ); Color ShadowColor = Color( 50, 50, 50, 230 ); + Vector2f ShadowOffset{ PixelDensity::dpToPx( 1 ), PixelDensity::dpToPx( 1 ) }; Float OutlineThickness = 0; Color OutlineColor = Color( 0, 0, 0, 255 ); }; diff --git a/include/eepp/graphics/text.hpp b/include/eepp/graphics/text.hpp index 1de6e60ab..a869ee44b 100644 --- a/include/eepp/graphics/text.hpp +++ b/include/eepp/graphics/text.hpp @@ -3,6 +3,7 @@ #include #include +#include #include namespace EE { namespace Graphics { @@ -160,6 +161,10 @@ class EE_API Text { * disable this to improve performance in very specific scenarios. */ void setDisableCacheWidth( bool newDisableCacheWidth ); + const Vector2f& getShadowOffset() const; + + void setShadowOffset( const Vector2f& shadowOffset ); + protected: struct VertexCoords { Vector2f texCoords; @@ -186,7 +191,8 @@ class EE_API Text { Float mCachedWidth; int mNumLines; int mLargestLineCharCount; - Color mFontShadowColor; + Color mShadowColor; + Vector2f mShadowOffset{ PixelDensity::dpToPx( 1 ), PixelDensity::dpToPx( 1 ) }; Uint32 mAlign; Uint32 mFontHeight; Uint32 mTabWidth; diff --git a/include/eepp/system/filesystem.hpp b/include/eepp/system/filesystem.hpp index 9f72e998f..495c6ef3e 100644 --- a/include/eepp/system/filesystem.hpp +++ b/include/eepp/system/filesystem.hpp @@ -64,6 +64,9 @@ class EE_API FileSystem { /** Removes the process path to a file path */ static void filePathRemoveProcessPath( std::string& path ); + /** Removes a base path from a file path */ + static void filePathRemoveBasePath( const std::string& basePath, std::string& path ); + /** Write a file in binary mode and close it. */ static bool fileWrite( const std::string& filepath, const Uint8* data, const Uint32& dataSize ); diff --git a/include/eepp/ui/css/propertydefinition.hpp b/include/eepp/ui/css/propertydefinition.hpp index 6eaccefbc..4909f7959 100644 --- a/include/eepp/ui/css/propertydefinition.hpp +++ b/include/eepp/ui/css/propertydefinition.hpp @@ -65,7 +65,8 @@ enum class PropertyId : Uint32 { Text = String::hash( "text" ), TextTransform = String::hash( "text-transform" ), Color = String::hash( "color" ), - ShadowColor = String::hash( "shadow-color" ), + TextShadowColor = String::hash( "text-shadow-color" ), + TextShadowOffset = String::hash( "text-shadow-offset" ), SelectionColor = String::hash( "selection-color" ), SelectionBackColor = String::hash( "selection-back-color" ), FontFamily = String::hash( "font-family" ), @@ -157,6 +158,7 @@ enum class PropertyId : Uint32 { Hint = String::hash( "hint" ), HintColor = String::hash( "hint-color" ), HintShadowColor = String::hash( "hint-shadow-color" ), + HintShadowOffset = String::hash( "hint-shadow-offset" ), HintFontFamily = String::hash( "hint-font-family" ), HintFontSize = String::hash( "hint-font-size" ), HintFontStyle = String::hash( "hint-font-style" ), diff --git a/include/eepp/ui/uicodeeditor.hpp b/include/eepp/ui/uicodeeditor.hpp index 6796f9cf5..692fee93e 100644 --- a/include/eepp/ui/uicodeeditor.hpp +++ b/include/eepp/ui/uicodeeditor.hpp @@ -556,6 +556,10 @@ class EE_API UICodeEditor : public UIWidget, public TextDocument::Client { const Float& getPluginsTopSpace() const; + UICodeEditor* setFontShadowOffset( const Vector2f& offset ); + + const Vector2f& getFontShadowOffset() const; + protected: struct LastXOffset { TextPosition position; diff --git a/include/eepp/ui/uiconsole.hpp b/include/eepp/ui/uiconsole.hpp index 6e8eb9e82..379c5c674 100644 --- a/include/eepp/ui/uiconsole.hpp +++ b/include/eepp/ui/uiconsole.hpp @@ -62,6 +62,10 @@ class EE_API UIConsole : public UIWidget, const Color& getFontShadowColor() const; + UIConsole* setFontShadowOffset( const Vector2f& offset ); + + const Vector2f& getFontShadowOffset() const; + UIConsole* setFontStyle( const Uint32& fontStyle ); UIConsole* setFontOutlineThickness( const Float& outlineThickness ); diff --git a/include/eepp/ui/uifontstyleconfig.hpp b/include/eepp/ui/uifontstyleconfig.hpp index 28e68b0a0..ee69cee5b 100644 --- a/include/eepp/ui/uifontstyleconfig.hpp +++ b/include/eepp/ui/uifontstyleconfig.hpp @@ -26,10 +26,10 @@ class UIFontStyleConfig : public FontStyleConfig { UIFontStyleConfig( const FontStyleConfig& fontStyleConfig ) : FontStyleConfig( fontStyleConfig ) {} - UIFontStyleConfig( const UIFontStyleConfig& fontStyleConfig ) : - FontStyleConfig( fontStyleConfig ), - FontSelectedColor( fontStyleConfig.FontSelectedColor ), - FontSelectionBackColor( fontStyleConfig.FontSelectionBackColor ) {} +// UIFontStyleConfig( const UIFontStyleConfig& fontStyleConfig ) : +// FontStyleConfig( fontStyleConfig ), +// FontSelectedColor( fontStyleConfig.FontSelectedColor ), +// FontSelectionBackColor( fontStyleConfig.FontSelectionBackColor ) {} virtual void updateStyleConfig( const UIFontStyleConfig& fontStyleConfig ) { FontStyleConfig::updateFontStyleConfig( fontStyleConfig ); diff --git a/include/eepp/ui/uitextinput.hpp b/include/eepp/ui/uitextinput.hpp index ed6adae87..6e14fe5bb 100644 --- a/include/eepp/ui/uitextinput.hpp +++ b/include/eepp/ui/uitextinput.hpp @@ -70,6 +70,10 @@ class EE_API UITextInput : public UITextView, public TextDocument::Client { UITextInput* setHintShadowColor( const Color& shadowColor ); + const Vector2f& getHintShadowOffset() const; + + UITextInput* setHintShadowOffset( const Vector2f& shadowOffset ); + Font* getHintFont() const; UITextInput* setHintFont( Font* font ); diff --git a/include/eepp/ui/uitextview.hpp b/include/eepp/ui/uitextview.hpp index d4b226dfd..a6fbb0de6 100644 --- a/include/eepp/ui/uitextview.hpp +++ b/include/eepp/ui/uitextview.hpp @@ -59,6 +59,10 @@ class EE_API UITextView : public UIWidget { UITextView* setFontShadowColor( const Color& color ); + const Vector2f& getFontShadowOffset() const; + + UITextView* setFontShadowOffset( const Vector2f& offset ); + const Color& getSelectionBackColor() const; UITextView* setSelectionBackColor( const Color& color ); diff --git a/include/eepp/ui/uitooltip.hpp b/include/eepp/ui/uitooltip.hpp index e9f58be2d..1c4324920 100644 --- a/include/eepp/ui/uitooltip.hpp +++ b/include/eepp/ui/uitooltip.hpp @@ -16,7 +16,7 @@ class EE_API UITooltip : public UIWidget { public: static UITooltip* New(); - static Vector2f getTooltipPosition( UITooltip* toolip, Vector2f requestedPosition ); + static Vector2f getTooltipPosition( UITooltip* toolip, const Vector2f& requestedPosition ); UITooltip(); @@ -109,12 +109,16 @@ class EE_API UITooltip : public UIWidget { void setTextTransform( const TextTransform::Value& textTransform ); - Vector2f getTooltipPosition( Vector2f requestedPosition ); + Vector2f getTooltipPosition( const Vector2f& requestedPosition ); bool getUsingCustomStyling() const; void setUsingCustomStyling( bool usingCustomStyling ); + void setFontShadowOffset( const Vector2f& offset ); + + const Vector2f& getFontShadowOffset() const; + protected: Text* mTextCache; UIFontStyleConfig mStyleConfig; diff --git a/src/eepp/graphics/text.cpp b/src/eepp/graphics/text.cpp index e5bbeb4e7..49048aebb 100644 --- a/src/eepp/graphics/text.cpp +++ b/src/eepp/graphics/text.cpp @@ -97,7 +97,7 @@ Text::Text() : mCachedWidth( 0 ), mNumLines( 0 ), mLargestLineCharCount( 0 ), - mFontShadowColor( Color( 0, 0, 0, 255 ) ), + mShadowColor( Color( 0, 0, 0, 255 ) ), mAlign( 0 ), mFontHeight( 0 ), mTabWidth( 4 ) {} @@ -117,7 +117,7 @@ Text::Text( const String& string, Font* font, unsigned int characterSize ) : mCachedWidth( 0 ), mNumLines( 0 ), mLargestLineCharCount( 0 ), - mFontShadowColor( Color( 0, 0, 0, 255 ) ), + mShadowColor( Color( 0, 0, 0, 255 ) ), mAlign( 0 ), mFontHeight( mFont->getFontHeight( mRealFontSize ) ), mTabWidth( 4 ) { @@ -141,7 +141,7 @@ Text::Text( Font* font, unsigned int characterSize ) : mCachedWidth( 0 ), mNumLines( 0 ), mLargestLineCharCount( 0 ), - mFontShadowColor( Color( 0, 0, 0, 255 ) ), + mShadowColor( Color( 0, 0, 0, 255 ) ), mAlign( 0 ), mFontHeight( mFont->getFontHeight( mRealFontSize ) ), mTabWidth( 4 ) { @@ -157,6 +157,8 @@ void Text::create( Font* font, const String& text, Color FontColor, Color FontSh mString = text; mFontSize = characterSize; mRealFontSize = PixelDensity::dpToPxI( mFontSize ); + Float dp = PixelDensity::dpToPx( 1 ); + mShadowOffset = { dp, dp }; setFillColor( FontColor ); setShadowColor( FontShadowColor ); mGeometryNeedUpdate = true; @@ -580,6 +582,14 @@ void Text::setDisableCacheWidth( bool newDisableCacheWidth ) { mDisableCacheWidth = newDisableCacheWidth; } +const Vector2f& Text::getShadowOffset() const { + return mShadowOffset; +} + +void Text::setShadowOffset( const Vector2f& shadowOffset ) { + mShadowOffset = shadowOffset; +} + Rectf Text::getLocalBounds() { ensureGeometryUpdate(); @@ -713,9 +723,8 @@ void Text::draw( const Float& X, const Float& Y, const Vector2f& scale, const Fl shadowColor.a = (Uint8)( (Float)shadowColor.a * ( (Float)getFillColor().a / (Float)255 ) ); colors.assign( mColors.size(), shadowColor ); - Float pd = PixelDensity::dpToPx( 1 ); - draw( X + pd, Y + pd, scale, rotation, effect, rotationCenter, scaleCenter, colors, {}, - Color::Transparent ); + draw( X + mShadowOffset.x, Y + mShadowOffset.y, scale, rotation, effect, rotationCenter, + scaleCenter, colors, {}, Color::Transparent ); } draw( X, Y, scale, rotation, effect, rotationCenter, scaleCenter, mColors, mOutlineColors, @@ -962,11 +971,12 @@ void Text::ensureColorUpdate() { } const Color& Text::getShadowColor() const { - return mFontShadowColor; + return mShadowColor; } void Text::setShadowColor( const Color& color ) { - mFontShadowColor = color; + mShadowColor = color; + mStyle |= Text::Shadow; } const int& Text::getNumLines() { diff --git a/src/eepp/system/filesystem.cpp b/src/eepp/system/filesystem.cpp index 8083e737d..92fb28f47 100644 --- a/src/eepp/system/filesystem.cpp +++ b/src/eepp/system/filesystem.cpp @@ -159,20 +159,18 @@ std::string FileSystem::fileRemoveFileName( const std::string& filepath ) { return filepath.substr( 0, filepath.find_last_of( "/\\" ) + 1 ); } -void FileSystem::filePathRemoveProcessPath( std::string& path ) { - std::string ProcessPath = Sys::getProcessPath(); - - if ( String::startsWith( path, ProcessPath ) && ProcessPath.length() < path.size() ) { - path = path.substr( ProcessPath.length() ); +void FileSystem::filePathRemoveBasePath( const std::string& basePath, std::string& path ) { + if ( String::startsWith( path, basePath ) && basePath.length() < path.size() ) { + path = path.substr( basePath.length() ); } } -void FileSystem::filePathRemoveCurrentWorkingDirectory( std::string& path ) { - std::string dirPath = getCurrentWorkingDirectory(); +void FileSystem::filePathRemoveProcessPath( std::string& path ) { + return filePathRemoveBasePath( Sys::getProcessPath(), path ); +} - if ( String::startsWith( path, dirPath ) && dirPath.length() < path.size() ) { - path = path.substr( dirPath.length() ); - } +void FileSystem::filePathRemoveCurrentWorkingDirectory( std::string& path ) { + return filePathRemoveBasePath( getCurrentWorkingDirectory(), path ); } bool FileSystem::fileWrite( const std::string& filepath, const Uint8* data, @@ -400,8 +398,7 @@ std::vector FileSystem::filesGetInPath( const String& path, const bool& if ( strncmp( dirp->d_name, "..", sizeof( dirp->d_name ) ) != 0 && strncmp( dirp->d_name, ".", sizeof( dirp->d_name ) ) != 0 ) { #else - if ( strcmp( dirp->d_name, ".." ) != 0 && - strcmp( dirp->d_name, "." ) != 0 ) { + if ( strcmp( dirp->d_name, ".." ) != 0 && strcmp( dirp->d_name, "." ) != 0 ) { #endif char* p = &dirp->d_name[0]; String tmp; @@ -514,8 +511,7 @@ std::vector FileSystem::filesGetInPath( const std::string& path, if ( strncmp( dirp->d_name, "..", sizeof( dirp->d_name ) ) != 0 && strncmp( dirp->d_name, ".", sizeof( dirp->d_name ) ) != 0 ) #else - if ( strcmp( dirp->d_name, ".." ) != 0 && - strcmp( dirp->d_name, "." ) != 0 ) + if ( strcmp( dirp->d_name, ".." ) != 0 && strcmp( dirp->d_name, "." ) != 0 ) #endif files.push_back( std::string( dirp->d_name ) ); } diff --git a/src/eepp/ui/css/stylesheetspecification.cpp b/src/eepp/ui/css/stylesheetspecification.cpp index f2dd33045..2e40901e2 100644 --- a/src/eepp/ui/css/stylesheetspecification.cpp +++ b/src/eepp/ui/css/stylesheetspecification.cpp @@ -195,7 +195,8 @@ void StyleSheetSpecification::registerDefaultProperties() { .setType( PropertyType::Color ) .addAlias( "text-color" ) .addAlias( "textcolor" ); - registerProperty( "shadow-color", "" ).setType( PropertyType::Color ); + registerProperty( "text-shadow-color", "" ).setType( PropertyType::Color ); + registerProperty( "text-shadow-offset", "" ).setType( PropertyType::Vector2 ); registerProperty( "selection-color", "" ).setType( PropertyType::Color ); registerProperty( "selection-back-color", "" ).setType( PropertyType::Color ); registerProperty( "font-family", "" ).addAlias( "font-name" ).setType( PropertyType::String ); @@ -305,6 +306,7 @@ void StyleSheetSpecification::registerDefaultProperties() { registerProperty( "hint", "" ).setType( PropertyType::String ); registerProperty( "hint-color", "" ).setType( PropertyType::Color ); registerProperty( "hint-shadow-color", "" ).setType( PropertyType::Color ); + registerProperty( "hint-shadow-offset", "" ).setType( PropertyType::Vector2 ); registerProperty( "hint-font-size", "" ).setType( PropertyType::NumberLength ); registerProperty( "hint-font-style", "" ).setType( PropertyType::String ); registerProperty( "hint-stroke-width", "" ) @@ -426,6 +428,10 @@ void StyleSheetSpecification::registerDefaultProperties() { registerShorthand( "min-size", { "min-width", "min-height" }, "vector2" ); registerShorthand( "max-size", { "max-width", "max-height" }, "vector2" ); registerShorthand( "border", { "border-width", "border-style", "border-color" }, "border" ); + registerShorthand( "text-shadow", { "text-shadow-color", "text-shadow-offset" }, + "color-vector2" ); + registerShorthand( "hint-shadow", { "hint-shadow-color", "hint-shadow-offset" }, + "color-vector2" ); } void StyleSheetSpecification::registerNodeSelector( const std::string& name, @@ -904,6 +910,43 @@ void StyleSheetSpecification::registerDefaultShorthandParsers() { return properties; }; + + mShorthandParsers["color-vector2"] = + [&]( const ShorthandDefinition* shorthand, + std::string value ) -> std::vector { + value = String::trim( value ); + if ( value.empty() || "none" == value ) + return {}; + + std::vector properties; + const std::vector& propNames = shorthand->getProperties(); + std::vector tokens = String::split( value, " ", "", "(" ); + std::vector vec; + + for ( auto& tok : tokens ) { + String::trimInPlace( tok ); + String::toLowerInPlace( tok ); + + if ( Color::isColorString( tok ) ) { + int pos = getIndexEndingWith( propNames, "-color" ); + if ( pos != -1 ) + properties.emplace_back( StyleSheetProperty( propNames[pos], tok ) ); + } else { + int pos = getIndexEndingWith( propNames, "-offset" ); + if ( pos != -1 ) + vec.emplace_back( tok ); + } + } + + if ( !vec.empty() ) { + int pos = getIndexEndingWith( propNames, "-offset" ); + if ( pos != -1 ) + properties.emplace_back( + StyleSheetProperty( propNames[pos], String::join( vec, ' ' ) ) ); + } + + return properties; + }; } }}} // namespace EE::UI::CSS diff --git a/src/eepp/ui/uicodeeditor.cpp b/src/eepp/ui/uicodeeditor.cpp index 1149736f1..72e94bda1 100644 --- a/src/eepp/ui/uicodeeditor.cpp +++ b/src/eepp/ui/uicodeeditor.cpp @@ -1826,6 +1826,7 @@ bool UICodeEditor::isUnlockedCommand( const std::string& command ) { UICodeEditor* UICodeEditor::setFontShadowColor( const Color& color ) { if ( mFontStyleConfig.ShadowColor != color ) { mFontStyleConfig.ShadowColor = color; + mFontStyleConfig.Style |= Text::Shadow; invalidateDraw(); onFontStyleChanged(); } @@ -1833,6 +1834,24 @@ UICodeEditor* UICodeEditor::setFontShadowColor( const Color& color ) { return this; } +const Color& UICodeEditor::getFontShadowColor() const { + return mFontStyleConfig.getFontShadowColor(); +} + +UICodeEditor* UICodeEditor::setFontShadowOffset( const Vector2f& offset ) { + if ( mFontStyleConfig.ShadowOffset != offset ) { + mFontStyleConfig.ShadowOffset = offset; + invalidateDraw(); + onFontStyleChanged(); + } + + return this; +} + +const Vector2f& UICodeEditor::getFontShadowOffset() const { + return mFontStyleConfig.getFontShadowOffset(); +} + UICodeEditor* UICodeEditor::setFontStyle( const Uint32& fontStyle ) { if ( mFontStyleConfig.Style != fontStyle ) { mFontStyleConfig.Style = fontStyle; @@ -1843,10 +1862,6 @@ UICodeEditor* UICodeEditor::setFontStyle( const Uint32& fontStyle ) { return this; } -const Color& UICodeEditor::getFontShadowColor() const { - return mFontStyleConfig.getFontShadowColor(); -} - const Uint32& UICodeEditor::getFontStyle() const { return mFontStyleConfig.getFontStyle(); } @@ -1902,9 +1917,12 @@ bool UICodeEditor::applyProperty( const StyleSheetProperty& attribute ) { case PropertyId::Color: setFontColor( attribute.asColor() ); break; - case PropertyId::ShadowColor: + case PropertyId::TextShadowColor: setFontShadowColor( attribute.asColor() ); break; + case PropertyId::TextShadowOffset: + setFontShadowOffset( attribute.asVector2f() ); + break; case PropertyId::SelectionColor: setFontSelectedColor( attribute.asColor() ); break; @@ -1954,8 +1972,11 @@ std::string UICodeEditor::getPropertyString( const PropertyDefinition* propertyD return isLocked() ? "true" : "false"; case PropertyId::Color: return getFontColor().toHexString(); - case PropertyId::ShadowColor: + case PropertyId::TextShadowColor: return getFontShadowColor().toHexString(); + case PropertyId::TextShadowOffset: + return String::fromFloat( getFontShadowOffset().x ) + " " + + String::fromFloat( getFontShadowOffset().y ); case PropertyId::SelectionColor: return getFontSelectedColor().toHexString(); case PropertyId::SelectionBackColor: @@ -1981,18 +2002,12 @@ std::string UICodeEditor::getPropertyString( const PropertyDefinition* propertyD std::vector UICodeEditor::getPropertiesImplemented() const { auto props = UIWidget::getPropertiesImplemented(); - auto local = { PropertyId::Locked, - PropertyId::Color, - PropertyId::ShadowColor, - PropertyId::SelectionColor, - PropertyId::SelectionBackColor, - PropertyId::FontFamily, - PropertyId::FontSize, - PropertyId::FontStyle, - PropertyId::TextStrokeWidth, - PropertyId::TextStrokeColor, - PropertyId::TextSelection, - PropertyId::LineSpacing }; + auto local = { + PropertyId::Locked, PropertyId::Color, PropertyId::TextShadowColor, + PropertyId::TextShadowOffset, PropertyId::SelectionColor, PropertyId::SelectionBackColor, + PropertyId::FontFamily, PropertyId::FontSize, PropertyId::FontStyle, + PropertyId::TextStrokeWidth, PropertyId::TextStrokeColor, PropertyId::TextSelection, + PropertyId::LineSpacing }; props.insert( props.end(), local.begin(), local.end() ); return props; } diff --git a/src/eepp/ui/uicombobox.cpp b/src/eepp/ui/uicombobox.cpp index 629a940f3..6e5a5d339 100644 --- a/src/eepp/ui/uicombobox.cpp +++ b/src/eepp/ui/uicombobox.cpp @@ -140,7 +140,8 @@ bool UIComboBox::applyProperty( const StyleSheetProperty& attribute ) { switch ( attribute.getPropertyDefinition()->getPropertyId() ) { case PropertyId::Color: - case PropertyId::ShadowColor: + case PropertyId::TextShadowColor: + case PropertyId::TextShadowOffset: case PropertyId::SelectionColor: case PropertyId::SelectionBackColor: case PropertyId::FontFamily: @@ -159,6 +160,7 @@ bool UIComboBox::applyProperty( const StyleSheetProperty& attribute ) { case PropertyId::Hint: case PropertyId::HintColor: case PropertyId::HintShadowColor: + case PropertyId::HintShadowOffset: case PropertyId::HintFontSize: case PropertyId::HintFontFamily: case PropertyId::HintFontStyle: @@ -187,7 +189,8 @@ std::string UIComboBox::getPropertyString( const PropertyDefinition* propertyDef switch ( propertyDef->getPropertyId() ) { case PropertyId::Color: - case PropertyId::ShadowColor: + case PropertyId::TextShadowColor: + case PropertyId::TextShadowOffset: case PropertyId::SelectionColor: case PropertyId::SelectionBackColor: case PropertyId::FontFamily: @@ -206,6 +209,7 @@ std::string UIComboBox::getPropertyString( const PropertyDefinition* propertyDef case PropertyId::Hint: case PropertyId::HintColor: case PropertyId::HintShadowColor: + case PropertyId::HintShadowOffset: case PropertyId::HintFontSize: case PropertyId::HintFontFamily: case PropertyId::HintFontStyle: @@ -229,7 +233,8 @@ std::vector UIComboBox::getPropertiesImplemented() const { auto props = UIWidget::getPropertiesImplemented(); auto local = { PropertyId::Color, - PropertyId::ShadowColor, + PropertyId::TextShadowColor, + PropertyId::TextShadowOffset, PropertyId::SelectionColor, PropertyId::SelectionBackColor, PropertyId::FontFamily, @@ -248,6 +253,7 @@ std::vector UIComboBox::getPropertiesImplemented() const { PropertyId::Hint, PropertyId::HintColor, PropertyId::HintShadowColor, + PropertyId::HintShadowOffset, PropertyId::HintFontSize, PropertyId::HintFontFamily, PropertyId::HintFontStyle, diff --git a/src/eepp/ui/uiconsole.cpp b/src/eepp/ui/uiconsole.cpp index 16e47d1de..bb623427b 100644 --- a/src/eepp/ui/uiconsole.cpp +++ b/src/eepp/ui/uiconsole.cpp @@ -142,9 +142,12 @@ bool UIConsole::applyProperty( const StyleSheetProperty& attribute ) { case PropertyId::Color: setFontColor( attribute.asColor() ); break; - case PropertyId::ShadowColor: + case PropertyId::TextShadowColor: setFontShadowColor( attribute.asColor() ); break; + case PropertyId::TextShadowOffset: + setFontShadowOffset( attribute.asVector2f() ); + break; case PropertyId::SelectionColor: mFontStyleConfig.FontSelectedColor = attribute.asColor(); break; @@ -187,8 +190,11 @@ std::string UIConsole::getPropertyString( const PropertyDefinition* propertyDef, switch ( propertyDef->getPropertyId() ) { case PropertyId::Color: return getFontColor().toHexString(); - case PropertyId::ShadowColor: + case PropertyId::TextShadowColor: return getFontShadowColor().toHexString(); + case PropertyId::TextShadowOffset: + return String::fromFloat( getFontShadowOffset().x ) + " " + + String::fromFloat( getFontShadowOffset().y ); case PropertyId::SelectionColor: return getFontSelectedColor().toHexString(); case PropertyId::SelectionBackColor: @@ -210,11 +216,11 @@ std::string UIConsole::getPropertyString( const PropertyDefinition* propertyDef, std::vector UIConsole::getPropertiesImplemented() const { auto props = UIWidget::getPropertiesImplemented(); - auto local = { PropertyId::Color, PropertyId::ShadowColor, - PropertyId::SelectionColor, PropertyId::SelectionBackColor, - PropertyId::FontFamily, PropertyId::FontSize, - PropertyId::FontStyle, PropertyId::TextStrokeWidth, - PropertyId::TextStrokeColor }; + auto local = { + PropertyId::Color, PropertyId::TextShadowColor, PropertyId::TextShadowOffset, + PropertyId::SelectionColor, PropertyId::SelectionBackColor, PropertyId::FontFamily, + PropertyId::FontSize, PropertyId::FontStyle, PropertyId::TextStrokeWidth, + PropertyId::TextStrokeColor }; props.insert( props.end(), local.begin(), local.end() ); return props; } @@ -276,6 +282,7 @@ const Color& UIConsole::getFontSelectionBackColor() const { UIConsole* UIConsole::setFontShadowColor( const Color& color ) { if ( color != mFontStyleConfig.getFontShadowColor() ) { mFontStyleConfig.ShadowColor = color; + mFontStyleConfig.Style |= Text::Shadow; onFontStyleChanged(); } return this; @@ -285,6 +292,18 @@ const Color& UIConsole::getFontShadowColor() const { return mFontStyleConfig.ShadowColor; } +UIConsole* UIConsole::setFontShadowOffset( const Vector2f& offset ) { + if ( offset != mFontStyleConfig.getFontShadowOffset() ) { + mFontStyleConfig.ShadowOffset = offset; + onFontStyleChanged(); + } + return this; +} + +const Vector2f& UIConsole::getFontShadowOffset() const { + return mFontStyleConfig.ShadowOffset; +} + UIConsole* UIConsole::setFontStyle( const Uint32& fontStyle ) { if ( mFontStyleConfig.Style != fontStyle ) { mFontStyleConfig.Style = fontStyle; diff --git a/src/eepp/ui/uipushbutton.cpp b/src/eepp/ui/uipushbutton.cpp index cf96b64db..a7d9dd443 100644 --- a/src/eepp/ui/uipushbutton.cpp +++ b/src/eepp/ui/uipushbutton.cpp @@ -454,7 +454,8 @@ std::string UIPushButton::getPropertyString( const PropertyDefinition* propertyD case PropertyId::Tint: return mIcon->getColor().toHexString(); case PropertyId::Color: - case PropertyId::ShadowColor: + case PropertyId::TextShadowColor: + case PropertyId::TextShadowOffset: case PropertyId::SelectionColor: case PropertyId::SelectionBackColor: case PropertyId::FontFamily: @@ -480,7 +481,8 @@ std::vector UIPushButton::getPropertiesImplemented() const { PropertyId::TextAsFallback, PropertyId::Tint, PropertyId::Color, - PropertyId::ShadowColor, + PropertyId::TextShadowColor, + PropertyId::TextShadowOffset, PropertyId::SelectionColor, PropertyId::SelectionBackColor, PropertyId::FontFamily, @@ -545,7 +547,8 @@ bool UIPushButton::applyProperty( const StyleSheetProperty& attribute ) { mIcon->setColor( attribute.asColor() ); break; case PropertyId::Color: - case PropertyId::ShadowColor: + case PropertyId::TextShadowColor: + case PropertyId::TextShadowOffset: case PropertyId::SelectionColor: case PropertyId::SelectionBackColor: case PropertyId::FontFamily: diff --git a/src/eepp/ui/uispinbox.cpp b/src/eepp/ui/uispinbox.cpp index 8fc02042a..379031283 100644 --- a/src/eepp/ui/uispinbox.cpp +++ b/src/eepp/ui/uispinbox.cpp @@ -296,6 +296,34 @@ std::string UISpinBox::getPropertyString( const PropertyDefinition* propertyDef, return String::fromDouble( getValue() ); case PropertyId::ClickStep: return String::fromDouble( getClickStep() ); + case PropertyId::Text: + case PropertyId::AllowEditing: + case PropertyId::MaxLength: + case PropertyId::Numeric: + case PropertyId::AllowFloat: + case PropertyId::Hint: + case PropertyId::HintColor: + case PropertyId::HintShadowColor: + case PropertyId::HintShadowOffset: + case PropertyId::HintFontSize: + case PropertyId::HintFontFamily: + case PropertyId::HintFontStyle: + case PropertyId::HintStrokeWidth: + case PropertyId::HintStrokeColor: + case PropertyId::Color: + case PropertyId::TextShadowColor: + case PropertyId::TextShadowOffset: + case PropertyId::SelectionColor: + case PropertyId::SelectionBackColor: + case PropertyId::FontFamily: + case PropertyId::FontSize: + case PropertyId::FontStyle: + case PropertyId::Wordwrap: + case PropertyId::TextStrokeWidth: + case PropertyId::TextStrokeColor: + case PropertyId::TextSelection: + case PropertyId::TextAlign: + return mInput->getPropertyString( propertyDef, propertyIndex ); default: return UIWidget::getPropertyString( propertyDef, propertyIndex ); } @@ -305,7 +333,35 @@ std::vector UISpinBox::getPropertiesImplemented() const { auto props = UIWidget::getPropertiesImplemented(); auto local = { PropertyId::MinValue, PropertyId::MaxValue, PropertyId::Value, PropertyId::ClickStep }; + auto input = { PropertyId::Text, + PropertyId::AllowEditing, + PropertyId::MaxLength, + PropertyId::Numeric, + PropertyId::AllowFloat, + PropertyId::Hint, + PropertyId::HintColor, + PropertyId::HintShadowColor, + PropertyId::HintShadowOffset, + PropertyId::HintFontSize, + PropertyId::HintFontFamily, + PropertyId::HintFontStyle, + PropertyId::HintStrokeWidth, + PropertyId::HintStrokeColor, + PropertyId::Color, + PropertyId::TextShadowColor, + PropertyId::TextShadowOffset, + PropertyId::SelectionColor, + PropertyId::SelectionBackColor, + PropertyId::FontFamily, + PropertyId::FontSize, + PropertyId::FontStyle, + PropertyId::Wordwrap, + PropertyId::TextStrokeWidth, + PropertyId::TextStrokeColor, + PropertyId::TextSelection, + PropertyId::TextAlign }; props.insert( props.end(), local.begin(), local.end() ); + props.insert( props.end(), input.begin(), input.end() ); return props; } @@ -336,13 +392,15 @@ bool UISpinBox::applyProperty( const StyleSheetProperty& attribute ) { case PropertyId::Hint: case PropertyId::HintColor: case PropertyId::HintShadowColor: + case PropertyId::HintShadowOffset: case PropertyId::HintFontSize: case PropertyId::HintFontFamily: case PropertyId::HintFontStyle: case PropertyId::HintStrokeWidth: case PropertyId::HintStrokeColor: case PropertyId::Color: - case PropertyId::ShadowColor: + case PropertyId::TextShadowColor: + case PropertyId::TextShadowOffset: case PropertyId::SelectionColor: case PropertyId::SelectionBackColor: case PropertyId::FontFamily: diff --git a/src/eepp/ui/uitextinput.cpp b/src/eepp/ui/uitextinput.cpp index 1597bdb87..49642b6d3 100644 --- a/src/eepp/ui/uitextinput.cpp +++ b/src/eepp/ui/uitextinput.cpp @@ -452,6 +452,9 @@ std::string UITextInput::getPropertyString( const PropertyDefinition* propertyDe return getHintColor().toHexString(); case PropertyId::HintShadowColor: return getHintShadowColor().toHexString(); + case PropertyId::HintShadowOffset: + return String::fromFloat( getHintShadowOffset().x ) + " " + + String::fromFloat( getHintShadowOffset().y ); case PropertyId::HintFontSize: return String::format( "%ddp", getHintFontSize() ); case PropertyId::HintFontFamily: @@ -469,12 +472,20 @@ std::string UITextInput::getPropertyString( const PropertyDefinition* propertyDe std::vector UITextInput::getPropertiesImplemented() const { auto props = UITextView::getPropertiesImplemented(); - auto local = { - PropertyId::Text, PropertyId::AllowEditing, PropertyId::MaxLength, - PropertyId::Numeric, PropertyId::AllowFloat, PropertyId::Hint, - PropertyId::HintColor, PropertyId::HintShadowColor, PropertyId::HintFontSize, - PropertyId::HintFontFamily, PropertyId::HintFontStyle, PropertyId::HintStrokeWidth, - PropertyId::HintStrokeColor }; + auto local = { PropertyId::Text, + PropertyId::AllowEditing, + PropertyId::MaxLength, + PropertyId::Numeric, + PropertyId::AllowFloat, + PropertyId::Hint, + PropertyId::HintColor, + PropertyId::HintShadowColor, + PropertyId::HintShadowOffset, + PropertyId::HintFontSize, + PropertyId::HintFontFamily, + PropertyId::HintFontStyle, + PropertyId::HintStrokeWidth, + PropertyId::HintStrokeColor }; props.insert( props.end(), local.begin(), local.end() ); return props; } @@ -508,6 +519,9 @@ bool UITextInput::applyProperty( const StyleSheetProperty& attribute ) { case PropertyId::HintShadowColor: setHintShadowColor( attribute.asColor() ); break; + case PropertyId::HintShadowOffset: + setHintShadowOffset( attribute.asVector2f() ); + break; case PropertyId::HintFontSize: setHintFontSize( attribute.asDpDimensionI() ); break; @@ -589,6 +603,20 @@ UITextInput* UITextInput::setHintShadowColor( const Color& shadowColor ) { return this; } +const Vector2f& UITextInput::getHintShadowOffset() const { + return mHintStyleConfig.getFontShadowOffset(); +} + +UITextInput* UITextInput::setHintShadowOffset( const Vector2f& shadowOffset ) { + if ( shadowOffset != mHintStyleConfig.getFontShadowOffset() ) { + mHintCache->setShadowOffset( shadowOffset ); + mHintStyleConfig.ShadowOffset = shadowOffset; + invalidateDraw(); + } + + return this; +} + Font* UITextInput::getHintFont() const { return mHintStyleConfig.getFont(); } diff --git a/src/eepp/ui/uitextview.cpp b/src/eepp/ui/uitextview.cpp index 08943714c..f31edbb9c 100644 --- a/src/eepp/ui/uitextview.cpp +++ b/src/eepp/ui/uitextview.cpp @@ -259,6 +259,7 @@ const Color& UITextView::getFontShadowColor() const { UITextView* UITextView::setFontShadowColor( const Color& color ) { if ( mFontStyleConfig.ShadowColor != color ) { mFontStyleConfig.ShadowColor = color; + mFontStyleConfig.Style |= Text::Shadow; Color newColor( color.r, color.g, color.b, color.a * mAlpha / 255.f ); mTextCache->setShadowColor( newColor ); onFontStyleChanged(); @@ -268,6 +269,21 @@ UITextView* UITextView::setFontShadowColor( const Color& color ) { return this; } +const Vector2f& UITextView::getFontShadowOffset() const { + return mFontStyleConfig.ShadowOffset; +} + +UITextView* UITextView::setFontShadowOffset( const Vector2f& offset ) { + if ( mFontStyleConfig.ShadowOffset != offset ) { + mFontStyleConfig.ShadowOffset = offset; + mTextCache->setShadowOffset( offset ); + onFontStyleChanged(); + invalidateDraw(); + } + + return this; +} + const Color& UITextView::getSelectionBackColor() const { return mFontStyleConfig.FontSelectionBackColor; } @@ -659,9 +675,12 @@ bool UITextView::applyProperty( const StyleSheetProperty& attribute ) { case PropertyId::Color: setFontColor( attribute.asColor() ); break; - case PropertyId::ShadowColor: + case PropertyId::TextShadowColor: setFontShadowColor( attribute.asColor() ); break; + case PropertyId::TextShadowOffset: + setFontShadowOffset( attribute.asVector2f() ); + break; case PropertyId::SelectionColor: mFontStyleConfig.FontSelectedColor = attribute.asColor(); break; @@ -736,8 +755,11 @@ std::string UITextView::getPropertyString( const PropertyDefinition* propertyDef return TextTransform::toString( getTextTransform() ); case PropertyId::Color: return getFontColor().toHexString(); - case PropertyId::ShadowColor: + case PropertyId::TextShadowColor: return getFontShadowColor().toHexString(); + case PropertyId::TextShadowOffset: + return String::fromFloat( getFontShadowOffset().x ) + " " + + String::fromFloat( getFontShadowOffset().y ); case PropertyId::SelectionColor: return mFontStyleConfig.FontSelectedColor.toHexString(); case PropertyId::SelectionBackColor: @@ -768,12 +790,21 @@ std::string UITextView::getPropertyString( const PropertyDefinition* propertyDef std::vector UITextView::getPropertiesImplemented() const { auto props = UIWidget::getPropertiesImplemented(); - auto local = { - PropertyId::Text, PropertyId::TextTransform, PropertyId::Color, - PropertyId::ShadowColor, PropertyId::SelectionColor, PropertyId::SelectionBackColor, - PropertyId::FontFamily, PropertyId::FontSize, PropertyId::FontStyle, - PropertyId::Wordwrap, PropertyId::TextStrokeWidth, PropertyId::TextStrokeColor, - PropertyId::TextSelection, PropertyId::TextAlign }; + auto local = { PropertyId::Text, + PropertyId::TextTransform, + PropertyId::Color, + PropertyId::TextShadowColor, + PropertyId::TextShadowOffset, + PropertyId::SelectionColor, + PropertyId::SelectionBackColor, + PropertyId::FontFamily, + PropertyId::FontSize, + PropertyId::FontStyle, + PropertyId::Wordwrap, + PropertyId::TextStrokeWidth, + PropertyId::TextStrokeColor, + PropertyId::TextSelection, + PropertyId::TextAlign }; props.insert( props.end(), local.begin(), local.end() ); return props; } diff --git a/src/eepp/ui/uitooltip.cpp b/src/eepp/ui/uitooltip.cpp index edd3b1347..b7c9d3635 100644 --- a/src/eepp/ui/uitooltip.cpp +++ b/src/eepp/ui/uitooltip.cpp @@ -13,7 +13,7 @@ UITooltip* UITooltip::New() { return eeNew( UITooltip, () ); } -Vector2f UITooltip::getTooltipPosition( UITooltip* toolip, Vector2f requestedPosition ) { +Vector2f UITooltip::getTooltipPosition( UITooltip* toolip, const Vector2f& requestedPosition ) { UISceneNode* uiSceneNode = toolip->getUISceneNode(); if ( NULL == uiSceneNode ) @@ -36,6 +36,22 @@ Vector2f UITooltip::getTooltipPosition( UITooltip* toolip, Vector2f requestedPos pos.y = requestedPosition.y - toolip->getPixelsSize().getHeight() - 1; } + if ( pos.x < 0 && + toolip->getPixelsSize().getWidth() < uiSceneNode->getPixelsSize().getWidth() ) { + auto distLeft = std::abs( std::max( 0.f, pos.x ) - requestedPosition.x ); + auto distRight = std::abs( uiSceneNode->getPixelsSize().getWidth() - requestedPosition.x ); + if ( distLeft < distRight ) { + pos.x = 0; + } else { + pos.x = uiSceneNode->getPixelsSize().getWidth() - toolip->getPixelsSize().getWidth(); + } + } + + if ( pos.y < 0 && + toolip->getPixelsSize().getHeight() < uiSceneNode->getPixelsSize().getHeight() ) { + pos.y = 0; + } + return pos; } @@ -178,6 +194,7 @@ const Color& UITooltip::getFontColor() const { void UITooltip::setFontColor( const Color& color ) { if ( mStyleConfig.FontColor != color ) { mStyleConfig.FontColor = color; + mTextCache->setColor( color ); onAlphaChange(); invalidateDraw(); } @@ -190,11 +207,25 @@ const Color& UITooltip::getFontShadowColor() const { void UITooltip::setFontShadowColor( const Color& color ) { if ( mStyleConfig.ShadowColor != color ) { mStyleConfig.ShadowColor = color; + mStyleConfig.Style |= Text::Shadow; + mTextCache->setShadowColor( color ); onAlphaChange(); invalidateDraw(); } } +const Vector2f& UITooltip::getFontShadowOffset() const { + return mStyleConfig.ShadowOffset; +} + +void UITooltip::setFontShadowOffset( const Vector2f& offset ) { + if ( mStyleConfig.ShadowOffset != offset ) { + mStyleConfig.ShadowOffset = offset; + mTextCache->setShadowOffset( offset ); + invalidateDraw(); + } +} + void UITooltip::onAutoSize() { if ( mFlags & UI_AUTO_SIZE ) { setInternalPixelsSize( @@ -342,6 +373,7 @@ const Color& UITooltip::getOutlineColor() const { UITooltip* UITooltip::setOutlineColor( const Color& outlineColor ) { if ( mStyleConfig.OutlineColor != outlineColor ) { + mStyleConfig.OutlineColor = outlineColor; mTextCache->setOutlineColor( outlineColor ); onAlphaChange(); invalidateDraw(); @@ -371,8 +403,11 @@ std::string UITooltip::getPropertyString( const PropertyDefinition* propertyDef, return TextTransform::toString( getTextTransform() ); case PropertyId::Color: return getFontColor().toHexString(); - case PropertyId::ShadowColor: + case PropertyId::TextShadowColor: return getFontShadowColor().toHexString(); + case PropertyId::TextShadowOffset: + return String::fromFloat( getFontShadowOffset().x ) + " " + + String::fromFloat( getFontShadowOffset().y ); case PropertyId::FontFamily: return NULL != getFont() ? getFont()->getName() : ""; case PropertyId::FontSize: @@ -395,10 +430,11 @@ std::string UITooltip::getPropertyString( const PropertyDefinition* propertyDef, std::vector UITooltip::getPropertiesImplemented() const { auto props = UIWidget::getPropertiesImplemented(); - auto local = { - PropertyId::TextTransform, PropertyId::Color, PropertyId::ShadowColor, - PropertyId::FontFamily, PropertyId::FontSize, PropertyId::FontStyle, - PropertyId::TextStrokeWidth, PropertyId::TextStrokeColor, PropertyId::TextAlign }; + auto local = { PropertyId::TextTransform, PropertyId::Color, + PropertyId::TextShadowColor, PropertyId::TextShadowOffset, + PropertyId::FontFamily, PropertyId::FontSize, + PropertyId::FontStyle, PropertyId::TextStrokeWidth, + PropertyId::TextStrokeColor, PropertyId::TextAlign }; props.insert( props.end(), local.begin(), local.end() ); return props; } @@ -438,7 +474,7 @@ void UITooltip::setTextTransform( const TextTransform::Value& textTransform ) { } } -Vector2f UITooltip::getTooltipPosition( Vector2f requestedPosition ) { +Vector2f UITooltip::getTooltipPosition( const Vector2f& requestedPosition ) { return UITooltip::getTooltipPosition( this, requestedPosition ); } @@ -462,10 +498,14 @@ bool UITooltip::applyProperty( const StyleSheetProperty& attribute ) { if ( !mUsingCustomStyling ) setFontColor( attribute.asColor() ); break; - case PropertyId::ShadowColor: + case PropertyId::TextShadowColor: if ( !mUsingCustomStyling ) setFontShadowColor( attribute.asColor() ); break; + case PropertyId::TextShadowOffset: + if ( !mUsingCustomStyling ) + setFontShadowOffset( attribute.asVector2f() ); + break; case PropertyId::FontFamily: { Font* font = FontManager::instance()->getByName( attribute.asString() ); diff --git a/src/tools/ecode/appconfig.cpp b/src/tools/ecode/appconfig.cpp index ef77cacf3..95691bb62 100644 --- a/src/tools/ecode/appconfig.cpp +++ b/src/tools/ecode/appconfig.cpp @@ -43,7 +43,7 @@ static std::vector urlDecode( const std::vector& vec ) void AppConfig::load( const std::string& confPath, std::string& keybindingsPath, std::string& initColorScheme, std::vector& recentFiles, std::vector& recentFolders, const std::string& resPath, - const Float& displayDPI, PluginManager* pluginManager ) { + PluginManager* pluginManager, const Sizei& displaySize ) { keybindingsPath = confPath + "keybindings.cfg"; ini.loadFromFile( confPath + "config.cfg" ); iniState.loadFromFile( confPath + "state.cfg" ); @@ -53,10 +53,22 @@ void AppConfig::load( const std::string& confPath, std::string& keybindingsPath, recentFolders = urlDecode( String::split( recentFol, ';' ) ); initColorScheme = editor.colorScheme = ini.getValue( "editor", "colorscheme", "eepp" ); editor.fontSize = ini.getValue( "editor", "font_size", "11dp" ); - windowState.size.setWidth( - iniState.getValueI( "window", "width", displayDPI > 105 ? 1920 : 1280 ) ); - windowState.size.setHeight( - iniState.getValueI( "window", "height", displayDPI > 105 ? 1080 : 720 ) ); + const Sizei desiredRes( 1280, 720 ); + Sizei defWinSize( desiredRes.getWidth(), desiredRes.getHeight() ); + if ( displaySize.getWidth() > desiredRes.getWidth() && + displaySize.getWidth() - desiredRes.getWidth() > 60 ) { + defWinSize.setWidth( desiredRes.getWidth() ); + } else { + defWinSize.setWidth( displaySize.getWidth() - 60 ); + } + if ( displaySize.getHeight() > desiredRes.getHeight() && + displaySize.getHeight() - desiredRes.getHeight() > 60 ) { + defWinSize.setHeight( desiredRes.getHeight() ); + } else { + defWinSize.setHeight( displaySize.getHeight() - 60 ); + } + windowState.size.setWidth( iniState.getValueI( "window", "width", defWinSize.getWidth() ) ); + windowState.size.setHeight( iniState.getValueI( "window", "height", defWinSize.getHeight() ) ); windowState.maximized = iniState.getValueB( "window", "maximized", false ); windowState.pixelDensity = iniState.getValueF( "window", "pixeldensity" ); windowState.winIcon = ini.getValue( "window", "winicon", resPath + "icon/ee.png" ); diff --git a/src/tools/ecode/appconfig.hpp b/src/tools/ecode/appconfig.hpp index 105bb6909..ca9adbea3 100644 --- a/src/tools/ecode/appconfig.hpp +++ b/src/tools/ecode/appconfig.hpp @@ -126,7 +126,7 @@ struct AppConfig { void load( const std::string& confPath, std::string& keybindingsPath, std::string& initColorScheme, std::vector& recentFiles, std::vector& recentFolders, const std::string& resPath, - const Float& displayDPI, PluginManager* pluginManager ); + PluginManager* pluginManager, const Sizei& displaySize ); void save( const std::vector& recentFiles, const std::vector& recentFolders, const std::string& panelPartition, diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index 3b0496f46..fcda8301c 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -6,8 +6,10 @@ #include "version.hpp" #include #include +#include #include using json = nlohmann::json; +namespace fs = std::filesystem; #ifdef ECODE_USE_BACKWARD #if EE_PLATFORM == EE_PLATFORM_LINUX @@ -374,7 +376,7 @@ void App::initPluginManager() { mPluginManager->registerPlugin( LSPClientPlugin::Definition() ); } -void App::loadConfig( const LogLevel& logLevel ) { +void App::loadConfig( const LogLevel& logLevel, const Sizeu& displaySize ) { mConfigPath = Sys::getConfigPath( "ecode" ); if ( !FileSystem::fileExists( mConfigPath ) ) FileSystem::makeDir( mConfigPath ); @@ -400,7 +402,7 @@ void App::loadConfig( const LogLevel& logLevel ) { initPluginManager(); mConfig.load( mConfigPath, mKeybindingsPath, mInitColorScheme, mRecentFiles, mRecentFolders, - mResPath, mDisplayDPI, mPluginManager.get() ); + mResPath, mPluginManager.get(), displaySize.asInt() ); } void App::saveConfig() { @@ -3105,11 +3107,15 @@ UIMessageBox* App::fileAlreadyExistsMsgBox() { return errorMsgBox( i18n( "file_already_exists", "File already exists!" ) ); } -std::string getNewFilePath( const FileInfo& file, UIMessageBox* msgBox ) { - auto folderName( msgBox->getTextInput()->getText() ); +std::string getNewFilePath( const FileInfo& file, UIMessageBox* msgBox, bool keepDir = true ) { + auto fileName( msgBox->getTextInput()->getText().toUtf8() ); auto folderPath( file.getDirectoryPath() ); + if ( file.isDirectory() && !keepDir ) { + FileSystem::dirRemoveSlashAtEnd( folderPath ); + folderPath = FileSystem::fileRemoveFileName( folderPath ); + } FileSystem::dirAddSlashAtEnd( folderPath ); - return folderPath + folderName; + return folderPath + fileName; } UIMessageBox* newInputMsgBox( const String& title, const String& msg ) { @@ -3128,10 +3134,16 @@ void App::renameFile( const FileInfo& file ) { i18n( "enter_new_file_name", "Enter new file name:" ) ); msgBox->getTextInput()->setText( file.getFileName() ); msgBox->addEventListener( Event::MsgBoxConfirmClick, [&, file, msgBox]( const Event* ) { - auto newFilePath( getNewFilePath( file, msgBox ) ); + auto newFilePath( getNewFilePath( file, msgBox, false ) ); if ( !FileSystem::fileExists( newFilePath ) ) { - if ( 0 != std::rename( file.getFilepath().c_str(), newFilePath.c_str() ) ) + try { + std::string fpath( file.getFilepath() ); + if ( file.isDirectory() ) + FileSystem::dirRemoveSlashAtEnd( fpath ); + fs::rename( fpath, newFilePath ); + } catch ( const fs::filesystem_error& err ) { errorMsgBox( i18n( "error_renaming_file", "Error renaming file." ) ); + } msgBox->closeWindow(); } else { fileAlreadyExistsMsgBox(); @@ -3216,8 +3228,20 @@ void App::newFile( const FileInfo& file ) { msgBox->addEventListener( Event::MsgBoxConfirmClick, [&, file, msgBox]( const Event* ) { auto newFilePath( getNewFilePath( file, msgBox ) ); if ( !FileSystem::fileExists( newFilePath ) ) { - if ( !FileSystem::fileWrite( newFilePath, nullptr, 0 ) ) + if ( !FileSystem::fileWrite( newFilePath, nullptr, 0 ) ) { errorMsgBox( i18n( "couldnt_create_file", "Couldn't create file." ) ); + } else if ( mProjectTreeView ) { + // We wait 100 ms to get the notification from the file system + mUISceneNode->runOnMainThread( + [&, newFilePath] { + if ( !mFileSystemModel || !mProjectTreeView ) + return; + std::string nfp( newFilePath ); + FileSystem::filePathRemoveBasePath( mFileSystemModel->getRootPath(), nfp ); + mProjectTreeView->selectRowWithPath( nfp ); + }, + Milliseconds( 100 ) ); + } msgBox->closeWindow(); } else { fileAlreadyExistsMsgBox(); @@ -3232,8 +3256,20 @@ void App::newFolder( const FileInfo& file ) { msgBox->addEventListener( Event::MsgBoxConfirmClick, [&, file, msgBox]( const Event* ) { auto newFolderPath( getNewFilePath( file, msgBox ) ); if ( !FileSystem::fileExists( newFolderPath ) ) { - if ( !FileSystem::makeDir( newFolderPath ) ) + if ( !FileSystem::makeDir( newFolderPath ) ) { errorMsgBox( i18n( "couldnt_create_directory", "Couldn't create directory." ) ); + } else if ( mProjectTreeView ) { + // We wait 100 ms to get the notification from the file system + mUISceneNode->runOnMainThread( + [&, newFolderPath] { + if ( !mFileSystemModel || !mProjectTreeView ) + return; + std::string nfp( newFolderPath ); + FileSystem::filePathRemoveBasePath( mFileSystemModel->getRootPath(), nfp ); + mProjectTreeView->selectRowWithPath( nfp ); + }, + Milliseconds( 100 ) ); + } msgBox->closeWindow(); } else { fileAlreadyExistsMsgBox(); @@ -3319,12 +3355,6 @@ void App::createProjectTreeMenu( const FileInfo& file ) { } else if ( "open_file" == id ) { loadFileFromPath( file.getFilepath() ); } else if ( "remove" == id ) { - if ( file.isDirectory() && !FileSystem::filesGetInPath( file.getFilepath() ).empty() ) { - errorMsgBox( - i18n( "cannot_remove_non_empty_dir", "Cannot remove non-empty directory." ) ); - return; - } - UIMessageBox* msgBox = UIMessageBox::New( UIMessageBox::OK_CANCEL, String::format( i18n( "confirm_remove_file", @@ -3333,12 +3363,24 @@ void App::createProjectTreeMenu( const FileInfo& file ) { .c_str(), file.getFileName().c_str() ) ); msgBox->addEventListener( Event::MsgBoxConfirmClick, [&, file, msgBox]( const Event* ) { - if ( !FileSystem::fileRemove( file.getFilepath() ) ) { + auto errFn = [&, file] { errorMsgBox( String::format( std::string( i18n( "couldnt_remove", "Couldn't remove" ).toUtf8() + "%s." ) .c_str(), file.isDirectory() ? i18n( "directory", "directory" ).toUtf8().c_str() : i18n( "file", "file" ).toUtf8().c_str() ) ); + }; + + if ( file.isDirectory() ) { + try { + std::string fpath( file.getFilepath() ); + FileSystem::dirRemoveSlashAtEnd( fpath ); + fs::remove_all( fpath ); + } catch ( const fs::filesystem_error& err ) { + errFn(); + } + } else if ( !FileSystem::fileRemove( file.getFilepath() ) ) { + errFn(); } msgBox->closeWindow(); } ); @@ -3575,7 +3617,7 @@ void App::init( const LogLevel& logLevel, std::string file, const Float& pidelDe mResPath += "assets"; FileSystem::dirAddSlashAtEnd( mResPath ); - loadConfig( logLevel ); + loadConfig( logLevel, currentDisplay->getSize() ); currentDisplay = displayManager->getDisplayIndex( mConfig.windowState.displayIndex < displayManager->getDisplayCount() @@ -3624,6 +3666,11 @@ void App::init( const LogLevel& logLevel, std::string file, const Float& pidelDe mWindow->setPosition( mConfig.windowState.position.x, mConfig.windowState.position.y ); } + if ( mWindow->isWindowed() && mWindow->getSize() >= currentDisplay->getSize().asInt() ) { + mWindow->setPosition( mWindow->getBorderSize().getWidth(), + mWindow->getBorderSize().getHeight() ); + } + loadKeybindings(); PixelDensity::setPixelDensity( mConfig.windowState.pixelDensity ); diff --git a/src/tools/ecode/ecode.hpp b/src/tools/ecode/ecode.hpp index 912d2e875..b16587abd 100644 --- a/src/tools/ecode/ecode.hpp +++ b/src/tools/ecode/ecode.hpp @@ -53,7 +53,7 @@ class App : public UICodeEditorSplitter::Client { void runCommand( const std::string& command ); - void loadConfig( const LogLevel& logLevel ); + void loadConfig( const LogLevel& logLevel, const Sizeu& displaySize ); void saveConfig(); diff --git a/src/tools/ecode/plugins/lsp/lspclientplugin.cpp b/src/tools/ecode/plugins/lsp/lspclientplugin.cpp index baad63c93..70e681c8d 100644 --- a/src/tools/ecode/plugins/lsp/lspclientplugin.cpp +++ b/src/tools/ecode/plugins/lsp/lspclientplugin.cpp @@ -528,6 +528,7 @@ bool LSPClientPlugin::onMouseMove( UICodeEditor* editor, const Vector2i& positio position.asFloat() ) ); editor->getTooltip()->setDontAutoHideOnMouseMove( true ); editor->getTooltip()->setUsingCustomStyling( true ); + editor->getTooltip()->setFontStyle( Text::Regular ); const auto& syntaxDef = resp.contents[0].kind == LSPMarkupKind::MarkDown