Fix status debugger panel serialization.

Fix UIWindow invalid min-size auto sizing.
Fix UIListView displaying horizontal scrollbar when wasn't necessary.
This commit is contained in:
Martín Lucas Golini
2026-08-20 17:12:25 -03:00
parent f193047f1e
commit c13710dddc
7 changed files with 61 additions and 20 deletions

View File

@@ -244,6 +244,7 @@ class EE_API UIAbstractTableView : public UIAbstractView {
ColumnWidthMode mColumnWidthMode{ ColumnWidthMode::Pixels };
bool mColumnWidthModeMenuEnabled{ false };
bool mUpdatingColumnsForScrollbars{ false };
bool mAutoExpandedColumnUsesVerticalScroll{ false };
std::string mPendingSerializedColumnWidths;
virtual ~UIAbstractTableView();

View File

@@ -61,8 +61,7 @@ class EE_API UIDropDown : public UITextInput {
protected:
StyleConfig mStyleConfig;
UINode* mFriendNode{ nullptr };
Uint64 mLastFocusLoss{ 0 };
std::vector<UIWidget*> mRelatedWidgets;
SmallVector<UIWidget*, 1> mRelatedWidgets;
UIDropDown( const std::string& tag );

View File

@@ -629,7 +629,11 @@ void UIAbstractTableView::updateColumnsWidth() {
if ( visibleColumnCount() == 1 && ( col = visibleColumn() ) != -1 ) {
Float width = eemax( getContentSpaceWidth(), getMaxColumnContentWidth( col, true ) );
bool shouldVScrollBeVisible = shouldVerticalScrollBeVisible();
if ( mScrollViewType == ScrollViewType::Outside || mVScroll->getAlpha() != 0.f ) {
const bool verticalScrollConsumesWidth =
mScrollViewType == ScrollViewType::Outside || mVScroll->getAlpha() != 0.f;
mAutoExpandedColumnUsesVerticalScroll =
shouldVScrollBeVisible && verticalScrollConsumesWidth;
if ( verticalScrollConsumesWidth ) {
if ( !mVScroll->isVisible() && shouldVScrollBeVisible )
width -= getVerticalScrollBar()->getPixelsSize().getWidth();
else if ( mVScroll->isVisible() && !shouldVScrollBeVisible )
@@ -843,10 +847,19 @@ void UIAbstractTableView::onContentSizeChange() {
bool verticalScrollWasVisible = mVScroll->isVisible();
UIScrollableWidget::onContentSizeChange();
const bool columnsDependOnContentWidth =
mColumnWidthMode == ColumnWidthMode::Percentage || mAutoColumnsWidth ||
( mAutoExpandOnSingleColumn && visibleColumnCount() == 1 );
if ( !columnsDependOnContentWidth || verticalScrollWasVisible == mVScroll->isVisible() )
const bool autoExpandedSingleColumn = mAutoExpandOnSingleColumn && visibleColumnCount() == 1;
const bool columnsDependOnContentWidth = mColumnWidthMode == ColumnWidthMode::Percentage ||
mAutoColumnsWidth || autoExpandedSingleColumn;
const bool verticalScrollConsumesWidth =
mVScroll->isVisible() &&
( mScrollViewType == ScrollViewType::Outside || mVScroll->getAlpha() != 0.f );
// Visibility can be updated before this callback begins, so comparing only the state before and
// after the base implementation can miss a stale auto-expanded width.
const bool autoExpandedColumnIsStale =
autoExpandedSingleColumn &&
mAutoExpandedColumnUsesVerticalScroll != verticalScrollConsumesWidth;
if ( !columnsDependOnContentWidth ||
( verticalScrollWasVisible == mVScroll->isVisible() && !autoExpandedColumnIsStale ) )
return;
mUpdatingColumnsForScrollbars = true;

View File

@@ -227,8 +227,6 @@ void UIDropDown::onPopUpFocusLoss() {
if ( getEventDispatcher()->getFocusNode() != this && !isChildFocus && !friendIsFocus &&
!isRelatedWidget ) {
hide();
mLastFocusLoss = Sys::getTicks();
}
}

View File

@@ -563,13 +563,12 @@ void UIWindow::onSizeChange() {
Sizef size( getMinWindowSizeWithDecoration() );
if ( getSize().getWidth() < size.getWidth() || getSize().getHeight() < size.getHeight() ) {
if ( getSize().getWidth() < size.getWidth() &&
getSize().getHeight() < mStyleConfig.MinWindowSize.getHeight() ) {
setSize( mStyleConfig.MinWindowSize );
if ( getSize().getWidth() < size.getWidth() && getSize().getHeight() < size.getHeight() ) {
internalSize( size );
} else if ( getSize().getWidth() < size.getWidth() ) {
setSize( Sizef( mStyleConfig.MinWindowSize.getWidth(), getSize().getHeight() ) );
internalSize( Sizef( size.getWidth(), getSize().getHeight() ) );
} else if ( getSize().getHeight() < size.getHeight() ) {
setSize( Sizef( getSize().getWidth(), mStyleConfig.MinWindowSize.getHeight() ) );
internalSize( Sizef( getSize().getWidth(), size.getHeight() ) );
}
} else {
fixChildrenSize();

View File

@@ -35,6 +35,7 @@ class TransferTestTabWidget : public UITabWidget {
class ThreeColumnModel : public Model {
public:
explicit ThreeColumnModel( size_t rows = 1 ) : mRows( rows ) {}
void setRows( size_t rows ) { mRows = rows; }
size_t rowCount( const ModelIndex& = ModelIndex() ) const override { return mRows; }
size_t columnCount( const ModelIndex& = ModelIndex() ) const override { return 3; }
@@ -74,6 +75,8 @@ class PercentageTestTable : public UITableView {
onColumnResizeToContent( column );
}
void updateScrollbars() { onContentSizeChange(); }
Float getMaxColumnContentWidth( const size_t&, bool ) override { return mContentWidth; }
protected:
@@ -330,6 +333,32 @@ UTEST( UIAbstractTableView, AutoPixelColumnsRecomputeWhenVerticalScrollbarAppear
EXPECT_FALSE( table->getHorizontalScrollBar()->isVisible() );
}
UTEST( UIAbstractTableView, AutoExpandedSingleColumnAccountsForVerticalScrollbar ) {
UIApplication app(
WindowSettings( 800, 600, "eepp - unit tests" ),
UIApplication::Settings( Sys::getProcessPath() + ".." + FileSystem::getOSSlash(), 1 ) );
auto* table = PercentageTestTable::New();
table->setParent( app.getUI() );
table->setPixelsSize( 400, 100 );
table->setAutoExpandOnSingleColumn( true );
table->setModel( std::make_shared<ThreeColumnModel>( 100 ) );
table->setColumnsVisible( { 0 } );
app.getUI()->update( Milliseconds( 16 ) );
EXPECT_TRUE( table->getVerticalScrollBar()->isVisible() );
EXPECT_EQ( table->getColumnWidth( 0 ), table->getContentSpaceWidth() );
EXPECT_FALSE( table->getHorizontalScrollBar()->isVisible() );
auto model = std::make_shared<ThreeColumnModel>();
table->setModel( model );
model->setRows( 100 );
table->getVerticalScrollBar()->setVisible( true );
table->updateScrollbars();
EXPECT_TRUE( table->getVerticalScrollBar()->isVisible() );
EXPECT_EQ( table->getColumnWidth( 0 ), table->getContentSpaceWidth() );
EXPECT_FALSE( table->getHorizontalScrollBar()->isVisible() );
}
UTEST( UIAbstractTableView, ColumnWidthsSerializationRoundTripsBothModes ) {
UIApplication app(
WindowSettings( 800, 600, "eepp - unit tests" ),

View File

@@ -141,7 +141,9 @@ StatusDebuggerController::getLocalDefaultKeybindings() {
StatusDebuggerController::StatusDebuggerController( UISplitter* mainSplitter,
UISceneNode* uiSceneNode,
PluginContextProvider* pluginContext ) :
StatusBarElement( mainSplitter, uiSceneNode, pluginContext ) {}
StatusBarElement( mainSplitter, uiSceneNode, pluginContext ) {
mSerializedLayout = mContext->getConfig().iniState.getValue( "debugger", "panel_layout" );
}
StatusDebuggerController::~StatusDebuggerController() {
mEventConnections.clear();
@@ -346,9 +348,7 @@ void StatusDebuggerController::restoreTabLayout() {
"debugger-breakpoints", "debugger-console" };
mRestoringLayout = true;
bool restored = false;
mSerializedLayout = mContext->getConfig().iniState.getValue(
"debugger", "panel_layout",
mContext->getConfig().iniState.getValue( "ui", "debugger_panel_layout", "" ) );
mSerializedLayout = mContext->getConfig().iniState.getValue( "debugger", "panel_layout" );
const std::string& saved = mSerializedLayout;
if ( !saved.empty() ) {
auto layout = nlohmann::json::parse( saved, nullptr, false, true );
@@ -392,11 +392,13 @@ void StatusDebuggerController::restoreTabLayout() {
mUITabWidget->setTabSelected( Uint32{ 0 } );
mUIRightTabWidget->setTabSelected( Uint32{ 0 } );
}
if ( mUITabWidget->getTabCount() )
if ( mUITabWidget->getTabCount() ) {
mTabWidgetSplitter->setCurrentWidget(
mUITabWidget->getTabSelected()->getOwnedWidget()->asType<UIWidget>() );
}
mRestoringLayout = false;
saveTabLayout();
updateRightPanel();
}