diff --git a/bin/unit_tests/assets/html/hn_thread_test.html b/bin/unit_tests/assets/html/hn_thread_test.html
index d2544b057..8369a0e4a 100644
--- a/bin/unit_tests/assets/html/hn_thread_test.html
+++ b/bin/unit_tests/assets/html/hn_thread_test.html
@@ -1,15 +1,7 @@
-
-
-
-
-
-
- $500 GPU outperforms Claude Sonnet on coding benchmarks | Hacker News
-
@@ -181,6 +173,4 @@
-
-
diff --git a/src/eepp/ui/uihtmltable.cpp b/src/eepp/ui/uihtmltable.cpp
index 28160c52b..80daf9e0b 100644
--- a/src/eepp/ui/uihtmltable.cpp
+++ b/src/eepp/ui/uihtmltable.cpp
@@ -133,9 +133,9 @@ void UIHTMLTable::computeIntrinsicWidths() const {
cell->mWidthPolicy = SizePolicy::WrapContent;
Float cellMin = cell->getMinIntrinsicWidth();
Float cellMax = cell->getMaxIntrinsicWidth();
- Float cellSpecified = std::max( cell->getPropertyWidth(),
- getRecursiveSpecifiedWidth(
- getRecursiveSpecifiedWidth, cell ) );
+ Float cellSpecified =
+ std::max( cell->getPropertyWidth(),
+ getRecursiveSpecifiedWidth( getRecursiveSpecifiedWidth, cell ) );
cell->mWidthPolicy = widthPolicy;
Uint32 colspan = cell->getColspan();
@@ -164,9 +164,9 @@ void UIHTMLTable::computeIntrinsicWidths() const {
cell->mWidthPolicy = SizePolicy::WrapContent;
Float cellMin = cell->getMinIntrinsicWidth();
Float cellMax = cell->getMaxIntrinsicWidth();
- Float cellSpecified = std::max( cell->getPropertyWidth(),
- getRecursiveSpecifiedWidth(
- getRecursiveSpecifiedWidth, cell ) );
+ Float cellSpecified =
+ std::max( cell->getPropertyWidth(),
+ getRecursiveSpecifiedWidth( getRecursiveSpecifiedWidth, cell ) );
cell->mWidthPolicy = widthPolicy;
Uint32 colspan = cell->getColspan();
@@ -220,8 +220,10 @@ void UIHTMLTable::computeIntrinsicWidths() const {
totalMax += mColMaxWidths[i];
}
- mMinIntrinsicWidth = totalMin + mPaddingPx.Left + mPaddingPx.Right + ( maxCols + 1 ) * mCellspacing;
- mMaxIntrinsicWidth = totalMax + mPaddingPx.Left + mPaddingPx.Right + ( maxCols + 1 ) * mCellspacing;
+ mMinIntrinsicWidth =
+ totalMin + mPaddingPx.Left + mPaddingPx.Right + ( maxCols + 1 ) * mCellspacing;
+ mMaxIntrinsicWidth =
+ totalMax + mPaddingPx.Left + mPaddingPx.Right + ( maxCols + 1 ) * mCellspacing;
mIntrinsicWidthsDirty = false;
}
@@ -266,24 +268,25 @@ void UIHTMLTable::updateLayout() {
mPacking = false;
return;
}
-
Float totalMin = 0.f;
- // Float totalMax = 0.f;
+ Float totalMax = 0.f; // Make sure this is uncommented
for ( size_t i = 0; i < maxCols; ++i ) {
totalMin += mColMinWidths[i];
- // totalMax += mColMaxWidths[i];
+ totalMax += mColMaxWidths[i]; // Accumulate max widths
}
Float tableUsedWidth = availableWidth; // always try to fill the container
// Assign column widths
if ( tableUsedWidth <= totalMin + 0.001f ) {
- // 1. Too narrow → scale down proportionally
- Float scale = tableUsedWidth / totalMin;
+ // 1. Too narrow → scale down proportionally to min widths
+ Float scale = totalMin > 0.001f ? ( tableUsedWidth / totalMin ) : 0.f;
for ( size_t i = 0; i < maxCols; ++i )
mColWidths[i] = mColMinWidths[i] * scale;
- } else {
- // 2. Extra space → distribute extra by flexibility
+
+ } else if ( tableUsedWidth <= totalMax + 0.001f ) {
+ // 2. Partial flex → space is between min and max. Distribute extra by flexibility (text
+ // wrapping)
Float extraSpace = tableUsedWidth - totalMin;
Float totalFlex = 0.f;
@@ -303,17 +306,55 @@ void UIHTMLTable::updateLayout() {
mColWidths[i] = mColMinWidths[i] + added;
}
} else {
- // No flexibility (all rigid) → stretch proportionally to min widths
- if ( totalMin > 0.001f ) {
- Float scale = tableUsedWidth / totalMin;
- for ( size_t i = 0; i < maxCols; ++i )
- mColWidths[i] = mColMinWidths[i] * scale;
- } else {
- Float w = tableUsedWidth / static_cast( maxCols );
- for ( size_t i = 0; i < maxCols; ++i )
- mColWidths[i] = w;
+ // Fallback if no flex exists
+ Float scale = totalMin > 0.001f ? ( tableUsedWidth / totalMin ) : 0.f;
+ for ( size_t i = 0; i < maxCols; ++i )
+ mColWidths[i] = mColMinWidths[i] * scale;
+ }
+
+ } else {
+ // 3. Abundant space → table is wider than all max widths combined.
+ // Give everyone their max width, then distribute the leftover space.
+ Float leftOver = tableUsedWidth - totalMax;
+
+ Float totalMaxUnspecified = 0.f;
+ size_t unspecifiedCount = 0;
+
+ for ( size_t i = 0; i < maxCols; ++i ) {
+ if ( mColSpecifiedWidths[i] <= 0.f ) {
+ totalMaxUnspecified += mColMaxWidths[i];
+ unspecifiedCount++;
}
}
+
+ if ( unspecifiedCount > 0 ) {
+ // Distribute leftover space proportionally to max-widths for a balanced look
+ if ( totalMaxUnspecified > 0.001f ) {
+ for ( size_t i = 0; i < maxCols; ++i ) {
+ if ( mColSpecifiedWidths[i] <= 0.f ) {
+ Float scale = mColMaxWidths[i] / totalMaxUnspecified;
+ mColWidths[i] = mColMaxWidths[i] + ( leftOver * scale );
+ } else {
+ mColWidths[i] = mColMaxWidths[i]; // Rigid explicit column stays rigid
+ }
+ }
+ } else {
+ // Fallback to strict even split if max widths are 0
+ Float share = leftOver / static_cast( unspecifiedCount );
+ for ( size_t i = 0; i < maxCols; ++i ) {
+ if ( mColSpecifiedWidths[i] <= 0.f ) {
+ mColWidths[i] = mColMaxWidths[i] + share;
+ } else {
+ mColWidths[i] = mColMaxWidths[i];
+ }
+ }
+ }
+ } else {
+ // Absolute fallback: All columns explicitly specified, but space remains. Scale up.
+ Float scale = totalMax > 0.001f ? ( tableUsedWidth / totalMax ) : 0.f;
+ for ( size_t i = 0; i < maxCols; ++i )
+ mColWidths[i] = mColMaxWidths[i] * scale;
+ }
}
// Safety fallback (should never trigger now)
diff --git a/src/tools/ecode/applayout.xml.hpp b/src/tools/ecode/applayout.xml.hpp
index 7b6964c74..b8d9b4718 100644
--- a/src/tools/ecode/applayout.xml.hpp
+++ b/src/tools/ecode/applayout.xml.hpp
@@ -531,6 +531,7 @@ Anchor.error:hover {
border-top-color: var(--button-border);
padding: 4dp 16dp 4dp 16dp;
border-top-left-radius: 12dp;
+ border-width: 1dp;
margin-bottom: 16dp;
margin-right: 2dp;
font-style: shadow;
diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp
index 1a7113743..00e73d12d 100644
--- a/src/tools/ecode/ecode.cpp
+++ b/src/tools/ecode/ecode.cpp
@@ -1423,6 +1423,19 @@ std::string App::getCurrentWorkingDir() const {
return "";
}
+std::string App::getCurrentFileDir() const {
+ if ( mSplitter && mSplitter->curEditorIsNotNull() && mSplitter->curEditorExists() &&
+ mSplitter->getCurEditor()->hasDocument() &&
+ mSplitter->getCurEditor()->getDocument().hasFilepath() ) {
+ return mSplitter->getCurEditor()->getDocument().getFileInfo().getDirectoryPath();
+ }
+
+ if ( !mCurrentProject.empty() && mCurrentProject != mPlaygroundPath )
+ return mCurrentProject;
+
+ return "";
+}
+
std::vector>
App::makeAutoClosePairs( const std::string& strPairs ) {
auto curPairs = String::split( strPairs, ',' );
diff --git a/src/tools/ecode/ecode.hpp b/src/tools/ecode/ecode.hpp
index d841ee29f..471216e6c 100644
--- a/src/tools/ecode/ecode.hpp
+++ b/src/tools/ecode/ecode.hpp
@@ -162,6 +162,8 @@ class App : public UICodeEditorSplitter::Client, public PluginContextProvider {
std::string getCurrentWorkingDir() const;
+ std::string getCurrentFileDir() const;
+
Drawable* findIcon( const std::string& name );
Drawable* findIcon( const std::string& name, const size_t iconSize );
diff --git a/src/tools/ecode/plugins/plugincontextprovider.hpp b/src/tools/ecode/plugins/plugincontextprovider.hpp
index 9b54b5c95..3f63463eb 100644
--- a/src/tools/ecode/plugins/plugincontextprovider.hpp
+++ b/src/tools/ecode/plugins/plugincontextprovider.hpp
@@ -125,6 +125,8 @@ class PluginContextProvider {
virtual std::string getCurrentWorkingDir() const = 0;
+ virtual std::string getCurrentFileDir() const = 0;
+
virtual void focusOrLoadFile( const std::string& path, const TextRange& range = {},
bool searchInSameContext = false ) = 0;
diff --git a/src/tools/ecode/terminalmanager.cpp b/src/tools/ecode/terminalmanager.cpp
index 54be52774..9baa26c21 100644
--- a/src/tools/ecode/terminalmanager.cpp
+++ b/src/tools/ecode/terminalmanager.cpp
@@ -265,10 +265,11 @@ void TerminalManager::configureTerminalScrollback() {
void TerminalManager::configureTerminalWorkingDir() {
static const auto layout( R"xml(
-
+
-
+
@@ -278,10 +279,10 @@ void TerminalManager::configureTerminalWorkingDir() {
-
+
)xml" );
UIWindow* window = mApp->getUISceneNode()->loadLayoutFromString( layout )->asType();
- UIComboBox* workingDirCombo = window->find( "working_dir_combo" );
+ UIDropDownList* workingDirCombo = window->find( "working_dir_combo" );
UIWidget* otherDirContainer = window->find( "other_dir_container" );
UITextInput* otherDirInput = window->find( "other_dir_input" );
UIPushButton* otherDirBrowse = window->find( "other_dir_browse" );
@@ -292,8 +293,7 @@ void TerminalManager::configureTerminalWorkingDir() {
mApp->i18n( "project_root_directory", "Project Root Directory" ),
mApp->i18n( "current_file_directory", "Current File Directory" ),
mApp->i18n( "user_home_directory", "User Home" ),
- mApp->i18n( "other_directory", "Other" )
- };
+ mApp->i18n( "other_directory", "Other" ) };
workingDirCombo->getListBox()->addListBoxItems( options );
workingDirCombo->getListBox()->setSelected(
@@ -306,14 +306,13 @@ void TerminalManager::configureTerminalWorkingDir() {
updateOtherVisible( mApp->getConfig().term.workingDir );
- workingDirCombo->on( Event::OnItemSelected, [updateOtherVisible, workingDirCombo]( auto ) {
+ workingDirCombo->on( Event::OnValueChange, [updateOtherVisible, workingDirCombo]( auto ) {
updateOtherVisible( static_cast(
workingDirCombo->getListBox()->getItemSelectedIndex() ) );
} );
otherDirBrowse->onClick( [this, otherDirInput]( auto ) {
- UIFileDialog* dialog = mApp->openFileDialog();
- dialog->setWindowFlags( UI_WIN_DEFAULT_FLAGS | UI_WIN_MODAL );
+ UIFileDialog* dialog = mApp->openFileDialog( false );
dialog->setTitle( mApp->i18n( "select_working_directory", "Select Working Directory" ) );
dialog->addFilePattern( "*", true );
dialog->setAllowFolderSelect( true );
@@ -330,7 +329,6 @@ void TerminalManager::configureTerminalWorkingDir() {
window->closeWindow();
} );
-
cancel->onClick( [window]( auto ) { window->closeWindow(); } );
window->on( Event::KeyDown, [window]( const Event* event ) {
@@ -349,7 +347,7 @@ std::string TerminalManager::getSelectedWorkingDir() const {
return !mApp->getCurrentProject().empty() ? mApp->getCurrentProject()
: mApp->getCurrentWorkingDir();
case TerminalWorkingDir::CurrentFileDir:
- return mApp->getCurrentWorkingDir();
+ return mApp->getCurrentFileDir();
case TerminalWorkingDir::UserHome:
return Sys::getUserDirectory();
case TerminalWorkingDir::Other: