diff --git a/bin/assets/layouts/test.css b/bin/assets/layouts/test.css index 58e89d675..62cf6596f 100644 --- a/bin/assets/layouts/test.css +++ b/bin/assets/layouts/test.css @@ -20,9 +20,12 @@ TabWidget { tab-separation: -1dp; - line-below-tabs: true; - line-below-tabs-color: #2f3030; - line-below-tabs-y-offset: -1dp; +} + +TabWidget::TabContainer { + background-image: rectangle(solid, #2f3030); + background-size: 100% 1dp; + background-position-y: bottom; } ProgressBar { diff --git a/bin/assets/ui/uitheme.css b/bin/assets/ui/uitheme.css index f8bda7c9f..6d9b6fd82 100644 --- a/bin/assets/ui/uitheme.css +++ b/bin/assets/ui/uitheme.css @@ -8,9 +8,12 @@ TabWidget { tab-separation: -1dp; - line-below-tabs: true; - line-below-tabs-color: #2f3030; - line-below-tabs-y-offset: -1dp; +} + +TabWidget::TabContainer { + background-image: rectangle(solid, #2f3030); + background-size: 100% 1dp; + background-position-y: bottom; } ProgressBar { diff --git a/docs/articles/cssspecification.md b/docs/articles/cssspecification.md index 55f8cccd4..936bbd6a4 100644 --- a/docs/articles/cssspecification.md +++ b/docs/articles/cssspecification.md @@ -933,18 +933,6 @@ or one of the special constants. --- -### line-below-tabs - ---- - -### line-below-tabs-color - ---- - -### line-below-tabs-y-offset - ---- - ### margin-bottom Read [margin-bottom](https://developer.mozilla.org/en-US/docs/Web/CSS/margin-bottom) documentation. @@ -983,30 +971,74 @@ Read [max-width](https://developer.mozilla.org/en-US/docs/Web/CSS/max-width) doc ### max-edge-resistance +On a view pager the max edge resistance allows to scroll outside the edge limits by a percentage of +the element width/height (depending on the view pager orientation) and automatically go back to the +final position when released. + +* Applicable to: EE::UI::UIViewPager (ViewPager) +* Value Type: float (normalized between `0` and `1`) +* Default value: `0` + --- ### max-length +Sets the maximum length of an input. + +* Applicable to: EE::UI::UITextInput (TextInput) +* Value type: integer +* Default value: _No value_ + --- ### max-progress +Sets the maximum number of progress that a loader can have. + +* Applicable to: EE::UI::UILoader (Loader) +* Value Type: float +* Default value: `100` + --- ### max-tab-width +Sets the maximum tab width accepted in a tab widget. + +* Applicable to: EE::UI::UITabWidget (TabWidget) +* Value Type: length +* Default value: `300dp` + --- ### max-text-length +Sets the maximum text length in a tab. + +* Applicable to: EE::UI::UITabWidget (TabWidget) +* Value Type: integer +* Default value: `100` + --- ### max-value +Sets the maximum value that a range element will hold. + +* Applicable to: EE::UI::UISlider (Slider), EE::UI::UIScrollBar (ScrollBar), EE::UI::UISpinBox (SpinBox) +* Value Type: float +* Default value: `1` for Slider and ScrollBar. Float numeric limits for SpinBox. + --- ### max-visible-items +Sets the maximum visible items for the list shown by a drop down list or combo box. + +* Applicable to: EE::UI::UIDropDownList (DropDownList) +* Value Type: integer +* Default value: `10` + --- ### min-height diff --git a/include/eepp/ui/css/propertydefinition.hpp b/include/eepp/ui/css/propertydefinition.hpp index 930c8c022..0297ad04a 100644 --- a/include/eepp/ui/css/propertydefinition.hpp +++ b/include/eepp/ui/css/propertydefinition.hpp @@ -86,9 +86,6 @@ enum class PropertyId : Uint32 { MaxTabWidth = String::hash( "max-tab-width" ), TabClosable = String::hash( "tab-closable" ), SpecialBorderTabs = String::hash( "special-border-tabs" ), - LineBelowTabs = String::hash( "line-below-tabs" ), - LineBelowTabsColor = String::hash( "line-below-tabs-color" ), - LineBelowTabsYOffset = String::hash( "line-below-tabs-y-offset" ), TabSeparation = String::hash( "tax-separation" ), Selected = String::hash( "selected" ), PopUpToMainControl = String::hash( "popup-to-main-control" ), diff --git a/include/eepp/ui/uitab.hpp b/include/eepp/ui/uitab.hpp index 19c0a99bc..827d807d4 100644 --- a/include/eepp/ui/uitab.hpp +++ b/include/eepp/ui/uitab.hpp @@ -35,7 +35,10 @@ class EE_API UITab : public UISelectButton { const Uint32& propertyIndex = 0 ); protected: + friend class UITabWidget; + Node* mControlOwned; + String mText; std::string mOwnedName; virtual Uint32 onMouseUp( const Vector2i& position, const Uint32& flags ); @@ -51,6 +54,8 @@ class EE_API UITab : public UISelectButton { virtual void onParentChange(); void setOwnedControl(); + + void updateTab(); }; }} // namespace EE::UI diff --git a/include/eepp/ui/uitabwidget.hpp b/include/eepp/ui/uitabwidget.hpp index e7220adc9..f433dbc69 100644 --- a/include/eepp/ui/uitabwidget.hpp +++ b/include/eepp/ui/uitabwidget.hpp @@ -12,7 +12,7 @@ class EE_API UITabWidget : public UIWidget { class StyleConfig { public: Int32 TabSeparation = 0; - Uint32 MaxTextLength = 30; + Uint32 MaxTextLength = 100; Uint32 TabWidgetHeight = 0; Uint32 TabTextAlign = ( UI_HALIGN_CENTER | UI_VALIGN_CENTER ); Uint32 MinTabWidth = 32; @@ -20,9 +20,6 @@ class EE_API UITabWidget : public UIWidget { bool TabsClosable = false; bool SpecialBorderTabs = false; //! Indicates if the periferical tabs ( the left and right //! border tab ) are different from the central tabs. - bool DrawLineBelowTabs = false; - Color LineBelowTabsColor; - Int32 LineBelowTabsYOffset = 0; }; static UITabWidget* New(); @@ -67,8 +64,6 @@ class EE_API UITabWidget : public UIWidget { UIWidget* getControlContainer() const; - virtual void draw(); - Int32 getTabSeparation() const; void setTabSeparation( const Int32& tabSeparation ); @@ -95,18 +90,6 @@ class EE_API UITabWidget : public UIWidget { void setSpecialBorderTabs( bool specialBorderTabs ); - bool getDrawLineBelowTabs() const; - - void setDrawLineBelowTabs( bool drawLineBelowTabs ); - - Color getLineBelowTabsColor() const; - - void setLineBelowTabsColor( const Color& lineBelowTabsColor ); - - Int32 getLineBelowTabsYOffset() const; - - void setLineBelowTabsYOffset( const Int32& lineBelowTabsYOffset ); - const StyleConfig& getStyleConfig() const; void setStyleConfig( const StyleConfig& styleConfig ); @@ -148,8 +131,6 @@ class EE_API UITabWidget : public UIWidget { virtual void onPaddingChange(); - void setTabContainerSize(); - void setContainerSize(); void posTabs(); @@ -158,6 +139,8 @@ class EE_API UITabWidget : public UIWidget { void orderTabs(); + void updateTabs(); + void applyThemeToTabs(); void refreshControlOwned( UITab* tab ); diff --git a/src/eepp/ui/uipushbutton.cpp b/src/eepp/ui/uipushbutton.cpp index 5b025ee55..493dc83ca 100644 --- a/src/eepp/ui/uipushbutton.cpp +++ b/src/eepp/ui/uipushbutton.cpp @@ -15,34 +15,21 @@ UIPushButton::UIPushButton( const std::string& tag ) : UIWidget( tag ), mIcon( NULL ), mTextBox( NULL ) { mFlags |= ( UI_AUTO_SIZE | UI_VALIGN_CENTER | UI_HALIGN_CENTER ); - Uint32 GfxFlags; - - if ( mStyleConfig.IconMinSize.x != 0 && mStyleConfig.IconMinSize.y != 0 ) { - GfxFlags = UI_VALIGN_CENTER | UI_HALIGN_CENTER; - } else { - GfxFlags = UI_AUTO_SIZE | UI_VALIGN_CENTER | UI_HALIGN_CENTER; - } - mIcon = UIImage::NewWithTag( "pushbutton::image" ); - mIcon->setParent( this ); - mIcon->setLayoutSizeRules( LayoutSizeRule::Fixed, LayoutSizeRule::Fixed ); - mIcon->setFlags( GfxFlags ); - mIcon->unsetFlags( UI_AUTO_SIZE ); - mIcon->setScaleType( UIScaleType::FitInside ); - - if ( mStyleConfig.IconMinSize.x != 0 && mStyleConfig.IconMinSize.y != 0 ) { - mIcon->setSize( mStyleConfig.IconMinSize.asFloat() ); - } - - mIcon->setVisible( true ); - mIcon->setEnabled( false ); + mIcon->setScaleType( UIScaleType::FitInside ) + ->setLayoutSizeRules( LayoutSizeRule::Fixed, LayoutSizeRule::Fixed ) + ->setFlags( UI_VALIGN_CENTER | UI_HALIGN_CENTER ) + ->setParent( this ) + ->setVisible( true ) + ->setEnabled( false ); mTextBox = UITextView::NewWithTag( "pushbutton::text" ); - mTextBox->setLayoutSizeRules( LayoutSizeRule::WrapContent, LayoutSizeRule::WrapContent ); - mTextBox->setParent( this ); - mTextBox->setVisible( true ); - mTextBox->setEnabled( false ); - mTextBox->setFlags( UI_VALIGN_CENTER | UI_HALIGN_CENTER ); + mTextBox->setLayoutSizeRules( LayoutSizeRule::WrapContent, LayoutSizeRule::WrapContent ) + ->setFlags( UI_VALIGN_CENTER | UI_HALIGN_CENTER ) + ->setParent( this ) + ->setVisible( true ) + ->setEnabled( false ); + auto cb = [&]( const Event* event ) { onSizeChange(); notifyLayoutAttrChange(); @@ -51,9 +38,6 @@ UIPushButton::UIPushButton( const std::string& tag ) : mTextBox->addEventListener( Event::OnFontStyleChanged, cb ); mTextBox->addEventListener( Event::OnTextChanged, cb ); - if ( mStyleConfig.IconAutoMargin ) - mNodeFlags |= NODE_FLAG_FREE_USE; - onSizeChange(); applyDefaultTheme(); @@ -265,7 +249,7 @@ Uint32 UIPushButton::onKeyUp( const KeyEvent& Event ) { } void UIPushButton::autoIconHorizontalMargin() { - if ( mNodeFlags & NODE_FLAG_FREE_USE ) { + if ( mStyleConfig.IconAutoMargin ) { Rectf RMargin = makePadding( true, false, false, false, true ); setIconHorizontalMargin( RMargin.Left ); } @@ -352,9 +336,6 @@ bool UIPushButton::applyProperty( const StyleSheetProperty& attribute ) { break; case PropertyId::IconAutoMargin: mStyleConfig.IconAutoMargin = attribute.asBool(); - - if ( mStyleConfig.IconAutoMargin ) - mNodeFlags |= NODE_FLAG_FREE_USE; break; case PropertyId::Color: case PropertyId::ShadowColor: diff --git a/src/eepp/ui/uispinbox.cpp b/src/eepp/ui/uispinbox.cpp index 5dd7c3246..cbe8bf702 100644 --- a/src/eepp/ui/uispinbox.cpp +++ b/src/eepp/ui/uispinbox.cpp @@ -2,6 +2,7 @@ #include #include #include +#include namespace EE { namespace UI { @@ -10,7 +11,11 @@ UISpinBox* UISpinBox::New() { } UISpinBox::UISpinBox() : - UIWidget( "spinbox" ), mMinValue( 0.f ), mMaxValue( 1024.f ), mValue( 0 ), mClickStep( 1.f ) { + UIWidget( "spinbox" ), + mMinValue( 0.f ), + mMaxValue( std::numeric_limits::max() ), + mValue( 0 ), + mClickStep( 1.f ) { mInput = UITextInput::NewWithTag( "spinbox::input" ); mInput->setVisible( true ); mInput->setEnabled( true ); diff --git a/src/eepp/ui/uitab.cpp b/src/eepp/ui/uitab.cpp index a406c6415..4655959b2 100644 --- a/src/eepp/ui/uitab.cpp +++ b/src/eepp/ui/uitab.cpp @@ -99,30 +99,18 @@ const String& UITab::getText() { } UIPushButton* UITab::setText( const String& text ) { + mText = text; + UITabWidget* tTabW = getTabWidget(); if ( NULL != tTabW ) { - if ( text.size() > tTabW->getMaxTextLength() ) { - UIPushButton::setText( text.substr( 0, tTabW->getMaxTextLength() ) ); + updateTab(); - onAutoSize(); + tTabW->orderTabs(); - tTabW->orderTabs(); - - tTabW->setTabSelected( tTabW->getSelectedTab() ); - - return this; - } + tTabW->setTabSelected( tTabW->getSelectedTab() ); } - UIPushButton::setText( text ); - - onAutoSize(); - - tTabW->orderTabs(); - - tTabW->setTabSelected( tTabW->getSelectedTab() ); - return this; } @@ -213,6 +201,20 @@ void UITab::setOwnedControl() { } } +void UITab::updateTab() { + UITabWidget* tTabW = getTabWidget(); + + if ( NULL != tTabW ) { + if ( mText.size() > tTabW->getMaxTextLength() ) { + UIPushButton::setText( mText.substr( 0, tTabW->getMaxTextLength() ) ); + } else { + UIPushButton::setText( mText ); + } + + onAutoSize(); + } +} + Node* UITab::getControlOwned() const { return mControlOwned; } diff --git a/src/eepp/ui/uitabwidget.cpp b/src/eepp/ui/uitabwidget.cpp index 916755d56..24e27a4da 100644 --- a/src/eepp/ui/uitabwidget.cpp +++ b/src/eepp/ui/uitabwidget.cpp @@ -78,7 +78,7 @@ void UITabWidget::onThemeLoaded() { void UITabWidget::setContainerSize() { mTabContainer->setPixelsSize( mSize.getWidth() - mRealPadding.Left - mRealPadding.Right, - mStyleConfig.TabWidgetHeight ); + PixelDensity::dpToPx( mStyleConfig.TabWidgetHeight ) ); mTabContainer->setPosition( mPadding.Left, mPadding.Top ); mCtrlContainer->setPosition( mPadding.Left, mPadding.Top + mStyleConfig.TabWidgetHeight ); mCtrlContainer->setPixelsSize( mSize.getWidth() - mRealPadding.Left - mRealPadding.Right, @@ -87,38 +87,6 @@ void UITabWidget::setContainerSize() { mRealPadding.Top - mRealPadding.Bottom ); } -void UITabWidget::draw() { - UIWidget::draw(); - - if ( mStyleConfig.DrawLineBelowTabs ) { - bool smooth = GLi->isLineSmooth(); - if ( smooth ) - GLi->lineSmooth( false ); - - Primitives P; - Vector2f p1( mScreenPos.x + mRealPadding.Left, - mScreenPos.y + mRealPadding.Top + mTabContainer->getPixelsSize().getHeight() + - mStyleConfig.LineBelowTabsYOffset ); - Vector2f p2( mScreenPos.x + mTabContainer->getPixelsPosition().x, p1.y ); - - P.setLineWidth( PixelDensity::dpToPx( 1 ) ); - P.setColor( Color( mStyleConfig.LineBelowTabsColor, mAlpha ) ); - P.drawLine( Line2f( Vector2f( (int)p1.x, (int)p1.y ), Vector2f( (int)p2.x, (int)p2.y ) ) ); - - Vector2f p3( mScreenPos.x + mTabContainer->getPixelsPosition().x + - mTabContainer->getPixelsSize().getWidth(), - mScreenPos.y + mRealPadding.Top + mTabContainer->getPixelsSize().getHeight() + - mStyleConfig.LineBelowTabsYOffset ); - Vector2f p4( mScreenPos.x + mRealPadding.Left + mCtrlContainer->getPixelsSize().getWidth(), - p3.y ); - - P.drawLine( Line2f( Vector2f( (int)p3.x, (int)p3.y ), Vector2f( (int)p4.x, (int)p4.y ) ) ); - - if ( smooth ) - GLi->lineSmooth( true ); - } -} - const UITabWidget::StyleConfig& UITabWidget::getStyleConfig() const { return mStyleConfig; } @@ -147,12 +115,6 @@ std::string UITabWidget::getPropertyString( const PropertyDefinition* propertyDe return getTabsClosable() ? "true" : "false"; case PropertyId::SpecialBorderTabs: return getSpecialBorderTabs() ? "true" : "false"; - case PropertyId::LineBelowTabs: - return getDrawLineBelowTabs() ? "true" : "false"; - case PropertyId::LineBelowTabsColor: - return getLineBelowTabsColor().toHexString(); - case PropertyId::LineBelowTabsYOffset: - return String::format( "%ddp", getLineBelowTabsYOffset() ); case PropertyId::TabSeparation: return String::format( "%ddp", getTabSeparation() ); default: @@ -198,10 +160,10 @@ bool UITabWidget::applyProperty( const StyleSheetProperty& attribute ) { setMaxTextLength( attribute.asUint( 1 ) ); break; case PropertyId::MinTabWidth: - setMinTabWidth( attribute.asDpDimensionUint( "1" ) ); + setMinTabWidth( attribute.asDpDimensionUint( this, "1" ) ); break; case PropertyId::MaxTabWidth: - setMaxTabWidth( attribute.asDpDimensionUint() ); + setMaxTabWidth( attribute.asDpDimensionUint( this ) ); break; case PropertyId::TabClosable: setTabsClosable( attribute.asBool() ); @@ -209,15 +171,6 @@ bool UITabWidget::applyProperty( const StyleSheetProperty& attribute ) { case PropertyId::SpecialBorderTabs: setSpecialBorderTabs( attribute.asBool() ); break; - case PropertyId::LineBelowTabs: - setDrawLineBelowTabs( attribute.asBool() ); - break; - case PropertyId::LineBelowTabsColor: - setLineBelowTabsColor( attribute.asColor() ); - break; - case PropertyId::LineBelowTabsYOffset: - setLineBelowTabsYOffset( attribute.asDpDimensionI() ); - break; case PropertyId::TabSeparation: setTabSeparation( attribute.asDpDimensionI() ); break; @@ -234,7 +187,6 @@ Int32 UITabWidget::getTabSeparation() const { void UITabWidget::setTabSeparation( const Int32& tabSeparation ) { mStyleConfig.TabSeparation = tabSeparation; - setTabContainerSize(); posTabs(); } @@ -244,6 +196,7 @@ Uint32 UITabWidget::getMaxTextLength() const { void UITabWidget::setMaxTextLength( const Uint32& maxTextLength ) { mStyleConfig.MaxTextLength = maxTextLength; + updateTabs(); invalidateDraw(); } @@ -257,6 +210,7 @@ Uint32 UITabWidget::getMinTabWidth() const { void UITabWidget::setMinTabWidth( const Uint32& minTabWidth ) { mStyleConfig.MinTabWidth = minTabWidth; + updateTabs(); invalidateDraw(); } @@ -266,6 +220,7 @@ Uint32 UITabWidget::getMaxTabWidth() const { void UITabWidget::setMaxTabWidth( const Uint32& maxTabWidth ) { mStyleConfig.MaxTabWidth = maxTabWidth; + updateTabs(); invalidateDraw(); } @@ -287,81 +242,51 @@ void UITabWidget::setSpecialBorderTabs( bool specialBorderTabs ) { applyThemeToTabs(); } -bool UITabWidget::getDrawLineBelowTabs() const { - return mStyleConfig.DrawLineBelowTabs; -} +void UITabWidget::posTabs() { + Int32 x = 0; + Int32 y = 0; + Int32 alignOffset = 0; + Uint32 tabsWidth = 0; -void UITabWidget::setDrawLineBelowTabs( bool drawLineBelowTabs ) { - mStyleConfig.DrawLineBelowTabs = drawLineBelowTabs; - invalidateDraw(); -} - -Color UITabWidget::getLineBelowTabsColor() const { - return mStyleConfig.LineBelowTabsColor; -} - -void UITabWidget::setLineBelowTabsColor( const Color& lineBelowTabsColor ) { - mStyleConfig.LineBelowTabsColor = lineBelowTabsColor; - invalidateDraw(); -} - -Int32 UITabWidget::getLineBelowTabsYOffset() const { - return mStyleConfig.LineBelowTabsYOffset; -} - -void UITabWidget::setLineBelowTabsYOffset( const Int32& lineBelowTabsYOffset ) { - mStyleConfig.LineBelowTabsYOffset = lineBelowTabsYOffset; - invalidateDraw(); -} - -void UITabWidget::setTabContainerSize() { - Uint32 s = 0; - - if ( mTabs.size() > 0 ) { + if ( !mTabs.empty() ) { for ( Uint32 i = 0; i < mTabs.size(); i++ ) { - s += mTabs[i]->getPixelsSize().getWidth() + mStyleConfig.TabSeparation; + tabsWidth += mTabs[i]->getPixelsSize().getWidth() + mStyleConfig.TabSeparation; } - s -= mStyleConfig.TabSeparation; + tabsWidth -= mStyleConfig.TabSeparation; } - mTabContainer->setPixelsSize( s, PixelDensity::dpToPx( mStyleConfig.TabWidgetHeight ) ); - switch ( Font::getHorizontalAlign( mFlags ) ) { case UI_HALIGN_LEFT: - mTabContainer->setPosition( 0, 0 ); + alignOffset = 0; break; case UI_HALIGN_CENTER: - mTabContainer->centerHorizontal(); + alignOffset = ( getPixelsSize().getWidth() - tabsWidth ) / 2; break; case UI_HALIGN_RIGHT: - mTabContainer->setPosition( getSize().getWidth() - mTabContainer->getSize().getWidth(), - 0 ); + alignOffset = getSize().getWidth() - tabsWidth; break; } -} - -void UITabWidget::posTabs() { - Uint32 w = 0; - Int32 h = 0; - Int32 VA = Font::getVerticalAlign( mFlags ); for ( Uint32 i = 0; i < mTabs.size(); i++ ) { - switch ( VA ) { + switch ( Font::getVerticalAlign( mFlags ) ) { case UI_VALIGN_BOTTOM: - h = mStyleConfig.TabWidgetHeight - mTabs[i]->getSize().getHeight(); + y = PixelDensity::dpToPx( mStyleConfig.TabWidgetHeight ) - + mTabs[i]->getPixelsSize().getHeight(); break; case UI_VALIGN_TOP: - h = 0; + y = 0; break; case UI_VALIGN_CENTER: - h = mStyleConfig.TabWidgetHeight / 2 - mTabs[i]->getSize().getHeight() / 2; + y = ( PixelDensity::dpToPx( mStyleConfig.TabWidgetHeight ) - + mTabs[i]->getPixelsSize().getHeight() ) / + 2; break; } - mTabs[i]->setPosition( w, h ); + mTabs[i]->setPixelsPosition( alignOffset + x, y ); - w += mTabs[i]->getSize().getWidth() + mStyleConfig.TabSeparation; + x += mTabs[i]->getPixelsSize().getWidth() + mStyleConfig.TabSeparation; } } @@ -380,13 +305,17 @@ void UITabWidget::orderTabs() { zorderTabs(); - setTabContainerSize(); - posTabs(); invalidateDraw(); } +void UITabWidget::updateTabs() { + for ( Uint32 i = 0; i < mTabs.size(); i++ ) { + mTabs[i]->updateTab(); + } +} + UITab* UITabWidget::createTab( const String& Text, UINode* CtrlOwned, Drawable* Icon ) { UITab* tCtrl = UITab::New(); tCtrl->setParent( mTabContainer ); @@ -613,7 +542,6 @@ Uint32 UITabWidget::getSelectedTabIndex() const { void UITabWidget::onSizeChange() { setContainerSize(); - setTabContainerSize(); posTabs(); if ( NULL != mTabSelected && NULL != mTabSelected->getControlOwned() ) {