Minor nit: improve dropdown list scrolling.

This commit is contained in:
Martín Lucas Golini
2026-06-14 16:30:21 -03:00
parent 66d1a85344
commit 407fc1ae11
5 changed files with 51 additions and 4 deletions

View File

@@ -130,6 +130,7 @@ class EE_API Event {
OnToggle,
OnFocusWithin,
OnFocusWithinLoss,
OnItemsCountChange,
NoEvent = eeINDEX_NOT_FOUND
};

View File

@@ -18,6 +18,7 @@ class EE_API UIDropDownList : public UIDropDown {
virtual ~UIDropDownList();
virtual Uint32 getType() const;
virtual bool isType( const Uint32& type ) const;
UIListBox* getListBox() const;
@@ -27,17 +28,24 @@ class EE_API UIDropDownList : public UIDropDown {
virtual UIDropDownList* setMaxNumVisibleItems( const Uint32& maxNumVisibleItems );
virtual bool applyProperty( const StyleSheetProperty& attribute );
virtual std::string getPropertyString( const PropertyDefinition* propertyDef,
const Uint32& propertyIndex = 0 ) const;
virtual std::vector<PropertyId> getPropertiesImplemented() const;
virtual void loadFromXmlNode( const pugi::xml_node& node );
void setClickStepItems( Uint32 num );
Uint32 getClickStepItems() const { return mClickStepItems; }
protected:
friend class UIComboBox;
UIListBox* mListBox;
Uint32 mListBoxCloseCb{ 0 };
Uint32 mClickStepItems{ 3 };
UIDropDownList( const std::string& tag = "dropdownlist" );
@@ -52,6 +60,8 @@ class EE_API UIDropDownList : public UIDropDown {
virtual void onClassChange();
void destroyListBox();
void updateClickStep();
};
}} // namespace EE::UI

View File

@@ -63,6 +63,8 @@ class EE_API UIListBox : public UITouchDraggableWidget {
std::vector<UIListBoxItem*> getItemsSelected();
Uint32 getVisibleItemsCount() const;
Rectf getContainerPadding() const;
void setSmoothScroll( const bool& soft );
@@ -195,6 +197,8 @@ class EE_API UIListBox : public UITouchDraggableWidget {
virtual void onTouchDragValueChange( Vector2f diff );
virtual bool isTouchOverAllowedChildren();
void onItemsCountChange();
};
}} // namespace EE::UI

View File

@@ -37,6 +37,7 @@ UIDropDownList::UIDropDownList( const std::string& tag ) : UIDropDown( tag ), mL
mListBox->on( Event::OnItemKeyDown, [this]( auto event ) { onItemKeyDown( event ); } );
mListBox->on( Event::KeyDown, [this]( auto event ) { onItemKeyDown( event ); } );
mListBox->on( Event::OnClear, [this]( auto event ) { onWidgetClear( event ); } );
mListBox->on( Event::OnItemsCountChange, [this]( auto event ) { updateClickStep(); } );
mListBoxCloseCb =
mListBox->on( Event::OnClose, [this]( const Event* ) { mListBox = nullptr; } );
mListBox->on( Event::OnSelectionChanged, [this]( auto ) {
@@ -139,10 +140,12 @@ UIDropDownList* UIDropDownList::setMaxNumVisibleItems( const Uint32& maxNumVisib
if ( maxNumVisibleItems != mStyleConfig.MaxNumVisibleItems ) {
mStyleConfig.MaxNumVisibleItems = maxNumVisibleItems;
if ( NULL != mListBox )
if ( NULL != mListBox ) {
mListBox->setSize( getSize().getWidth(), std::min( mStyleConfig.MaxNumVisibleItems,
getListBox()->getItemsCount() ) *
mListBox->getRowHeight() );
updateClickStep();
}
}
return this;
}
@@ -232,4 +235,20 @@ void UIDropDownList::onClassChange() {
mListBox->setClasses( getClasses() );
}
void UIDropDownList::setClickStepItems( Uint32 num ) {
if ( num != mClickStepItems ) {
mClickStepItems = num;
updateClickStep();
}
}
void UIDropDownList::updateClickStep() {
if ( mListBox == nullptr )
return;
Float totalScrollableItems = (Float)mListBox->getItemsCount() - getMaxNumVisibleItems();
mListBox->getVerticalScrollBar()->setClickStep(
totalScrollableItems > mClickStepItems ? mClickStepItems / totalScrollableItems
: mListBox->getVerticalScrollBar()->getMaxValue() );
}
}} // namespace EE::UI

View File

@@ -135,6 +135,7 @@ void UIListBox::addListBoxItems( const std::vector<String>& texts ) {
findMaxWidth();
updatePageStep();
updateScroll();
onItemsCountChange();
}
Uint32 UIListBox::addListBoxItem( const String& text ) {
@@ -143,6 +144,7 @@ Uint32 UIListBox::addListBoxItem( const String& text ) {
updatePageStep();
updateScroll();
onItemsCountChange();
return (Uint32)( mItems.size() - 1 );
}
@@ -190,6 +192,8 @@ void UIListBox::removeListBoxItems( const std::vector<Uint32>& ItemsIndex ) {
if ( mTexts.empty() )
sendCommonEvent( Event::OnClear );
onItemsCountChange();
}
void UIListBox::clear() {
@@ -204,11 +208,12 @@ void UIListBox::clear() {
sendCommonEvent( Event::OnClear );
sendCommonEvent( Event::OnSelectionChanged );
onItemsCountChange();
}
Uint32 UIListBox::removeListBoxItem( Uint32 ItemIndex ) {
removeListBoxItems( { ItemIndex } );
onItemsCountChange();
return ItemIndex;
}
@@ -415,7 +420,7 @@ void UIListBox::createItemIndex( const Uint32& i ) {
void UIListBox::updateScrollBarState() {
bool clipped = 0 != mContainer->isClipped();
Uint32 visibleItems = mContainer->getSize().getHeight() / mRowHeight;
Uint32 visibleItems = getVisibleItemsCount();
mItemsNotVisible = (Int32)mItems.size() - visibleItems;
if ( mItemsNotVisible <= 0 ) {
@@ -488,7 +493,7 @@ void UIListBox::updateScroll( bool fromScrollChange ) {
updateScrollBarState();
Uint32 visibleItems = mContainer->getSize().getHeight() / mRowHeight;
Uint32 visibleItems = getVisibleItemsCount();
mItemsNotVisible = (Uint32)mItems.size() - visibleItems;
Int32 scrolleable = (Int32)mItems.size() * mRowHeight - mContainer->getSize().getHeight();
bool isScrollVisible = mVScrollBar->isVisible();
@@ -729,6 +734,10 @@ std::vector<UIListBoxItem*> UIListBox::getItemsSelected() {
return tItems;
}
Uint32 UIListBox::getVisibleItemsCount() const {
return mContainer->getSize().getHeight() / mRowHeight;
}
Uint32 UIListBox::getItemIndex( UIListBoxItem* Item ) {
for ( Uint32 i = 0; i < mItems.size(); i++ ) {
if ( Item == mItems[i] )
@@ -1138,4 +1147,8 @@ void UIListBox::loadItemsFromXmlNode( const pugi::xml_node& node ) {
endAttributesTransaction();
}
void UIListBox::onItemsCountChange() {
sendCommonEvent( Event::OnItemsCountChange );
}
}} // namespace EE::UI