diff --git a/bin/assets/ui/breeze.css b/bin/assets/ui/breeze.css index e492f8a03..9fb3d6b40 100644 --- a/bin/assets/ui/breeze.css +++ b/bin/assets/ui/breeze.css @@ -111,7 +111,8 @@ RadioButton::active { ListBox, DropDownList::ListBox, -ComboBox::DropDownList::ListBox { +ComboBox::DropDownList::ListBox, +Table { background-color: var(--list-back); border-color: var(--button-border); border-radius: var(--button-radius); @@ -126,7 +127,8 @@ ListBox::item { background-position: left bottom, right bottom; } -ListBox:hover { +ListBox:hover, +Table::hover { border-color: var(--primary); } @@ -217,18 +219,21 @@ SpinBox::btndown { height: 13dp; } -TextEdit { +TextEdit::input { background-color: var(--list-back); border-color: var(--button-border); border-radius: var(--button-radius); border-width: var(--border-width); -} - -TextEdit::input { padding-left: var(--base-horizontal-padding); padding-right: var(--base-horizontal-padding); padding-top: var(--base-vertical-padding); padding-bottom: var(--base-vertical-padding); + transition: all 0.15; +} + +TextEdit::input:focus, +TextEdit::input:hover { + border-color: var(--primary); } Tooltip { @@ -576,10 +581,26 @@ Menu::Separator { height: 3dp; background-color: var(--button-back); background-image: rectangle(solid, var(--button-border)); - background-size: 100% 1dp; + background-size: 100% 1px; background-position: center; } -:root { +Menu::SubMenu::Arrow { + width: 16dp; + height: 16dp; + foreground-image: poly(line, var(--icon), "-7dp -5dp, -2dp 0dp"), poly(line, var(--icon), "-7dp 5dp, -2dp 0dp"); +} + +Menu::CheckBox::icon { + width: 16dp; + height: 16dp; + foreground-image: none, none; +} + +Menu::CheckBox::icon:selected { + foreground-image: poly(line, var(--icon), "10dp 14dp, 12dp 16dp"), poly(line, var(--icon), "12dp 16dp, 16dp 8dp"); +} + +.appbackground { background-color: var(--back); } diff --git a/include/eepp/ui/uiscenenode.hpp b/include/eepp/ui/uiscenenode.hpp index 1d6645461..4991197fb 100644 --- a/include/eepp/ui/uiscenenode.hpp +++ b/include/eepp/ui/uiscenenode.hpp @@ -109,6 +109,7 @@ class EE_API UISceneNode : public SceneNode { std::unordered_set mDirtyStyle; std::unordered_set mDirtyStyleState; std::unordered_map mDirtyStyleStateCSSAnimations; + std::vector> mTimes; virtual void resizeControl( EE::Window::Window* win ); diff --git a/projects/linux/ee.creator.user b/projects/linux/ee.creator.user index 9eb90fd1e..fdf68a72d 100644 --- a/projects/linux/ee.creator.user +++ b/projects/linux/ee.creator.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -1531,7 +1531,7 @@ eepp-UIEditor-debug ProjectExplorer.CustomExecutableRunConfiguration - -x assets/layouts/test.xml -c assets/layouts/test.css -u + -x assets/layouts/test_widgets.xml -c assets/ui/breeze.css false true diff --git a/src/eepp/maps/mapeditor/mapeditor.cpp b/src/eepp/maps/mapeditor/mapeditor.cpp index 0391938b1..5fca340e0 100644 --- a/src/eepp/maps/mapeditor/mapeditor.cpp +++ b/src/eepp/maps/mapeditor/mapeditor.cpp @@ -1,11 +1,4 @@ -#include -#include -#include -#include -#include -#include -#include - +#include #include #include #include @@ -17,14 +10,18 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include #include #include - #include #include -#include - using namespace EE::Graphics; using namespace EE::Maps::Private; @@ -107,6 +104,7 @@ bool MapEditor::addShortcut( const Uint32& KeyCode, const Uint32& Mod, UIWidget* void MapEditor::createWinMenu() { UIWinMenu* WinMenu = UIWinMenu::New(); WinMenu->setParent( mUIContainer ); + WinMenu->getUISceneNode()->updateDirtyStyleStates(); mTileBox = createTextBox( "", mUIContainer, Sizef(), Vector2f(), diff --git a/src/eepp/ui/css/drawableimageparser.cpp b/src/eepp/ui/css/drawableimageparser.cpp index 185e04e5a..7202a67e2 100644 --- a/src/eepp/ui/css/drawableimageparser.cpp +++ b/src/eepp/ui/css/drawableimageparser.cpp @@ -23,6 +23,10 @@ Drawable* DrawableImageParser::createDrawable( const std::string& value, const S Drawable* res = NULL; ownIt = false; + if ( "none" == value ) { + return NULL; + } + if ( !functionType.isEmpty() ) { if ( exists( functionType.getName() ) ) { return mFuncs[functionType.getName()]( functionType, size, ownIt, node ); diff --git a/src/eepp/ui/tools/textureatlaseditor.cpp b/src/eepp/ui/tools/textureatlaseditor.cpp index 09befdf70..4a2dce8f8 100644 --- a/src/eepp/ui/tools/textureatlaseditor.cpp +++ b/src/eepp/ui/tools/textureatlaseditor.cpp @@ -44,8 +44,10 @@ TextureAtlasEditor::TextureAtlasEditor( UIWindow* attachTo, const TGEditorCloseC if ( NULL == mUIWindow ) { mUIContainer = uiSceneNode; + uiSceneNode->getRoot()->addClass( "appbackground" ); } else { mUIContainer = mUIWindow->getContainer(); + mUIWindow->getContainer()->addClass( "appbackground" ); } std::string layout = R"xml( diff --git a/src/eepp/ui/uimenucheckbox.cpp b/src/eepp/ui/uimenucheckbox.cpp index 67d2040bd..b712f8a3d 100644 --- a/src/eepp/ui/uimenucheckbox.cpp +++ b/src/eepp/ui/uimenucheckbox.cpp @@ -10,6 +10,7 @@ UIMenuCheckBox* UIMenuCheckBox::New() { UIMenuCheckBox::UIMenuCheckBox() : UIMenuItem( "menu::checkbox" ), mActive( false ), mSkinActive( NULL ), mSkinInactive( NULL ) { + mIcon->setElementTag( mTag + "::icon" ); applyDefaultTheme(); mIcon->setFlags( UI_SKIN_KEEP_SIZE_ON_DRAW ); } @@ -45,16 +46,23 @@ void UIMenuCheckBox::setActive( const bool& active ) { bool oActive = mActive; mActive = active; + if ( mActive ) { + mIcon->pushState( UIState::StateSelected ); + } else { + mIcon->popState( UIState::StateSelected ); + } + if ( mActive ) { if ( NULL != mSkinActive ) { if ( NULL == mIcon->getSkin() || mIcon->getSkin()->getName() != mSkinActive->getName() ) mIcon->setSkin( mSkinActive ); if ( NULL != mSkinState ) { - if ( mSkinState->getState() & UIState::StateFlagSelected ) + if ( mSkinState->getState() & UIState::StateFlagSelected ) { mIcon->pushState( UIState::StateHover ); - else + } else { mIcon->popState( UIState::StateHover ); + } } } else { mIcon->removeSkin(); @@ -66,10 +74,11 @@ void UIMenuCheckBox::setActive( const bool& active ) { mIcon->setSkin( mSkinInactive ); if ( NULL != mSkinState ) { - if ( mSkinState->getState() & UIState::StateFlagSelected ) + if ( mSkinState->getState() & UIState::StateFlagSelected ) { mIcon->pushState( UIState::StateHover ); - else + } else { mIcon->popState( UIState::StateHover ); + } } } else { mIcon->removeSkin(); diff --git a/src/eepp/ui/uimessagebox.cpp b/src/eepp/ui/uimessagebox.cpp index e39d135b0..c1a3faf58 100644 --- a/src/eepp/ui/uimessagebox.cpp +++ b/src/eepp/ui/uimessagebox.cpp @@ -24,7 +24,8 @@ UIMessageBox::UIMessageBox( const Type& type, const String& message, const Uint3 UILinearLayout* vlay = UILinearLayout::NewVertical(); vlay->setLayoutSizeRules( LayoutSizeRule::WrapContent, LayoutSizeRule::WrapContent ) ->setLayoutMargin( Rect( 8, 8, 8, 8 ) ) - ->setParent( mLayoutCont ); + ->setParent( mLayoutCont ) + ->clipDisable(); mTextBox = UITextView::New(); mTextBox->setText( message ) @@ -35,7 +36,8 @@ UIMessageBox::UIMessageBox( const Type& type, const String& message, const Uint3 hlay->setLayoutMargin( Rect( 0, 8, 0, 0 ) ) ->setLayoutSizeRules( LayoutSizeRule::WrapContent, LayoutSizeRule::WrapContent ) ->setLayoutGravity( UI_HALIGN_RIGHT | UI_VALIGN_CENTER ) - ->setParent( vlay ); + ->setParent( vlay ) + ->clipDisable(); mButtonOK = UIPushButton::New(); mButtonOK->setSize( 90, 0 )->setParent( hlay ); @@ -74,6 +76,8 @@ UIMessageBox::UIMessageBox( const Type& type, const String& message, const Uint3 } } + reloadStyle( true, true ); + applyDefaultTheme(); } diff --git a/src/eepp/ui/uinodedrawable.cpp b/src/eepp/ui/uinodedrawable.cpp index 7da7c8cb1..30621b3e2 100644 --- a/src/eepp/ui/uinodedrawable.cpp +++ b/src/eepp/ui/uinodedrawable.cpp @@ -384,7 +384,7 @@ void UINodeDrawable::LayerDrawable::setDrawable( Drawable* drawable, const bool& mOwnsDrawable = ownIt; invalidate(); - if ( mDrawable->isDrawableResource() ) { + if ( NULL != mDrawable && mDrawable->isDrawableResource() ) { mResourceChangeCbId = reinterpret_cast( mDrawable ) ->pushResourceChangeCallback( [&]( DrawableResource::Event event, DrawableResource* ) { @@ -402,11 +402,9 @@ void UINodeDrawable::LayerDrawable::setDrawable( const std::string& drawableRef bool ownIt; Drawable* drawable = createDrawable( drawableRef, mSize, ownIt ); - if ( NULL != drawable ) { - setDrawable( drawable, ownIt ); + setDrawable( drawable, ownIt ); - mDrawableRef = drawableRef; - } + mDrawableRef = drawableRef; } Drawable* UINodeDrawable::LayerDrawable::createDrawable( const std::string& value, diff --git a/src/eepp/ui/uiscenenode.cpp b/src/eepp/ui/uiscenenode.cpp index a6493f73c..b8570748d 100644 --- a/src/eepp/ui/uiscenenode.cpp +++ b/src/eepp/ui/uiscenenode.cpp @@ -118,8 +118,6 @@ bool UISceneNode::windowExists( UIWindow* win ) { return mWindowsList.end() != std::find( mWindowsList.begin(), mWindowsList.end(), win ); } -static std::vector> times; - std::vector UISceneNode::loadNode( pugi::xml_node node, Node* parent ) { std::vector rootWidgets; @@ -139,7 +137,7 @@ std::vector UISceneNode::loadNode( pugi::xml_node node, Node* parent uiwidget->loadFromXmlNode( widget ); if ( mVerbose ) { - times.push_back( std::make_pair( + mTimes.push_back( std::make_pair( clock.getElapsedTime().asMilliseconds(), widget.name() ) ); } @@ -167,15 +165,15 @@ UIWidget* UISceneNode::loadLayoutNodes( pugi::xml_node node, Node* parent ) { if ( mVerbose ) { std::sort( - times.begin(), times.end(), + mTimes.begin(), mTimes.end(), []( const std::pair& left, const std::pair& right ) { return left.first < right.first; } ); - for ( auto& time : times ) { + for ( auto& time : mTimes ) { eePRINTL( "Widget %s created in %.2f ms", time.second.c_str(), time.first ); } - times.clear(); + mTimes.clear(); eePRINTL( "UISceneNode::loadLayoutNodes loaded nodes%s in: %.2f ms", id.empty() ? "" : std::string( " (id=" + id + ")" ).c_str(), @@ -242,13 +240,14 @@ bool UISceneNode::hasStyleSheet() { void UISceneNode::reloadStyle( const bool& disableAnimations ) { if ( NULL != mChild ) { - Node* ChildLoop = mChild; + Node* child = mChild; - while ( NULL != ChildLoop ) { - if ( ChildLoop->isWidget() ) - ChildLoop->asType()->reloadStyle( true, disableAnimations ); + while ( NULL != child ) { + if ( child->isWidget() ) { + child->asType()->reloadStyle( true, disableAnimations ); + } - ChildLoop = ChildLoop->getNextNode(); + child = child->getNextNode(); } } } diff --git a/src/eepp/ui/uistyle.cpp b/src/eepp/ui/uistyle.cpp index a1a1ab5cd..7f8693115 100644 --- a/src/eepp/ui/uistyle.cpp +++ b/src/eepp/ui/uistyle.cpp @@ -111,10 +111,10 @@ const bool& UIStyle::isChangingState() const { } StyleSheetVariable UIStyle::getVariable( const std::string& variable ) { - if ( NULL != mDefinition ) { - auto it = mDefinition->getVariables().find( String::hash( variable ) ); + if ( NULL != mGlobalDefinition ) { + auto it = mGlobalDefinition->getVariables().find( String::hash( variable ) ); - if ( it != mDefinition->getVariables().end() ) { + if ( it != mGlobalDefinition->getVariables().end() ) { return it->second; } } @@ -216,16 +216,18 @@ void UIStyle::onStateChange() { if ( newDefinition ) changedProperties |= newDefinition->getPropertyIds(); - if ( !newDefinition->getPropertyIds().empty() ) { - if ( nullptr != mDefinition ) { - const PropertyIdSet propertiesInBothDefinitions = - ( mDefinition->getPropertyIds() & newDefinition->getPropertyIds() ); + if ( !mForceReapplyProperties ) { + if ( nullptr != newDefinition && !newDefinition->getPropertyIds().empty() ) { + if ( nullptr != mDefinition ) { + const PropertyIdSet propertiesInBothDefinitions = + ( mDefinition->getPropertyIds() & newDefinition->getPropertyIds() ); - for ( Uint32 id : propertiesInBothDefinitions ) { - const StyleSheetProperty* p0 = mDefinition->getProperty( id ); - const StyleSheetProperty* p1 = newDefinition->getProperty( id ); - if ( nullptr != p0 && nullptr != p1 && *p0 == *p1 ) - changedProperties.erase( id ); + for ( Uint32 id : propertiesInBothDefinitions ) { + const StyleSheetProperty* p0 = mDefinition->getProperty( id ); + const StyleSheetProperty* p1 = newDefinition->getProperty( id ); + if ( nullptr != p0 && nullptr != p1 && *p0 == *p1 ) + changedProperties.erase( id ); + } } } } @@ -238,7 +240,7 @@ void UIStyle::onStateChange() { updateAnimations(); - if ( !mDefinition->getTransitionProperties().empty() ) { + if ( nullptr != mDefinition && !mDefinition->getTransitionProperties().empty() ) { mTransitions = TransitionDefinition::parseTransitionProperties( mDefinition->getTransitionProperties() ); } @@ -253,7 +255,6 @@ void UIStyle::onStateChange() { if ( property->getPropertyDefinition()->isIndexed() ) { for ( size_t i = 0; i < property->getPropertyIndexCount(); i++ ) { - applyVarValues( property->getPropertyIndexRef( i ) ); applyStyleSheetProperty( property->getPropertyIndex( i ), prevDefinition ); @@ -663,7 +664,9 @@ void UIStyle::removeAnimation( const PropertyDefinition* propertyDefinition, } StyleSheetProperty* UIStyle::getLocalProperty( Uint32 propId ) { - StyleSheetProperty* property = mDefinition->getProperty( propId ); + StyleSheetProperty* property = nullptr; + if ( nullptr != mDefinition ) + property = mDefinition->getProperty( propId ); if ( nullptr == property ) return mElementStyle->getPropertyById( propId ); return property; diff --git a/src/eepp/ui/uiwidget.cpp b/src/eepp/ui/uiwidget.cpp index feb6287f2..7bfdfc738 100644 --- a/src/eepp/ui/uiwidget.cpp +++ b/src/eepp/ui/uiwidget.cpp @@ -451,8 +451,10 @@ Node* UIWidget::setSize( const Float& Width, const Float& Height ) { Node* UIWidget::setId( const std::string& id ) { Node::setId( id ); - if ( !isSceneNodeLoading() && !isLoadingState() ) + if ( !isSceneNodeLoading() && !isLoadingState() ) { getUISceneNode()->invalidateStyle( this ); + getUISceneNode()->invalidateStyleState( this ); + } return this; } @@ -799,8 +801,10 @@ void UIWidget::addClass( const std::string& cls ) { if ( !cls.empty() && !hasClass( cls ) ) { mClasses.push_back( cls ); - if ( !isSceneNodeLoading() && !isLoadingState() ) + if ( !isSceneNodeLoading() && !isLoadingState() ) { getUISceneNode()->invalidateStyle( this ); + getUISceneNode()->invalidateStyleState( this ); + } onClassChange(); } @@ -816,8 +820,10 @@ void UIWidget::addClasses( const std::vector& classes ) { } } - if ( !isSceneNodeLoading() && !isLoadingState() ) + if ( !isSceneNodeLoading() && !isLoadingState() ) { getUISceneNode()->invalidateStyle( this ); + getUISceneNode()->invalidateStyleState( this ); + } onClassChange(); } @@ -827,8 +833,10 @@ void UIWidget::removeClass( const std::string& cls ) { if ( hasClass( cls ) ) { mClasses.erase( std::find( mClasses.begin(), mClasses.end(), cls ) ); - if ( !isSceneNodeLoading() && !isLoadingState() ) + if ( !isSceneNodeLoading() && !isLoadingState() ) { getUISceneNode()->invalidateStyle( this ); + getUISceneNode()->invalidateStyleState( this ); + } onClassChange(); } @@ -848,8 +856,10 @@ void UIWidget::removeClasses( const std::vector& classes ) { } } - if ( !isSceneNodeLoading() && !isLoadingState() ) + if ( !isSceneNodeLoading() && !isLoadingState() ) { getUISceneNode()->invalidateStyle( this ); + getUISceneNode()->invalidateStyleState( this ); + } onClassChange(); } @@ -867,8 +877,10 @@ void UIWidget::setElementTag( const std::string& tag ) { mMinHeightEq = ""; mMinSize = Sizef::Zero; - if ( !isSceneNodeLoading() && !isLoadingState() ) + if ( !isSceneNodeLoading() && !isLoadingState() ) { getUISceneNode()->invalidateStyle( this ); + getUISceneNode()->invalidateStyleState( this ); + } onTagChange(); } @@ -965,6 +977,7 @@ void UIWidget::onThemeLoaded() {} void UIWidget::onParentChange() { if ( !isSceneNodeLoading() && !isLoadingState() ) { getUISceneNode()->invalidateStyle( this ); + getUISceneNode()->invalidateStyleState( this, true ); } } diff --git a/src/eepp/ui/uiwindow.cpp b/src/eepp/ui/uiwindow.cpp index 13840a6d4..bba76810a 100644 --- a/src/eepp/ui/uiwindow.cpp +++ b/src/eepp/ui/uiwindow.cpp @@ -59,10 +59,10 @@ UIWindow::UIWindow( UIWindow::WindowBaseContainerType type, const StyleConfig& w switch ( type ) { case LINEAR_LAYOUT: - mContainer = UILinearLayout::New(); + mContainer = UILinearLayout::NewWithTag( "window::container" ); break; case RELATIVE_LAYOUT: - mContainer = UIRelativeLayout::New(); + mContainer = UIRelativeLayout::NewWithTag( "window::container" ); break; case SIMPLE_LAYOUT: default: diff --git a/src/test/eetest.cpp b/src/test/eetest.cpp index bd4e9751b..a7d04ec58 100644 --- a/src/test/eetest.cpp +++ b/src/test/eetest.cpp @@ -621,8 +621,8 @@ void EETest::createUI() { eePRINTL( "UIWidget size: %d", sizeof( UIWidget ) ); mTheme = UITheme::load( mThemeName, mThemeName, - MyPath + "ui/" + mThemeName + EE_TEXTURE_ATLAS_EXTENSION, TTF, - MyPath + "ui/uitheme.css" ); + MyPath + "ui/" + mThemeName + EE_TEXTURE_ATLAS_EXTENSION, TTF, + MyPath + "ui/uitheme.css" ); /*mTheme = UITheme::load( mThemeName, mThemeName, "", TTF, MyPath + "ui/breeze.css" );*/ diff --git a/src/tools/uieditor/uieditor.cpp b/src/tools/uieditor/uieditor.cpp index 2f7c383d4..4ca0b5abd 100644 --- a/src/tools/uieditor/uieditor.cpp +++ b/src/tools/uieditor/uieditor.cpp @@ -925,6 +925,7 @@ void createAppMenu() { void setUserDefaultTheme() { useDefaultTheme = true; uiSceneNode->getUIThemeManager()->setDefaultTheme( theme ); + uiSceneNode->combineStyleSheet( theme->getStyleSheet() ); } EE_MAIN_FUNC int main( int argc, char* argv[] ) { @@ -1002,6 +1003,7 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) { theme = UITheme::load( "uitheme" + pd, "uitheme" + pd, "assets/ui/uitheme" + pd + ".eta", font, "assets/ui/uitheme.css" ); + /*theme = UITheme::load( "uitheme", "uitheme", "", font, "assets/ui/breeze.css" );*/ uiSceneNode = UISceneNode::New(); uiSceneNode->setId( "uiSceneNode" ); @@ -1015,14 +1017,13 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) { appUiSceneNode->enableDrawInvalidation(); uiSceneNode->enableDrawInvalidation(); - appUiSceneNode->combineStyleSheet( theme->getStyleSheet() ); + appUiSceneNode->setStyleSheet( theme->getStyleSheet() ); appUiSceneNode->getUIThemeManager() ->setDefaultEffectsEnabled( true ) ->setDefaultTheme( theme ) ->setDefaultFont( font ) ->add( theme ); - uiSceneNode->combineStyleSheet( theme->getStyleSheet() ); uiSceneNode->getUIThemeManager()->setDefaultFont( font )->setDefaultEffectsEnabled( true ); if ( useAppTheme.Get() ) { @@ -1038,6 +1039,7 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) { uiContainer->setId( "appContainer" )->setSize( uiSceneNode->getSize() ); updateRecentProjects(); + updateRecentFiles(); resizeCb( window );