diff --git a/include/eepp/ui/abstract/uiabstracttableview.hpp b/include/eepp/ui/abstract/uiabstracttableview.hpp
index 94380c4a7..ce2c52e58 100644
--- a/include/eepp/ui/abstract/uiabstracttableview.hpp
+++ b/include/eepp/ui/abstract/uiabstracttableview.hpp
@@ -183,7 +183,7 @@ class EE_API UIAbstractTableView : public UIAbstractView {
 	virtual UITableRow* updateRow( const int& rowIndex, const ModelIndex& index,
 								   const Float& yOffset );
 
-	virtual UIWidget* updateCell( const int& rowIndex, const ModelIndex& index,
+	virtual UIWidget* updateCell( const Vector2<Int64>& posIndex, const ModelIndex& index,
 								  const size_t& indentLevel, const Float& yOffset );
 
 	virtual UIWidget* createCell( UIWidget* rowWidget, const ModelIndex& index );
diff --git a/include/eepp/ui/uitreeview.hpp b/include/eepp/ui/uitreeview.hpp
index bb98ec0b1..452d5aa6a 100644
--- a/include/eepp/ui/uitreeview.hpp
+++ b/include/eepp/ui/uitreeview.hpp
@@ -144,7 +144,7 @@ class EE_API UITreeView : public UIAbstractTableView {
 
 	virtual void onColumnSizeChange( const size_t& colIndex, bool fromUserInteraction = false );
 
-	virtual UIWidget* updateCell( const int& rowIndex, const ModelIndex& index,
+	virtual UIWidget* updateCell( const Vector2<Int64>& posIndex, const ModelIndex& index,
 								  const size_t& indentLevel, const Float& yOffset );
 
 	virtual UIWidget* createCell( UIWidget* rowWidget, const ModelIndex& index );
diff --git a/src/eepp/ui/abstract/uiabstracttableview.cpp b/src/eepp/ui/abstract/uiabstracttableview.cpp
index ad28a994d..8b162489a 100644
--- a/src/eepp/ui/abstract/uiabstracttableview.cpp
+++ b/src/eepp/ui/abstract/uiabstracttableview.cpp
@@ -577,15 +577,15 @@ UIWidget* UIAbstractTableView::setupCell( UITableCell* widget, UIWidget* rowWidg
 	return widget;
 }
 
-UIWidget* UIAbstractTableView::updateCell( const int& rowIndex, const ModelIndex& index,
+UIWidget* UIAbstractTableView::updateCell( const Vector2<Int64>& posIndex, const ModelIndex& index,
 										   const size_t&, const Float& yOffset ) {
-	if ( rowIndex >= (int)mWidgets.size() )
-		mWidgets.resize( rowIndex + 1 );
-	auto* widget = mWidgets[rowIndex][index.column()];
+	if ( posIndex.y >= (int)mWidgets.size() )
+		mWidgets.resize( posIndex.y + 1 );
+	auto* widget = mWidgets[posIndex.y][index.column()];
 	if ( !widget ) {
-		UIWidget* rowWidget = updateRow( rowIndex, index, yOffset );
+		UIWidget* rowWidget = updateRow( posIndex.y, index, yOffset );
 		widget = createCell( rowWidget, index );
-		mWidgets[rowIndex][index.column()] = widget;
+		mWidgets[posIndex.y][index.column()] = widget;
 		widget->reloadStyle( true, true, true );
 	}
 	const auto& colData = columnData( index.column() );
diff --git a/src/eepp/ui/uitableview.cpp b/src/eepp/ui/uitableview.cpp
index 22d575595..522917fe2 100644
--- a/src/eepp/ui/uitableview.cpp
+++ b/src/eepp/ui/uitableview.cpp
@@ -28,22 +28,37 @@ bool UITableView::isType( const Uint32& type ) const {
 
 void UITableView::drawChilds() {
 	int realIndex = 0;
+	int realColIndex = 0;
 	ConditionalLock l( getModel() != nullptr, getModel() ? &getModel()->resourceMutex() : nullptr );
 	size_t start = mScrollOffset.y / getRowHeight();
 	size_t end =
 		eemin<size_t>( (size_t)eeceil( ( mScrollOffset.y + mSize.getHeight() ) / getRowHeight() ),
 					   getItemCount() );
-	Float yOffset;
+	Float yOffset = 0;
+	Float xOffset;
 	for ( size_t i = start; i < end; i++ ) {
+		xOffset = 0;
 		yOffset = getHeaderHeight() + i * getRowHeight();
 		ModelIndex index( getModel()->index( i ) );
 		if ( yOffset - mScrollOffset.y > mSize.getHeight() )
 			break;
 		if ( yOffset - mScrollOffset.y + getRowHeight() < 0 )
 			continue;
+		realColIndex = 0;
 		for ( size_t colIndex = 0; colIndex < getModel()->columnCount(); colIndex++ ) {
-			updateCell( realIndex, getModel()->index( index.row(), colIndex, index.parent() ), 0,
-						yOffset );
+			if ( xOffset - mScrollOffset.x > mSize.getWidth() )
+				break;
+			if ( xOffset - mScrollOffset.x + columnData( colIndex ).width < 0 ) {
+				xOffset += columnData( colIndex ).width;
+				continue;
+			}
+			xOffset += columnData( colIndex ).width;
+			if ( columnData( colIndex ).visible ) {
+				updateCell( { realColIndex, realIndex },
+							getModel()->index( index.row(), colIndex, index.parent() ), 0,
+							yOffset );
+				realColIndex++;
+			}
 		}
 		updateRow( realIndex, index, yOffset )->nodeDraw();
 		realIndex++;
@@ -87,13 +102,6 @@ Node* UITableView::overFind( const Vector2f& point ) {
 					break;
 				if ( yOffset - mScrollOffset.y + getRowHeight() < 0 )
 					continue;
-				for ( size_t colIndex = 0; colIndex < getModel()->columnCount(); colIndex++ ) {
-					if ( columnData( colIndex ).visible ) {
-						updateCell( realIndex,
-									getModel()->index( index.row(), colIndex, index.parent() ), 0,
-									yOffset );
-					}
-				}
 				pOver = updateRow( realIndex, index, yOffset )->overFind( point );
 				if ( pOver )
 					break;
@@ -116,7 +124,7 @@ Float UITableView::getMaxColumnContentWidth( const size_t& colIndex, bool bestGu
 				 [this] { mUISceneNode->setIsLoading( false ); } );
 	Float yOffset = getHeaderHeight();
 	auto worstCaseFunc = [&]( const ModelIndex& index ) {
-		UIWidget* widget = updateCell( index.row(), index, 0, yOffset );
+		UIWidget* widget = updateCell( { index.column(), index.row() }, index, 0, yOffset );
 		if ( widget->isType( UI_TYPE_PUSHBUTTON ) ) {
 			Float w = widget->asType<UIPushButton>()->getContentSize().getWidth();
 			if ( w > lWidth )
diff --git a/src/eepp/ui/uitreeview.cpp b/src/eepp/ui/uitreeview.cpp
index a3feb9789..9895cbb38 100644
--- a/src/eepp/ui/uitreeview.cpp
+++ b/src/eepp/ui/uitreeview.cpp
@@ -215,15 +215,15 @@ UIWidget* UITreeView::createCell( UIWidget* rowWidget, const ModelIndex& index )
 	return setupCell( widget, rowWidget, index );
 }
 
-UIWidget* UITreeView::updateCell( const int& rowIndex, const ModelIndex& index,
+UIWidget* UITreeView::updateCell( const Vector2<Int64>& posIndex, const ModelIndex& index,
 								  const size_t& indentLevel, const Float& yOffset ) {
-	if ( rowIndex >= (int)mWidgets.size() )
-		mWidgets.resize( rowIndex + 1 );
-	auto* widget = mWidgets[rowIndex][index.column()];
+	if ( posIndex.y >= (int)mWidgets.size() )
+		mWidgets.resize( posIndex.y + 1 );
+	auto* widget = mWidgets[posIndex.y][index.column()];
 	if ( !widget ) {
-		UIWidget* rowWidget = updateRow( rowIndex, index, yOffset );
+		UIWidget* rowWidget = updateRow( posIndex.y, index, yOffset );
 		widget = createCell( rowWidget, index );
-		mWidgets[rowIndex][index.column()] = widget;
+		mWidgets[posIndex.y][index.column()] = widget;
 		widget->reloadStyle( true, true, true );
 	}
 	const auto& colData = columnData( index.column() );
@@ -347,28 +347,41 @@ Sizef UITreeView::getContentSize() const {
 
 void UITreeView::drawChilds() {
 	int realIndex = 0;
+	int realColIndex = 0;
 	Float rowHeight = getRowHeight();
 
-	traverseTree( [this, &realIndex, rowHeight]( const int&, const ModelIndex& index,
-												 const size_t& indentLevel, const Float& yOffset ) {
+	traverseTree( [this, &realIndex, &realColIndex, rowHeight]( const int&, const ModelIndex& index,
+																const size_t& indentLevel,
+																const Float& yOffset ) {
 		if ( yOffset - mScrollOffset.y > mSize.getHeight() )
 			return IterationDecision::Stop;
 		if ( yOffset - mScrollOffset.y + rowHeight < 0 )
 			return IterationDecision::Continue;
+		realColIndex = 0;
+		Float xOffset = 0;
 		for ( size_t colIndex = 0; colIndex < getModel()->columnCount(); colIndex++ ) {
+			if ( xOffset - mScrollOffset.x > mSize.getWidth() )
+				break;
+			if ( xOffset - mScrollOffset.x + columnData( colIndex ).width < 0 ) {
+				xOffset += columnData( colIndex ).width;
+				continue;
+			}
+			xOffset += columnData( colIndex ).width;
 			if ( columnData( colIndex ).visible ) {
 				if ( (Int64)colIndex != index.column() ) {
-					updateCell( realIndex,
+					updateCell( { realColIndex, realIndex },
 								getModel()->index( index.row(), colIndex, index.parent() ),
 								indentLevel, yOffset );
 				} else {
-					auto* cell = updateCell( realIndex, index, indentLevel, yOffset );
+					auto* cell =
+						updateCell( { realColIndex, realIndex }, index, indentLevel, yOffset );
 
 					if ( mFocusSelectionDirty && index == getSelection().first() ) {
 						cell->setFocus();
 						mFocusSelectionDirty = false;
 					}
 				}
+				realColIndex++;
 			}
 		}
 		updateRow( realIndex, index, yOffset )->nodeDraw();
@@ -511,8 +524,9 @@ Float UITreeView::getMaxColumnContentWidth( const size_t& colIndex, bool ) {
 				 [this] { mUISceneNode->setIsLoading( false ); } );
 	traverseTree( [&, colIndex]( const int&, const ModelIndex& index, const size_t& indentLevel,
 								 const Float& yOffset ) {
-		UIWidget* widget = updateCell(
-			0, getModel()->index( index.row(), colIndex, index.parent() ), indentLevel, yOffset );
+		UIWidget* widget = updateCell( { (Int64)colIndex, (Int64)0 },
+									   getModel()->index( index.row(), colIndex, index.parent() ),
+									   indentLevel, yOffset );
 		if ( widget->isType( UI_TYPE_PUSHBUTTON ) ) {
 			Float w = widget->asType<UIPushButton>()->getContentSize().getWidth();
 			if ( w > lWidth )
diff --git a/src/examples/7guis/cells/cells.cpp b/src/examples/7guis/cells/cells.cpp
index 7fb653e6b..9b7c4ef09 100644
--- a/src/examples/7guis/cells/cells.cpp
+++ b/src/examples/7guis/cells/cells.cpp
@@ -4,6 +4,8 @@
 // Referece https://eugenkiss.github.io/7guis/tasks/#cells
 // Row header pending
 EE_MAIN_FUNC int main( int, char** ) {
+	Log::instance()->setLiveWrite( true );
+	Log::instance()->setLogToStdOut( true );
 	UIApplication app( { 1024, 768, "eepp - 7GUIs - Cells" } );
 	UIWidget* rlay = app.getUI()->loadLayoutFromString( R"xml(
 	<style>
@@ -17,6 +19,11 @@ EE_MAIN_FUNC int main( int, char** ) {
 	)xml" );
 	auto table = rlay->find<UITableView>( "sheet" );
 	auto model = std::make_shared<Spreadsheet>();
+	for ( size_t x = 0; x < model->columnCount(); x++ ) {
+		for ( size_t y = 0; y < model->rowCount(); y++ ) {
+			model->setData( model->index( y, x ), Variant( String::format( "%zu - %zu", x, y ) ) );
+		}
+	}
 	table->setModel( model );
 	table->setColumnsWidth( PixelDensity::dpToPx( 80 ) );
 	table->setSelectionType( UITableView::SelectionType::Cell );
@@ -29,5 +36,9 @@ EE_MAIN_FUNC int main( int, char** ) {
 		ret->setPullDataFrom( ModelRole::Custom );
 		return ret;
 	};
+	app.getUI()->on( Event::KeyDown, [&app]( const Event* event ) {
+		if ( event->asKeyEvent()->getKeyCode() == KEY_F11 )
+			UIWidgetInspector::create( app.getUI() );
+	} );
 	return app.run();
 }
diff --git a/src/examples/7guis/cells/parser.cpp b/src/examples/7guis/cells/parser.cpp
index 17d3e934f..ceec75ffc 100644
--- a/src/examples/7guis/cells/parser.cpp
+++ b/src/examples/7guis/cells/parser.cpp
@@ -119,7 +119,9 @@ std::shared_ptr<Formula> FormulaParser::formula() {
 			nextToken();
 			double val = 0;
 			String::fromString( val, n );
-			return std::make_shared<Number>( val );
+			if ( lookahead.token == TokenType::EPSILON )
+				return std::make_shared<Number>( val );
+			break;
 		}
 		case TokenType::EQUALS:
 			nextToken();
@@ -129,6 +131,7 @@ std::shared_ptr<Formula> FormulaParser::formula() {
 		default:
 			return std::make_shared<Textual>( formulaString );
 	}
+	return nullptr;
 }
 
 std::shared_ptr<Formula> FormulaParser::parseFormula( std::string _formulaString ) {
