diff --git a/bin/assets/ui/breeze.css b/bin/assets/ui/breeze.css
index 024751261..1a0c2bc36 100644
--- a/bin/assets/ui/breeze.css
+++ b/bin/assets/ui/breeze.css
@@ -539,7 +539,7 @@ Tab {
height: 24dp;
transition: background-color 0.15s;
foreground-image: linear-gradient( to top, var(--tab-line), var(--tab-back));
- foreground-size: 1dp 80%;
+ foreground-size: 1dprd 80%;
foreground-position: right bottom;
}
@@ -586,9 +586,6 @@ Tab::close {
width: 10dp;
height: 10dp;
border-radius: 5dp;
- /*background-color: var(--tab-close);
- foreground-image: poly(line, var(--icon-line-hover), "0dp 0dp, 5dp 5dp"), poly(line, var(--icon-line-hover), "5dp 0dp, 0dp 5dp");
- foreground-position: 2.5dp 2.5dp, 2.5dp 2.5dp;*/
foreground-image: url("data:image/svg,");
foreground-tint: var(--tab-close);
foreground-size: 10dp 10dp;
@@ -597,7 +594,6 @@ Tab::close {
}
Tab::close:hover {
- /*background-color: var(--tab-close-hover);*/
foreground-tint: var(--tab-close-hover);
}
diff --git a/docs/articles/cssspecification.md b/docs/articles/cssspecification.md
index 2ba7efdd6..4db92d92c 100644
--- a/docs/articles/cssspecification.md
+++ b/docs/articles/cssspecification.md
@@ -27,8 +27,7 @@ the CSS file.
* eepp CSS supports alternative path methods besides paths (resource locator to previously loaded
resources by the process).
-* eepp CSS supports [Device-independent
-pixel](https://en.wikipedia.org/wiki/Device-independent_pixel) unit `dp`.
+* eepp CSS supports [Device-independent pixel](https://en.wikipedia.org/wiki/Device-independent_pixel) unit `dp`.
* CSS files should be always UTF-8 encoded.
@@ -2461,6 +2460,8 @@ Read [length](https://developer.mozilla.org/en-US/docs/Web/CSS/length) documenta
* Supported lenghts: `em`, `rem`, `pt`, `pc`, `in`, `cm`, `mm`, `vw`, `vh`, `vmin`, `vmax`.
+* Also adds: `dp` as [Device-independent pixel](https://en.wikipedia.org/wiki/Device-independent_pixel). Plus `dprd` (dp rounded down) and `dpru` (dp rounded up).
+
---
### length-percentage (data-type)
diff --git a/include/eepp/ui/css/stylesheetlength.hpp b/include/eepp/ui/css/stylesheetlength.hpp
index 9b2011715..3976a998f 100644
--- a/include/eepp/ui/css/stylesheetlength.hpp
+++ b/include/eepp/ui/css/stylesheetlength.hpp
@@ -30,6 +30,8 @@ class EE_API StyleSheetLength {
Vmin,
Vmax,
Rem,
+ Dprd,
+ Dpru,
};
static Unit unitFromString( std::string unitStr );
@@ -64,7 +66,7 @@ class EE_API StyleSheetLength {
StyleSheetLength& operator=( const Float& val );
- static StyleSheetLength fromString( std::string str, const Float& defaultValue = 0 );
+ static StyleSheetLength fromString( const std::string& str, const Float& defaultValue = 0 );
std::string toString() const;
diff --git a/include/eepp/ui/css/stylesheetselector.hpp b/include/eepp/ui/css/stylesheetselector.hpp
index ca5c7b8bd..f70239221 100644
--- a/include/eepp/ui/css/stylesheetselector.hpp
+++ b/include/eepp/ui/css/stylesheetselector.hpp
@@ -21,14 +21,13 @@ class EE_API StyleSheetSelector {
bool select( UIWidget* element, const bool& applyPseudo = true ) const;
- const bool& isCacheable() const;
+ bool isCacheable() const;
bool hasPseudoClasses() const;
- std::vector getRelatedElements( UIWidget* element,
- const bool& applyPseudo = true ) const;
+ std::vector getRelatedElements( UIWidget* element, bool applyPseudo = true ) const;
- const bool& isStructurallyVolatile() const;
+ bool isStructurallyVolatile() const;
const StyleSheetSelectorRule& getRule( const Uint32& index );
diff --git a/projects/linux/ee.creator.user b/projects/linux/ee.creator.user
index e8eeb3ad6..8109aad79 100644
--- a/projects/linux/ee.creator.user
+++ b/projects/linux/ee.creator.user
@@ -1,6 +1,6 @@
-
+
EnvironmentId
@@ -1215,6 +1215,7 @@
ecode-debug
ProjectExplorer.CustomExecutableRunConfiguration
+ --css=/root/.config/ecode/style.css
0
false
1
diff --git a/src/eepp/ui/css/stylesheetlength.cpp b/src/eepp/ui/css/stylesheetlength.cpp
index a38a42214..ddb9cfb4b 100644
--- a/src/eepp/ui/css/stylesheetlength.cpp
+++ b/src/eepp/ui/css/stylesheetlength.cpp
@@ -4,45 +4,115 @@
#include
using namespace EE::Graphics;
+using namespace std::literals;
namespace EE { namespace UI { namespace CSS {
+enum UnitHashes : String::HashType {
+ Percentage = String::hash( "%" ),
+ In = String::hash( "in" ),
+ Cm = String::hash( "cm" ),
+ Mm = String::hash( "mm" ),
+ Em = String::hash( "em" ),
+ Ex = String::hash( "ex" ),
+ Pt = String::hash( "pt" ),
+ Pc = String::hash( "pc" ),
+ Px = String::hash( "px" ),
+ Dpi = String::hash( "dpi" ),
+ Dp = String::hash( "dp" ),
+ Dpcm = String::hash( "dpcm" ),
+ Vw = String::hash( "vw" ),
+ Vh = String::hash( "vh" ),
+ Vmin = String::hash( "vmin" ),
+ Vmax = String::hash( "vmax" ),
+ Rem = String::hash( "rem" ),
+ Dprd = String::hash( "dprd" ),
+ Dpru = String::hash( "dpru" ),
+};
+
+enum PercentagePositions : String::HashType {
+ Center = String::hash( "center" ),
+ Left = String::hash( "left" ),
+ Right = String::hash( "right" ),
+ Top = String::hash( "top" ),
+ Bottom = String::hash( "bottom" ),
+ None = 0,
+};
+
+static std::string positionToPercentage( const PercentagePositions& pos ) {
+ switch ( pos ) {
+ case Center:
+ return "50%";
+ case Left:
+ case Top:
+ return "0%";
+ case Right:
+ case Bottom:
+ return "100%";
+ default:
+ case None:
+ return "";
+ }
+}
+
+static PercentagePositions isPercentagePosition( const String::HashType& strHash ) {
+ switch ( strHash ) {
+ case PercentagePositions::Center:
+ return PercentagePositions::Center;
+ case PercentagePositions::Left:
+ return PercentagePositions::Left;
+ case PercentagePositions::Right:
+ return PercentagePositions::Right;
+ case PercentagePositions::Top:
+ return PercentagePositions::Top;
+ case PercentagePositions::Bottom:
+ return PercentagePositions::Bottom;
+ }
+ return PercentagePositions::None;
+}
+
StyleSheetLength::Unit StyleSheetLength::unitFromString( std::string unitStr ) {
String::toLowerInPlace( unitStr );
- if ( "%" == unitStr )
- return Unit::Percentage;
- else if ( "dp" == unitStr )
- return Unit::Dp;
- else if ( "px" == unitStr )
- return Unit::Px;
- else if ( "in" == unitStr )
- return Unit::In;
- else if ( "cm" == unitStr )
- return Unit::Cm;
- else if ( "mm" == unitStr )
- return Unit::Mm;
- else if ( "em" == unitStr )
- return Unit::Em;
- else if ( "ex" == unitStr )
- return Unit::Ex;
- else if ( "pt" == unitStr )
- return Unit::Pt;
- else if ( "pc" == unitStr )
- return Unit::Pc;
- else if ( "dpi" == unitStr )
- return Unit::Dpi;
- else if ( "dpcm" == unitStr )
- return Unit::Dpcm;
- else if ( "vw" == unitStr )
- return Unit::Vw;
- else if ( "vh" == unitStr )
- return Unit::Vh;
- else if ( "vmin" == unitStr )
- return Unit::Vmin;
- else if ( "vmax" == unitStr )
- return Unit::Vmax;
- else if ( "rem" == unitStr )
- return Unit::Rem;
+ switch ( String::hash( unitStr ) ) {
+ case UnitHashes::Percentage:
+ return Unit::Percentage;
+ case UnitHashes::Dp:
+ return Unit::Dp;
+ case UnitHashes::Px:
+ return Unit::Px;
+ case UnitHashes::In:
+ return Unit::In;
+ case UnitHashes::Cm:
+ return Unit::Cm;
+ case UnitHashes::Mm:
+ return Unit::Mm;
+ case UnitHashes::Em:
+ return Unit::Em;
+ case UnitHashes::Ex:
+ return Unit::Ex;
+ case UnitHashes::Pt:
+ return Unit::Pt;
+ case UnitHashes::Pc:
+ return Unit::Pc;
+ case UnitHashes::Dpi:
+ return Unit::Dpi;
+ case UnitHashes::Dpcm:
+ return Unit::Dpcm;
+ case UnitHashes::Vw:
+ return Unit::Vw;
+ case UnitHashes::Vh:
+ return Unit::Vh;
+ case UnitHashes::Vmin:
+ return Unit::Vmin;
+ case UnitHashes::Vmax:
+ return Unit::Vmax;
+ case UnitHashes::Rem:
+ return Unit::Rem;
+ case UnitHashes::Dprd:
+ return Unit::Dprd;
+ case UnitHashes::Dpru:
+ return Unit::Dpru;
+ }
return Unit::Px;
}
@@ -82,6 +152,10 @@ std::string StyleSheetLength::unitToString( const StyleSheetLength::Unit& unit )
return "vmax";
case Unit::Rem:
return "rem";
+ case Unit::Dprd:
+ return "dprd";
+ case Unit::Dpru:
+ return "dpru";
}
return "px";
}
@@ -123,6 +197,12 @@ Float StyleSheetLength::asPixels( const Float& parentSize, const Sizef& viewSize
case Unit::Dp:
ret = PixelDensity::dpToPx( mValue );
break;
+ case Unit::Dprd:
+ ret = roundDown( PixelDensity::dpToPx( mValue ) );
+ break;
+ case Unit::Dpru:
+ ret = roundUp( PixelDensity::dpToPx( mValue ) );
+ break;
case Unit::Em:
ret = Math::round( mValue * elFontSize );
break;
@@ -190,22 +270,15 @@ StyleSheetLength& StyleSheetLength::operator=( const StyleSheetLength& val ) {
return *this;
}
-static std::string positionToPercentage( const std::string& pos ) {
- if ( pos == "center" )
- return "50%";
- if ( pos == "left" || pos == "top" )
- return "0%";
- if ( pos == "right" || pos == "bottom" )
- return "100%";
- return pos;
-}
+StyleSheetLength StyleSheetLength::fromString( const std::string& str, const Float& defaultValue ) {
+ PercentagePositions isPercentage = isPercentagePosition( String::hash( str ) );
+ if ( PercentagePositions::None != isPercentage )
+ return fromString( positionToPercentage( isPercentage ), defaultValue );
-StyleSheetLength StyleSheetLength::fromString( std::string str, const Float& defaultValue ) {
StyleSheetLength length;
length.setValue( defaultValue, Unit::Px );
std::string num;
std::string unit;
- str = positionToPercentage( str );
for ( std::size_t i = 0; i < str.size(); i++ ) {
if ( String::isNumber( str[i], true ) || ( '-' == str[i] && i == 0 ) ||
@@ -219,11 +292,8 @@ StyleSheetLength StyleSheetLength::fromString( std::string str, const Float& def
if ( !num.empty() ) {
Float val = 0;
- bool res = String::fromString( val, num );
-
- if ( res ) {
+ if ( String::fromString( val, num ) )
length.setValue( val, unitFromString( unit ) );
- }
}
return length;
@@ -233,7 +303,8 @@ std::string StyleSheetLength::toString() const {
std::string res;
if ( (Int64)mValue == mValue )
res = String::format( "%lld%s", (Int64)mValue, unitToString( mUnit ).c_str() );
- res = String::format( "%.2f%s", mValue, unitToString( mUnit ).c_str() );
+ else
+ res = String::format( "%.2f%s", mValue, unitToString( mUnit ).c_str() );
String::replace( res, ",", "." );
return res;
}
diff --git a/src/eepp/ui/css/stylesheetselector.cpp b/src/eepp/ui/css/stylesheetselector.cpp
index 035592232..abcd0e764 100644
--- a/src/eepp/ui/css/stylesheetselector.cpp
+++ b/src/eepp/ui/css/stylesheetselector.cpp
@@ -109,7 +109,7 @@ void StyleSheetSelector::parseSelector( std::string selector ) {
}
}
-const bool& StyleSheetSelector::isCacheable() const {
+bool StyleSheetSelector::isCacheable() const {
return mCacheable;
}
@@ -210,7 +210,7 @@ bool StyleSheetSelector::select( UIWidget* element, const bool& applyPseudo ) co
}
std::vector StyleSheetSelector::getRelatedElements( UIWidget* element,
- const bool& applyPseudo ) const {
+ bool applyPseudo ) const {
static std::vector EMPTY_ELEMENTS;
std::vector elements;
if ( mSelectorRules.empty() )
@@ -331,7 +331,7 @@ std::vector StyleSheetSelector::getRelatedElements( UIWidget* element
return elements;
}
-const bool& StyleSheetSelector::isStructurallyVolatile() const {
+bool StyleSheetSelector::isStructurallyVolatile() const {
return mStructurallyVolatile;
}
diff --git a/src/eepp/ui/uinodedrawable.cpp b/src/eepp/ui/uinodedrawable.cpp
index d99ca49f9..fc43358a2 100644
--- a/src/eepp/ui/uinodedrawable.cpp
+++ b/src/eepp/ui/uinodedrawable.cpp
@@ -656,7 +656,7 @@ void UINodeDrawable::LayerDrawable::update() {
setDrawable( mDrawableRef );
}
- mDrawableSize = calcDrawableSize( mSizeEq ).roundDown();
+ mDrawableSize = calcDrawableSize( mSizeEq );
mOffset = calcPosition( mPositionX + " " + mPositionY );
mNeedsUpdate = false;
diff --git a/src/eepp/ui/uitabwidget.cpp b/src/eepp/ui/uitabwidget.cpp
index 4b1120670..34e61048f 100644
--- a/src/eepp/ui/uitabwidget.cpp
+++ b/src/eepp/ui/uitabwidget.cpp
@@ -482,6 +482,7 @@ UITab* UITabWidget::createTab( const String& text, UINode* nodeOwned, Drawable*
tab->setVisible( true );
tab->setEnabled( true );
tab->setOwnedWidget( nodeOwned );
+ tab->reloadStyle( true, true, true );
if ( tab->getCloseButton() ) {
tab->getCloseButton()
->setVisible( mStyleConfig.TabsClosable && mStyleConfig.TabCloseButtonVisible )
@@ -752,9 +753,7 @@ UITab* UITabWidget::setTabSelected( UITab* tab ) {
if ( tab->getOwnedWidget() )
tab->getOwnedWidget()->setFocus();
return tab;
- }
-
- if ( NULL != mTabSelected ) {
+ } else if ( NULL != mTabSelected ) {
mTabSelected->unselect();
if ( NULL != mTabSelected->getOwnedWidget() ) {
diff --git a/src/tools/ecode/applayout.xml.hpp b/src/tools/ecode/applayout.xml.hpp
index 6a5fd3f3e..e4d7ae2c9 100644
--- a/src/tools/ecode/applayout.xml.hpp
+++ b/src/tools/ecode/applayout.xml.hpp
@@ -390,6 +390,13 @@ Anchor.error:hover {
#code_container > TabWidget > TabWidget::TabBar > Tab > Tab::Text {
text-overflow: ellipsis;
}
+#code_container > TabWidget > TabWidget::TabBar > Tab > Tab::close {
+ opacity: 0;
+}
+#code_container > TabWidget > TabWidget::TabBar > Tab:selected > Tab::close,
+#code_container > TabWidget > TabWidget::TabBar > Tab:hover > Tab::close {
+ opacity: 1;
+}
diff --git a/src/tools/ecode/projectdirectorytree.cpp b/src/tools/ecode/projectdirectorytree.cpp
index 92125625d..1336da534 100644
--- a/src/tools/ecode/projectdirectorytree.cpp
+++ b/src/tools/ecode/projectdirectorytree.cpp
@@ -15,12 +15,14 @@ ProjectDirectoryTree::ProjectDirectoryTree( const std::string& path,
mRunning( false ),
mIsReady( false ),
mIgnoreHidden( true ),
+ mClosing( false ),
mIgnoreMatcher( path ),
mApp( app ) {
FileSystem::dirAddSlashAtEnd( mPath );
}
ProjectDirectoryTree::~ProjectDirectoryTree() {
+ mClosing = true;
if ( mApp->getPluginManager() )
mApp->getPluginManager()->unsubscribeMessages( "ProjectDirectoryTree" );
Lock rl( mMatchingMutex );
@@ -28,6 +30,9 @@ ProjectDirectoryTree::~ProjectDirectoryTree() {
mRunning = false;
Lock l( mFilesMutex );
}
+ {
+ Lock l( mDoneMutex );
+ }
}
void ProjectDirectoryTree::scan( const ProjectDirectoryTree::ScanCompleteEvent& scanComplete,
@@ -76,7 +81,6 @@ void ProjectDirectoryTree::scan( const ProjectDirectoryTree::ScanCompleteEvent&
mAllowedMatcher.get() );
}
mIsReady = true;
- mRunning = false;
mApp->getPluginManager()->subscribeMessages(
"ProjectDirectoryTree", [this]( const PluginMessage& msg ) -> PluginRequestHandle {
return processMessage( msg );
@@ -88,8 +92,11 @@ void ProjectDirectoryTree::scan( const ProjectDirectoryTree::ScanCompleteEvent&
#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ )
},
[scanComplete, this]( const auto& ) {
- if ( scanComplete )
+ if ( !mClosing && scanComplete ) {
+ Lock l( mDoneMutex );
scanComplete( *this );
+ }
+ mRunning = false;
} );
#endif
}
@@ -324,7 +331,8 @@ void ProjectDirectoryTree::tryAddFile( const FileInfo& file ) {
}
if ( foundPattern ) {
Lock l( mFilesMutex );
- auto exists = std::find( mFiles.begin(), mFiles.end(), file.getFilepath() ) != mFiles.end();
+ auto exists =
+ std::find( mFiles.begin(), mFiles.end(), file.getFilepath() ) != mFiles.end();
if ( !exists ) {
mFiles.emplace_back( file.getFilepath() );
mNames.emplace_back( file.getFileName() );
diff --git a/src/tools/ecode/projectdirectorytree.hpp b/src/tools/ecode/projectdirectorytree.hpp
index c204f1de9..4e1526fbb 100644
--- a/src/tools/ecode/projectdirectorytree.hpp
+++ b/src/tools/ecode/projectdirectorytree.hpp
@@ -158,8 +158,10 @@ class ProjectDirectoryTree {
bool mRunning;
bool mIsReady;
bool mIgnoreHidden;
+ bool mClosing;
mutable Mutex mFilesMutex;
mutable Mutex mMatchingMutex;
+ Mutex mDoneMutex;
IgnoreMatcherManager mIgnoreMatcher;
App* mApp{ nullptr };