diff --git a/TODO.md b/TODO.md index 5cde8d271..76ba69f6e 100644 --- a/TODO.md +++ b/TODO.md @@ -1,10 +1,6 @@ # TODO - Short and mid term plans. -## Graphics Module - -* Add support for font packs/families (separate fonts for regular/bold/italics). - ## UI Module * Implement a Rich Text View. diff --git a/docs/articles/cssspecification.md b/docs/articles/cssspecification.md index 8a4de115a..2ba7efdd6 100644 --- a/docs/articles/cssspecification.md +++ b/docs/articles/cssspecification.md @@ -859,7 +859,7 @@ the load can't be determined. ### inner-widget-orientation -PushButton can contain 3 widgets: the text (textbox), the icon, and a custom extra +PushButton can contain 3 widgets: the text (textbox), the icon, and a custom extra item. And with these 3 items does its own layouting. This property allows configuring the order in which these items are displayed/sorted inside the button. @@ -1763,6 +1763,12 @@ When enabled will only display text if the icon is not set/found. --- +### text-overflow + +Read [text-overflow](https://developer.mozilla.org/en-US/docs/Web/CSS/text-overflow) documentation. + +--- + ### text-selection Enables/disables text selection in any element that contains text. diff --git a/include/eepp/core/string.hpp b/include/eepp/core/string.hpp index df3b0b694..c12b7f309 100644 --- a/include/eepp/core/string.hpp +++ b/include/eepp/core/string.hpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -461,6 +460,11 @@ class EE_API String { **/ String( const String& str ); + /** @brief Copy constructor + ** @param str Instance to copy + **/ + String( const String::View& str ); + /** @brief Create a new String from a UTF-8 encoded string ** @param begin Forward iterator to the begining of the UTF-8 sequence ** @param end Forward iterator to the end of the UTF-8 sequence diff --git a/include/eepp/graphics/text.hpp b/include/eepp/graphics/text.hpp index ad5636853..815d07c61 100644 --- a/include/eepp/graphics/text.hpp +++ b/include/eepp/graphics/text.hpp @@ -65,6 +65,28 @@ class EE_API Text { const Uint32& tabWidth = 4, const Float& outlineThickness = 0.f ); + static std::size_t findLastCharPosWithinLength( Font* font, const Uint32& fontSize, + const String& string, Float maxWidth, + const Uint32& style, + const Uint32& tabWidth = 4, + const Float& outlineThickness = 0.f ); + + static std::size_t findLastCharPosWithinLength( Font* font, const Uint32& fontSize, + const String::View& string, Float maxWidth, + const Uint32& style, + const Uint32& tabWidth = 4, + const Float& outlineThickness = 0.f ); + + static std::size_t findLastCharPosWithinLength( const String& string, + Float maxWidth, + const FontStyleConfig& config, + const Uint32& tabWidth = 4 ); + + static std::size_t findLastCharPosWithinLength( const String::View& string, + Float maxWidth, + const FontStyleConfig& config, + const Uint32& tabWidth = 4 ); + static Text* New(); static Text* New( const String& string, Font* font, @@ -85,6 +107,8 @@ class EE_API Text { Color FontShadowColor = Color( 0, 0, 0, 255 ), Uint32 characterSize = PixelDensity::dpToPx( 12 ) ); + void setString( const String::View& string ); + void setString( const String& string ); void setString( String&& string ); @@ -280,6 +304,12 @@ class EE_API Text { template static Sizef draw( const StringType& string, const Vector2f& pos, const FontStyleConfig& config, const Uint32& tabWidth = 4 ); + + template + static std::size_t + findLastCharPosWithinLength( Font* font, const Uint32& fontSize, const StringType& string, + Float width, const Uint32& style, const Uint32& tabWidth = 4, + const Float& outlineThickness = 0.f ); }; }} // namespace EE::Graphics diff --git a/include/eepp/ui/css/propertydefinition.hpp b/include/eepp/ui/css/propertydefinition.hpp index c79ca36c3..f1db84896 100644 --- a/include/eepp/ui/css/propertydefinition.hpp +++ b/include/eepp/ui/css/propertydefinition.hpp @@ -215,6 +215,7 @@ enum class PropertyId : Uint32 { Glyph = String::hash( "glyph" ), Name = String::hash( "name" ), RowValign = String::hash( "row-valign" ), + TextOverflow = String::hash( "text-overflow" ), }; enum class PropertyType : Uint32 { diff --git a/include/eepp/ui/uitabwidget.hpp b/include/eepp/ui/uitabwidget.hpp index e1b86284a..932b16889 100644 --- a/include/eepp/ui/uitabwidget.hpp +++ b/include/eepp/ui/uitabwidget.hpp @@ -4,7 +4,6 @@ #include #include #include -#include namespace EE { namespace UI { diff --git a/include/eepp/ui/uitextview.hpp b/include/eepp/ui/uitextview.hpp index e7d6b92a2..0d5ee0130 100644 --- a/include/eepp/ui/uitextview.hpp +++ b/include/eepp/ui/uitextview.hpp @@ -106,6 +106,12 @@ class EE_API UITextView : public UIWidget { virtual void loadFromXmlNode( const pugi::xml_node& node ); + UITextView* setTextOverflow( const std::string_view& textOverflow ); + + const std::string& getTextOverflow() const; + + bool hasTextOverflow() const; + protected: Text* mTextCache; String mString; @@ -124,6 +130,8 @@ class EE_API UITextView : public UIWidget { Int32 mLastSelCurEnd; Int32 mFontLineCenter; bool mSelecting; + std::string mTextOverflow; + Float mTextOverflowWidth{ 0 }; TextTransform::Value mTextTransform{ TextTransform::None }; virtual void drawSelection( Text* textCache ); @@ -171,6 +179,8 @@ class EE_API UITextView : public UIWidget { void recalculate(); void resetSelCache(); + + void updateTextOverflow(); }; class EE_API UIAnchor : public UITextView { diff --git a/src/eepp/core/string.cpp b/src/eepp/core/string.cpp index 99079ba31..c3e8c11f6 100644 --- a/src/eepp/core/string.cpp +++ b/src/eepp/core/string.cpp @@ -1061,6 +1061,8 @@ String::String( const StringType& utf32String ) : mString( utf32String ) {} String::String( const String& str ) : mString( str.mString ) {} +String::String( const String::View& utf32String ) : mString( utf32String ) {} + String String::fromUtf8( const std::string& utf8String ) { String::StringType utf32; diff --git a/src/eepp/graphics/fontfamily.cpp b/src/eepp/graphics/fontfamily.cpp index 6848a1d81..c8ca1ea79 100644 --- a/src/eepp/graphics/fontfamily.cpp +++ b/src/eepp/graphics/fontfamily.cpp @@ -29,7 +29,7 @@ void FontFamily::loadFromRegular( FontTrueType* font, std::string overwriteFontN setFont( font, findType( font->getInfo().fontpath, fontname, ext, - { "Italic", "Oblique", "italic", "oblique", "It", "it" } ), + { "Italic"sv, "Oblique"sv, "italic"sv, "oblique"sv, "It"sv, "it"sv } ), "italic"sv ); setFont( diff --git a/src/eepp/graphics/text.cpp b/src/eepp/graphics/text.cpp index fff46e8ef..a5792512d 100644 --- a/src/eepp/graphics/text.cpp +++ b/src/eepp/graphics/text.cpp @@ -369,6 +369,13 @@ void Text::onNewString() { } } +void Text::setString( const String::View& string ) { + if ( mString.view() != string ) { + mString = string; + onNewString(); + } +} + void Text::setString( const String& string ) { if ( mString != string ) { mString = string; @@ -583,18 +590,49 @@ Float Text::getTextWidth( Font* font, const Uint32& fontSize, const StringType& if ( rune != '\r' && rune != '\t' ) { width += font->getKerning( prevChar, rune, fontSize, bold, italic, outlineThickness ); width += glyph.advance; - } else if ( rune == '\t' ) { + } else if ( rune == '\t' ) width += hspace * tabWidth; - } - if ( rune == '\n' ) { + + if ( rune == '\n' ) width = 0; - } maxWidth = eemax( width, maxWidth ); prevChar = rune; } return maxWidth; } +template +std::size_t Text::findLastCharPosWithinLength( Font* font, const Uint32& fontSize, + const StringType& string, Float maxWidth, + const Uint32& style, const Uint32& tabWidth, + const Float& outlineThickness ) { + if ( NULL == font || string.empty() ) + return 0; + String::StringBaseType rune; + Uint32 prevChar = 0; + Float width = 0; + bool bold = ( style & Text::Bold ) != 0; + bool italic = ( style & Text::Italic ) != 0; + Float hspace = static_cast( + font->getGlyph( L' ', fontSize, bold, italic, outlineThickness ).advance ); + for ( std::size_t i = 0; i < string.size(); ++i ) { + rune = string.at( i ); + Glyph glyph = font->getGlyph( rune, fontSize, bold, italic, outlineThickness ); + if ( rune != '\r' && rune != '\t' ) { + width += font->getKerning( prevChar, rune, fontSize, bold, italic, outlineThickness ); + width += glyph.advance; + } else if ( rune == '\t' ) + width += hspace * tabWidth; + + if ( width > maxWidth ) + return i > 0 ? i - 1 : 0; + if ( rune == '\n' ) + width = 0; + prevChar = rune; + } + return width <= maxWidth ? string.size() : string.size() - 1; +} + Vector2f Text::findCharacterPos( std::size_t index, Font* font, const Uint32& fontSize, const String& string, const Uint32& style, const Uint32& tabWidth, const Float& outlineThickness ) { @@ -720,6 +758,38 @@ Int32 Text::findCharacterFromPos( const Vector2i& pos, bool returnNearest, Font* return nearest; } +std::size_t Text::findLastCharPosWithinLength( Font* font, const Uint32& fontSize, + const String& string, Float maxWidth, + const Uint32& style, const Uint32& tabWidth, + const Float& outlineThickness ) { + return findLastCharPosWithinLength( font, fontSize, string, maxWidth, style, tabWidth, + outlineThickness ); +} + +std::size_t Text::findLastCharPosWithinLength( Font* font, const Uint32& fontSize, + const String::View& string, Float maxWidth, + const Uint32& style, const Uint32& tabWidth, + const Float& outlineThickness ) { + return findLastCharPosWithinLength( font, fontSize, string, maxWidth, style, + tabWidth, outlineThickness ); +} + +std::size_t Text::findLastCharPosWithinLength( const String& string, Float maxWidth, + const FontStyleConfig& config, + const Uint32& tabWidth ) { + return findLastCharPosWithinLength( config.Font, config.CharacterSize, string, + maxWidth, config.Style, tabWidth, + config.OutlineThickness ); +} + +std::size_t Text::findLastCharPosWithinLength( const String::View& string, Float maxWidth, + const FontStyleConfig& config, + const Uint32& tabWidth ) { + return findLastCharPosWithinLength( config.Font, config.CharacterSize, string, + maxWidth, config.Style, tabWidth, + config.OutlineThickness ); +} + void Text::updateWidthCache() { if ( NULL == mFontStyleConfig.Font || mString.empty() ) return; diff --git a/src/eepp/ui/css/stylesheetspecification.cpp b/src/eepp/ui/css/stylesheetspecification.cpp index 68370b006..f6369a640 100644 --- a/src/eepp/ui/css/stylesheetspecification.cpp +++ b/src/eepp/ui/css/stylesheetspecification.cpp @@ -406,6 +406,8 @@ void StyleSheetSpecification::registerDefaultProperties() { .addAlias( "row-vertical-align" ) .setType( PropertyType::String ); + registerProperty( "text-overflow", "clip" ).setType( PropertyType::String ); + // Shorthands registerShorthand( "margin", { "margin-top", "margin-right", "margin-bottom", "margin-left" }, "box" ); diff --git a/src/eepp/ui/uipushbutton.cpp b/src/eepp/ui/uipushbutton.cpp index a22f160f8..3ca44608e 100644 --- a/src/eepp/ui/uipushbutton.cpp +++ b/src/eepp/ui/uipushbutton.cpp @@ -538,6 +538,7 @@ std::string UIPushButton::getPropertyString( const PropertyDefinition* propertyD case PropertyId::TextStrokeColor: case PropertyId::TextSelection: case PropertyId::TextTransform: + case PropertyId::TextOverflow: return mTextBox->getPropertyString( propertyDef, propertyIndex ); default: return UIWidget::getPropertyString( propertyDef, propertyIndex ); @@ -564,7 +565,8 @@ std::vector UIPushButton::getPropertiesImplemented() const { PropertyId::TextStrokeWidth, PropertyId::TextStrokeColor, PropertyId::TextSelection, - PropertyId::TextTransform }; + PropertyId::TextTransform, + PropertyId::TextOverflow }; props.insert( props.end(), local.begin(), local.end() ); return props; } @@ -633,6 +635,7 @@ bool UIPushButton::applyProperty( const StyleSheetProperty& attribute ) { case PropertyId::TextStrokeColor: case PropertyId::TextSelection: case PropertyId::TextTransform: + case PropertyId::TextOverflow: attributeSet = mTextBox->applyProperty( attribute ); break; default: diff --git a/src/eepp/ui/uitab.cpp b/src/eepp/ui/uitab.cpp index 676305f97..b05dcf436 100644 --- a/src/eepp/ui/uitab.cpp +++ b/src/eepp/ui/uitab.cpp @@ -236,39 +236,41 @@ void UITab::onAutoSize() { mCloseButton->setEnabled( tTabW->getTabsClosable() ); } - if ( mFlags & UI_AUTO_SIZE ) { - Float nonTextW = - ( NULL != mIcon ? mIcon->getSize().getWidth() + mIcon->getLayoutMargin().Left + - mIcon->getLayoutMargin().Right - : 0 ) + - ( NULL != mCloseButton && mCloseButton->isVisible() - ? mCloseButton->getSize().getWidth() + mCloseButton->getLayoutMargin().Left + - mCloseButton->getLayoutMargin().Right - : 0 ) + - getSkinSize().getWidth(); - Float textW = mTextBox->getSize().getWidth(); - Float w = textW + nonTextW; + if ( ( mFlags & UI_AUTO_SIZE ) == 0 ) + return; - if ( NULL != tTabW ) { - if ( !mMinWidthEq.empty() ) - w = eemax( w, getMinSize().getWidth() ); - if ( !mMaxWidthEq.empty() ) - w = eemin( w, getMaxSize().getWidth() ); + Float nonTextW = + ( NULL != mIcon ? mIcon->getSize().getWidth() + mIcon->getLayoutMargin().Left + + mIcon->getLayoutMargin().Right + : 0 ) + + ( NULL != mCloseButton && mCloseButton->isVisible() + ? mCloseButton->getSize().getWidth() + mCloseButton->getLayoutMargin().Left + + mCloseButton->getLayoutMargin().Right + : 0 ) + + getSkinSize().getWidth(); - if ( textW > w - nonTextW ) - getTextBox()->setMaxWidthEq( String::format( "%.0fdp", w - nonTextW ) ); - } + Float textW = mTextBox->getSize().getWidth(); + Float w = textW + nonTextW; - setInternalWidth( w ); + if ( NULL != tTabW ) { + if ( !mMinWidthEq.empty() ) + w = eemax( w, getMinSize().getWidth() ); + if ( !mMaxWidthEq.empty() ) + w = eemin( w, getMaxSize().getWidth() ); - if ( getSize().getWidth() != w ) { - if ( NULL != getTabWidget() ) - getTabWidget()->orderTabs(); - } - - if ( getTextBox()->getTextWidth() > getTextBox()->getSize().getWidth() ) - getTextBox()->setHorizontalAlign( UI_HALIGN_LEFT ); + if ( textW > w - nonTextW ) + getTextBox()->setMaxWidthEq( String::format( "%.0fdp", w - nonTextW ) ); } + + setInternalWidth( w ); + + if ( getSize().getWidth() != w ) { + if ( NULL != getTabWidget() ) + getTabWidget()->orderTabs(); + } + + if ( getTextBox()->getTextWidth() > getTextBox()->getSize().getWidth() ) + getTextBox()->setHorizontalAlign( UI_HALIGN_LEFT ); } std::string UITab::getPropertyString( const PropertyDefinition* propertyDef, diff --git a/src/eepp/ui/uitextview.cpp b/src/eepp/ui/uitextview.cpp index bdb7b8e28..1be98a6f1 100644 --- a/src/eepp/ui/uitextview.cpp +++ b/src/eepp/ui/uitextview.cpp @@ -15,6 +15,8 @@ #define PUGIXML_HEADER_ONLY #include +using namespace std::literals; + namespace EE { namespace UI { UITextView* UITextView::New() { @@ -77,25 +79,25 @@ void UITextView::draw() { if ( mVisible && 0.f != mAlpha ) { UINode::draw(); - if ( mTextCache->getTextWidth() ) { - drawSelection( mTextCache ); + if ( mTextCache->getTextWidth() <= 0.f ) + return; - if ( isClipped() ) { - clipSmartEnable( mScreenPos.x + mPaddingPx.Left, mScreenPos.y + mPaddingPx.Top, - mSize.getWidth() - mPaddingPx.Left - mPaddingPx.Right, - mSize.getHeight() - mPaddingPx.Top - mPaddingPx.Bottom ); - } + drawSelection( mTextCache ); - mTextCache->setAlign( Font::getHorizontalAlign( getFlags() ) ); - mTextCache->draw( (Float)mScreenPosi.x + (int)mRealAlignOffset.x + (int)mPaddingPx.Left, - mFontLineCenter + (Float)mScreenPosi.y + (int)mRealAlignOffset.y + - (int)mPaddingPx.Top, - Vector2f::One, 0.f, getBlendMode() ); - - if ( isClipped() ) { - clipSmartDisable(); - } + if ( isClipped() ) { + clipSmartEnable( mScreenPos.x + mPaddingPx.Left, mScreenPos.y + mPaddingPx.Top, + mSize.getWidth() - mPaddingPx.Left - mPaddingPx.Right, + mSize.getHeight() - mPaddingPx.Top - mPaddingPx.Bottom ); } + + mTextCache->setAlign( Font::getHorizontalAlign( getFlags() ) ); + mTextCache->draw( (Float)mScreenPosi.x + (int)mRealAlignOffset.x + (int)mPaddingPx.Left, + mFontLineCenter + (Float)mScreenPosi.y + (int)mRealAlignOffset.y + + (int)mPaddingPx.Top, + Vector2f::One, 0.f, getBlendMode() ); + + if ( isClipped() ) + clipSmartDisable(); } } @@ -321,15 +323,16 @@ void UITextView::onAutoSize() { bool sizeChanged = false; if ( ( mFlags & UI_AUTO_SIZE && 0 == getSize().getWidth() ) ) { - setInternalPixelsSize( Sizef( mTextCache->getTextWidth(), mTextCache->getTextHeight() ) ); + setInternalPixelsSize( Sizef( getTextWidth(), mTextCache->getTextHeight() ) ); sizeChanged = true; } if ( mWidthPolicy == SizePolicy::WrapContent ) { - Float totW = (int)mTextCache->getTextWidth() + mPaddingPx.Left + mPaddingPx.Right; + Float totW = (int)getTextWidth() + mPaddingPx.Left + mPaddingPx.Right; + if ( !getMaxWidthEq().empty() ) { Float oldW = totW; - totW = eemin( totW, getMaxSize().getWidth() ); + totW = eemin( totW, getMaxSizePx().getWidth() ); if ( oldW != totW ) setClipType( ClipType::ContentBox ); } @@ -343,7 +346,7 @@ void UITextView::onAutoSize() { Float totH = (int)mTextCache->getTextHeight() + mPaddingPx.Top + mPaddingPx.Bottom; if ( !getMaxHeightEq().empty() ) { Float oldH = totH; - totH = eemin( totH, getMaxSize().getHeight() ); + totH = eemin( totH, getMaxSizePx().getHeight() ); if ( oldH != totH ) setClipType( ClipType::ContentBox ); } @@ -353,8 +356,10 @@ void UITextView::onAutoSize() { } } - if ( sizeChanged ) + if ( sizeChanged ) { + updateTextOverflow(); notifyLayoutAttrChange(); + } } void UITextView::alignFix() { @@ -362,11 +367,11 @@ void UITextView::alignFix() { case UI_HALIGN_CENTER: mRealAlignOffset.x = (Float)( (Int32)( ( mSize.x - mPaddingPx.Left - mPaddingPx.Right ) / 2 - - mTextCache->getTextWidth() / 2 ) ); + getTextWidth() / 2 ) ); break; case UI_HALIGN_RIGHT: - mRealAlignOffset.x = ( (Float)mSize.x - mPaddingPx.Left - mPaddingPx.Right - - (Float)mTextCache->getTextWidth() ); + mRealAlignOffset.x = + ( (Float)mSize.x - mPaddingPx.Left - mPaddingPx.Right - (Float)getTextWidth() ); break; case UI_HALIGN_LEFT: mRealAlignOffset.x = 0; @@ -443,7 +448,8 @@ void UITextView::setTheme( UITheme* Theme ) { } Float UITextView::getTextWidth() { - return mTextCache->getTextWidth(); + return hasTextOverflow() ? Text::getTextWidth( mString, mFontStyleConfig ) + : mTextCache->getTextWidth(); } Float UITextView::getTextHeight() { @@ -655,6 +661,7 @@ void UITextView::recalculate() { mFontLineCenter = eefloor( (Float)( ( mTextCache->getFont()->getLineSpacing( fontHeight ) - fontHeight ) / 2 ) ); + updateTextOverflow(); autoWrap(); onAutoSize(); alignFix(); @@ -742,6 +749,9 @@ bool UITextView::applyProperty( const StyleSheetProperty& attribute ) { setTextAlign( UI_HALIGN_RIGHT ); break; } + case PropertyId::TextOverflow: + setTextOverflow( attribute.value() ); + break; default: return UIWidget::applyProperty( attribute ); } @@ -789,6 +799,8 @@ std::string UITextView::getPropertyString( const PropertyDefinition* propertyDef ? "center" : ( Font::getHorizontalAlign( getFlags() ) == UI_HALIGN_RIGHT ? "right" : "left" ); + case PropertyId::TextOverflow: + return mTextOverflow; default: return UIWidget::getPropertyString( propertyDef, propertyIndex ); } @@ -810,7 +822,8 @@ std::vector UITextView::getPropertiesImplemented() const { PropertyId::TextStrokeWidth, PropertyId::TextStrokeColor, PropertyId::TextSelection, - PropertyId::TextAlign }; + PropertyId::TextAlign, + PropertyId::TextOverflow }; props.insert( props.end(), local.begin(), local.end() ); return props; } @@ -833,6 +846,61 @@ void UITextView::loadFromXmlNode( const pugi::xml_node& node ) { endAttributesTransaction(); } +void UITextView::updateTextOverflow() { + if ( hasTextOverflow() ) { + mTextOverflowWidth = Text::getTextWidth( mTextOverflow, mFontStyleConfig ); + + Float maxWidth = mSize.getWidth() - mPaddingPx.Left - mPaddingPx.Right; + + std::size_t charPos = + Text::findLastCharPosWithinLength( mString, maxWidth, mFontStyleConfig ); + + if ( charPos != mString.size() ) { + maxWidth -= mTextOverflowWidth; + charPos = Text::findLastCharPosWithinLength( mString, maxWidth, mFontStyleConfig ); + mTextCache->setString( mString.view().substr( 0, charPos ) + mTextOverflow ); + } else { + if ( mFlags & UI_WORD_WRAP ) { + autoWrap(); + } else if ( mString != mTextCache->getString() ) { + mTextCache->setString( mString ); + } + } + } else { + mTextOverflowWidth = 0.f; + + if ( mFlags & UI_WORD_WRAP ) { + autoWrap(); + } else if ( mString != mTextCache->getString() ) { + mTextCache->setString( mString ); + } + } +} + +UITextView* UITextView::setTextOverflow( const std::string_view& textOverflow ) { + if ( textOverflow == mTextOverflow || + ( mTextOverflow == u8"…" && textOverflow == "ellipsis"sv ) ) + return this; + + if ( "ellipsis"sv == textOverflow ) { + mTextOverflow = u8"…"; // U+2026 + } else { + mTextOverflow = textOverflow; + } + + updateTextOverflow(); + + return this; +} + +const std::string& UITextView::getTextOverflow() const { + return mTextOverflow; +} + +bool UITextView::hasTextOverflow() const { + return !mTextOverflow.empty() && mTextOverflow != "clip"sv; +} + UIAnchor* UIAnchor::New() { return eeNew( UIAnchor, () ); } diff --git a/src/tools/ecode/applayout.xml.hpp b/src/tools/ecode/applayout.xml.hpp index 7c30c0099..6a5fd3f3e 100644 --- a/src/tools/ecode/applayout.xml.hpp +++ b/src/tools/ecode/applayout.xml.hpp @@ -384,6 +384,12 @@ Anchor.error:hover { .texture-preview { border: 1dp solid var(--list-back); } +#code_container > TabWidget { + max-tab-width: 200dp; +} +#code_container > TabWidget > TabWidget::TabBar > Tab > Tab::Text { + text-overflow: ellipsis; +} diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index 933d9b02d..b5137056d 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -3126,6 +3126,8 @@ void App::loadFolder( const std::string& path ) { if ( mSplitter->getCurWidget() ) mSplitter->getCurWidget()->setFocus(); + + setAppTitle( titleFromEditor( mSplitter->getCurEditor() ) ); } #if EE_PLATFORM == EE_PLATFORM_MACOS