mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-02 11:10:31 +03:00
Fix stack-overflow when auto-sizing dropdowns.
Fix combobox button click not closing the popup listbox when clicking the button with a visible popup listbox. Fix some incorrect size policies in UIFileDialog.
This commit is contained in:
@@ -21,7 +21,7 @@ class EE_API UIComboBox : public UIWidget {
|
|||||||
|
|
||||||
UIDropDownList* getDropDownList() const { return mDropDownList; }
|
UIDropDownList* getDropDownList() const { return mDropDownList; }
|
||||||
|
|
||||||
UINode* getButton() const { return mButton; }
|
UIWidget* getButton() const { return mButton; }
|
||||||
|
|
||||||
const String& getText();
|
const String& getText();
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ class EE_API UIComboBox : public UIWidget {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
UIDropDownList* mDropDownList;
|
UIDropDownList* mDropDownList;
|
||||||
UINode* mButton;
|
UIWidget* mButton;
|
||||||
|
|
||||||
UIComboBox();
|
UIComboBox();
|
||||||
|
|
||||||
|
|||||||
@@ -51,15 +51,24 @@ class EE_API UIDropDown : public UITextInput {
|
|||||||
const Uint32& propertyIndex = 0 ) const;
|
const Uint32& propertyIndex = 0 ) const;
|
||||||
virtual std::vector<PropertyId> getPropertiesImplemented() const;
|
virtual std::vector<PropertyId> getPropertiesImplemented() const;
|
||||||
|
|
||||||
|
void addRelatedWidget( UIWidget* widget ) { mRelatedWidgets.push_back( widget ); }
|
||||||
|
|
||||||
|
void removeRelatedWidget( UIWidget* widget ) {
|
||||||
|
mRelatedWidgets.erase(
|
||||||
|
std::find( mRelatedWidgets.begin(), mRelatedWidgets.end(), widget ) );
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
StyleConfig mStyleConfig;
|
StyleConfig mStyleConfig;
|
||||||
UINode* mFriendNode{ nullptr };
|
UINode* mFriendNode{ nullptr };
|
||||||
|
Uint64 mLastFocusLoss{ 0 };
|
||||||
|
std::vector<UIWidget*> mRelatedWidgets;
|
||||||
|
|
||||||
UIDropDown( const std::string& tag );
|
UIDropDown( const std::string& tag );
|
||||||
|
|
||||||
virtual UIWidget* getPopUpWidget() const;
|
virtual UIWidget* getPopUpWidget() const;
|
||||||
|
|
||||||
void onPopUpFocusLoss( const Event* Event );
|
virtual void onPopUpFocusLoss();
|
||||||
|
|
||||||
virtual void onItemSelected( const Event* Event );
|
virtual void onItemSelected( const Event* Event );
|
||||||
virtual void show();
|
virtual void show();
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ enum UIFlag : Int64 {
|
|||||||
UI_HTML_ELEMENT = ( 1ULL << 31 ),
|
UI_HTML_ELEMENT = ( 1ULL << 31 ),
|
||||||
UI_CREATING_NODE = ( 1ULL << 32 ),
|
UI_CREATING_NODE = ( 1ULL << 32 ),
|
||||||
UI_IGNORE_GLOBAL_CSS = ( 1ULL << 33 ),
|
UI_IGNORE_GLOBAL_CSS = ( 1ULL << 33 ),
|
||||||
|
UI_AUTO_SIZING = ( 1ULL << 34 ),
|
||||||
};
|
};
|
||||||
|
|
||||||
enum UINodeType {
|
enum UINodeType {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ UIComboBox::UIComboBox() : UIWidget( "combobox" ), mDropDownList( NULL ), mButto
|
|||||||
mButton->setVisible( true );
|
mButton->setVisible( true );
|
||||||
mButton->setEnabled( true );
|
mButton->setEnabled( true );
|
||||||
mButton->on( Event::OnSizeChange, [this]( const Event* ) { onSizeChange(); } );
|
mButton->on( Event::OnSizeChange, [this]( const Event* ) { onSizeChange(); } );
|
||||||
|
mDropDownList->addRelatedWidget( mButton );
|
||||||
|
|
||||||
applyDefaultTheme();
|
applyDefaultTheme();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,14 +75,21 @@ void UIDropDown::setFriendNode( UINode* friendNode ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UIDropDown::onAutoSize() {
|
void UIDropDown::onAutoSize() {
|
||||||
|
if ( mFlags & UI_AUTO_SIZING )
|
||||||
|
return;
|
||||||
|
|
||||||
|
mFlags |= UI_AUTO_SIZING;
|
||||||
|
|
||||||
Float max = eemax<Float>( PixelDensity::dpToPxI( getSkinSize().getHeight() ),
|
Float max = eemax<Float>( PixelDensity::dpToPxI( getSkinSize().getHeight() ),
|
||||||
mTextCache.getLineSpacing() );
|
mTextCache.getLineSpacing() );
|
||||||
|
|
||||||
if ( mHeightPolicy == SizePolicy::WrapContent && mLayoutWeight == 0 ) {
|
if ( mHeightPolicy == SizePolicy::WrapContent ) {
|
||||||
setInternalPixelsHeight( eeceil( max + mPaddingPx.Top + mPaddingPx.Bottom ) );
|
setInternalPixelsHeight( eeceil( max + mPaddingPx.Top + mPaddingPx.Bottom ) );
|
||||||
} else if ( ( mFlags & UI_AUTO_SIZE ) && 0 == getSize().getHeight() && max > 0 ) {
|
} else if ( ( mFlags & UI_AUTO_SIZE ) && 0 == getSize().getHeight() && max > 0 ) {
|
||||||
setInternalPixelsHeight( eeceil( max ) );
|
setInternalPixelsHeight( eeceil( max ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mFlags &= ~UI_AUTO_SIZING;
|
||||||
}
|
}
|
||||||
|
|
||||||
UIWidget* UIDropDown::getPopUpWidget() const {
|
UIWidget* UIDropDown::getPopUpWidget() const {
|
||||||
@@ -207,15 +214,21 @@ void UIDropDown::onItemKeyDown( const Event* Event ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIDropDown::onPopUpFocusLoss( const Event* ) {
|
void UIDropDown::onPopUpFocusLoss() {
|
||||||
if ( NULL == getEventDispatcher() )
|
if ( NULL == getEventDispatcher() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool frienIsFocus = NULL != mFriendNode && mFriendNode == getEventDispatcher()->getFocusNode();
|
bool friendIsFocus = NULL != mFriendNode && mFriendNode == getEventDispatcher()->getFocusNode();
|
||||||
bool isChildFocus = isChild( getEventDispatcher()->getFocusNode() );
|
bool isChildFocus = isChild( getEventDispatcher()->getFocusNode() );
|
||||||
|
bool isRelatedWidget =
|
||||||
|
std::find( mRelatedWidgets.begin(), mRelatedWidgets.end(),
|
||||||
|
getEventDispatcher()->getFocusNode() ) != mRelatedWidgets.end();
|
||||||
|
|
||||||
if ( getEventDispatcher()->getFocusNode() != this && !isChildFocus && !frienIsFocus ) {
|
if ( getEventDispatcher()->getFocusNode() != this && !isChildFocus && !friendIsFocus &&
|
||||||
|
!isRelatedWidget ) {
|
||||||
hide();
|
hide();
|
||||||
|
|
||||||
|
mLastFocusLoss = Sys::getTicks();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ UIDropDownList::UIDropDownList( const std::string& tag ) : UIDropDown( tag ), mL
|
|||||||
// This will force to change the parent when shown, and force the CSS style reload.
|
// This will force to change the parent when shown, and force the CSS style reload.
|
||||||
mListBox->setParent( this );
|
mListBox->setParent( this );
|
||||||
|
|
||||||
mListBox->on( Event::OnWidgetFocusLoss, [this]( auto event ) { onPopUpFocusLoss( event ); } );
|
mListBox->on( Event::OnWidgetFocusLoss, [this]( auto event ) { onPopUpFocusLoss(); } );
|
||||||
mListBox->on( Event::OnItemSelected, [this]( auto event ) { onItemSelected( event ); } );
|
mListBox->on( Event::OnItemSelected, [this]( auto event ) { onItemSelected( event ); } );
|
||||||
mListBox->on( Event::OnItemClicked, [this]( auto event ) { onItemClicked( event ); } );
|
mListBox->on( Event::OnItemClicked, [this]( auto event ) { onItemClicked( event ); } );
|
||||||
mListBox->on( Event::OnItemKeyDown, [this]( auto event ) { onItemKeyDown( event ); } );
|
mListBox->on( Event::OnItemKeyDown, [this]( auto event ) { onItemKeyDown( event ); } );
|
||||||
@@ -99,16 +99,22 @@ Uint32 UIDropDownList::onKeyDown( const KeyEvent& Event ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UIDropDownList::onAutoSize() {
|
void UIDropDownList::onAutoSize() {
|
||||||
|
if ( mFlags & UI_AUTO_SIZING )
|
||||||
|
return;
|
||||||
|
|
||||||
UIDropDown::onAutoSize();
|
UIDropDown::onAutoSize();
|
||||||
|
|
||||||
Float max = eemax<Float>( PixelDensity::dpToPxI( getSkinSize().getWidth() ),
|
mFlags |= UI_AUTO_SIZING;
|
||||||
getTextWidth() );
|
|
||||||
|
|
||||||
if ( mWidthPolicy == SizePolicy::WrapContent && mLayoutWeight == 0 ) {
|
Float max = eemax<Float>( PixelDensity::dpToPxI( getSkinSize().getWidth() ), getTextWidth() );
|
||||||
|
|
||||||
|
if ( mWidthPolicy == SizePolicy::WrapContent ) {
|
||||||
setInternalPixelsWidth( eeceil( max + mPaddingPx.Left + mPaddingPx.Right ) );
|
setInternalPixelsWidth( eeceil( max + mPaddingPx.Left + mPaddingPx.Right ) );
|
||||||
} else if ( ( mFlags & UI_AUTO_SIZE ) && 0 == getSize().getWidth() && max > 0 ) {
|
} else if ( ( mFlags & UI_AUTO_SIZE ) && 0 == getSize().getWidth() && max > 0 ) {
|
||||||
setInternalPixelsWidth( eeceil( max ) );
|
setInternalPixelsWidth( eeceil( max ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mFlags &= ~UI_AUTO_SIZING;
|
||||||
}
|
}
|
||||||
|
|
||||||
UIDropDownList* UIDropDownList::showList() {
|
UIDropDownList* UIDropDownList::showList() {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ UIDropDownModelList::UIDropDownModelList( const std::string& tag ) :
|
|||||||
mListView->setParent( this );
|
mListView->setParent( this );
|
||||||
mListView->setSingleClickNavigation( true );
|
mListView->setSingleClickNavigation( true );
|
||||||
|
|
||||||
mListView->on( Event::OnWidgetFocusLoss, [this]( auto event ) { onPopUpFocusLoss( event ); } );
|
mListView->on( Event::OnWidgetFocusLoss, [this]( auto event ) { onPopUpFocusLoss(); } );
|
||||||
mListView->on( Event::OnModelEvent, [this]( auto event ) { onItemSelected( event ); } );
|
mListView->on( Event::OnModelEvent, [this]( auto event ) { onItemSelected( event ); } );
|
||||||
mListView->on( Event::KeyDown, [this]( auto event ) { onItemKeyDown( event ); } );
|
mListView->on( Event::KeyDown, [this]( auto event ) { onItemKeyDown( event ); } );
|
||||||
mListView->on( Event::OnClear, [this]( auto event ) { onWidgetClear( event ); } );
|
mListView->on( Event::OnClear, [this]( auto event ) { onWidgetClear( event ); } );
|
||||||
@@ -87,7 +87,7 @@ void UIDropDownModelList::setListView( UIAbstractTableView* listView ) {
|
|||||||
mListView->setVisible( false );
|
mListView->setVisible( false );
|
||||||
mListView->setParent( this );
|
mListView->setParent( this );
|
||||||
|
|
||||||
mListView->on( Event::OnWidgetFocusLoss, [this]( auto event ) { onPopUpFocusLoss( event ); } );
|
mListView->on( Event::OnWidgetFocusLoss, [this]( auto event ) { onPopUpFocusLoss(); } );
|
||||||
mListView->on( Event::OnModelEvent, [this]( auto event ) { onItemSelected( event ); } );
|
mListView->on( Event::OnModelEvent, [this]( auto event ) { onItemSelected( event ); } );
|
||||||
mListView->on( Event::KeyDown, [this]( auto event ) { onItemKeyDown( event ); } );
|
mListView->on( Event::KeyDown, [this]( auto event ) { onItemKeyDown( event ); } );
|
||||||
mListView->on( Event::OnClear, [this]( auto event ) { onWidgetClear( event ); } );
|
mListView->on( Event::OnClear, [this]( auto event ) { onWidgetClear( event ); } );
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ UIFileDialog::UIFileDialog( Uint32 dialogFlags, const std::string& defaultFilePa
|
|||||||
|
|
||||||
mPath = UITextInput::New();
|
mPath = UITextInput::New();
|
||||||
mPath->setText( mCurPath )
|
mPath->setText( mCurPath )
|
||||||
->setLayoutSizePolicy( SizePolicy::WrapContent, SizePolicy::WrapContent )
|
->setLayoutSizePolicy( SizePolicy::Fixed, SizePolicy::WrapContent )
|
||||||
->setLayoutWeight( 1 )
|
->setLayoutWeight( 1 )
|
||||||
->setParent( hLayout );
|
->setParent( hLayout );
|
||||||
mPath->on( Event::OnPressEnter, [this]( auto event ) { onPressEnter( event ); } );
|
mPath->on( Event::OnPressEnter, [this]( auto event ) { onPressEnter( event ); } );
|
||||||
@@ -176,7 +176,7 @@ UIFileDialog::UIFileDialog( Uint32 dialogFlags, const std::string& defaultFilePa
|
|||||||
|
|
||||||
mMultiView = UIMultiModelView::New();
|
mMultiView = UIMultiModelView::New();
|
||||||
mMultiView->setParent( linearLayout );
|
mMultiView->setParent( linearLayout );
|
||||||
mMultiView->setLayoutSizePolicy( SizePolicy::MatchParent, SizePolicy::WrapContent )
|
mMultiView->setLayoutSizePolicy( SizePolicy::MatchParent, SizePolicy::Fixed )
|
||||||
->setLayoutWeight( 1 )
|
->setLayoutWeight( 1 )
|
||||||
->setLayoutMargin( Rectf( 0, 0, 0, 4 ) );
|
->setLayoutMargin( Rectf( 0, 0, 0, 4 ) );
|
||||||
mMultiView->on( Event::KeyDown, [this]( const Event* event ) {
|
mMultiView->on( Event::KeyDown, [this]( const Event* event ) {
|
||||||
@@ -245,7 +245,7 @@ UIFileDialog::UIFileDialog( Uint32 dialogFlags, const std::string& defaultFilePa
|
|||||||
->setEnabled( false );
|
->setEnabled( false );
|
||||||
|
|
||||||
mFile = UITextInput::New();
|
mFile = UITextInput::New();
|
||||||
mFile->setLayoutSizePolicy( SizePolicy::WrapContent, SizePolicy::MatchParent )
|
mFile->setLayoutSizePolicy( SizePolicy::Fixed, SizePolicy::MatchParent )
|
||||||
->setLayoutWeight( 1 )
|
->setLayoutWeight( 1 )
|
||||||
->setParent( hLayout );
|
->setParent( hLayout );
|
||||||
mFile->setLayoutMargin( Rectf( 0, 0, 4, 0 ) );
|
mFile->setLayoutMargin( Rectf( 0, 0, 4, 0 ) );
|
||||||
|
|||||||
Reference in New Issue
Block a user