diff --git a/include/eepp/ui/uinode.hpp b/include/eepp/ui/uinode.hpp index 06e2cb263..b6634d81d 100644 --- a/include/eepp/ui/uinode.hpp +++ b/include/eepp/ui/uinode.hpp @@ -325,7 +325,7 @@ class EE_API UINode : public Node { void writeFlag( const Uint32& Flag, const Uint32& Val ); Rectf makePadding( bool PadLeft = true, bool PadRight = true, bool PadTop = true, - bool PadBottom = true, bool SkipFlags = false ); + bool PadBottom = true, bool SkipFlags = false ) const; Sizef getSkinSize( UISkin* Skin, const Uint32& State = UIState::StateFlagNormal ) const; diff --git a/include/eepp/ui/uipushbutton.hpp b/include/eepp/ui/uipushbutton.hpp index 21ece7e0f..7bc7ad31f 100644 --- a/include/eepp/ui/uipushbutton.hpp +++ b/include/eepp/ui/uipushbutton.hpp @@ -56,7 +56,7 @@ class EE_API UIPushButton : public UIWidget { UIWidget* getFirstInnerItem() const; - virtual void updateLayout(); + virtual Sizef updateLayout(); protected: UIImage* mIcon; @@ -66,6 +66,8 @@ class EE_API UIPushButton : public UIWidget { explicit UIPushButton( const std::string& tag ); + virtual Rectf calculatePadding() const; + virtual void onSizeChange(); virtual void onAlphaChange(); @@ -85,6 +87,8 @@ class EE_API UIPushButton : public UIWidget { virtual Uint32 onKeyUp( const KeyEvent& Event ); Vector2f packLayout( const std::vector& widgets, const Rectf& padding ); + + Vector2f calcLayoutSize( const std::vector& widgets, const Rectf& padding ) const; }; }} // namespace EE::UI diff --git a/include/eepp/ui/uiscrollablewidget.hpp b/include/eepp/ui/uiscrollablewidget.hpp index 84adf61cd..21f15474f 100644 --- a/include/eepp/ui/uiscrollablewidget.hpp +++ b/include/eepp/ui/uiscrollablewidget.hpp @@ -49,7 +49,7 @@ class EE_API UIScrollableWidget : public UIWidget { Sizef getVisibleArea() const; - Rectf getVisibleRect() const; + virtual Rectf getVisibleRect() const; protected: ScrollViewType mViewType; diff --git a/src/eepp/ui/uinode.cpp b/src/eepp/ui/uinode.cpp index e0b6bd4d2..4ab9efa02 100644 --- a/src/eepp/ui/uinode.cpp +++ b/src/eepp/ui/uinode.cpp @@ -345,7 +345,7 @@ void UINode::updateDebugData() { text += String::format( "X: %.2fpx (%.2fdp) Y: %.2fpx (%.2fdp)\nW: %.2fpx (%.2fdp) H: %.2fpx (%.2fdp)", - mPosition.x, mDpPos.x, mPosition.y, mDpPos.y, mSize.x, mDpSize.y, mSize.y, mDpSize.y ); + mPosition.x, mDpPos.x, mPosition.y, mDpPos.y, mSize.x, mDpSize.x, mSize.y, mDpSize.y ); if ( widget->getPadding() != Rectf( 0, 0, 0, 0 ) ) { Rectf p( widget->getPadding() ); @@ -958,7 +958,7 @@ void UINode::applyDefaultTheme() { } Rectf UINode::makePadding( bool PadLeft, bool PadRight, bool PadTop, bool PadBottom, - bool SkipFlags ) { + bool SkipFlags ) const { Rectf tPadding( 0, 0, 0, 0 ); if ( mFlags & UI_AUTO_PADDING || SkipFlags ) { diff --git a/src/eepp/ui/uipushbutton.cpp b/src/eepp/ui/uipushbutton.cpp index 60930479d..fb6c2e56c 100644 --- a/src/eepp/ui/uipushbutton.cpp +++ b/src/eepp/ui/uipushbutton.cpp @@ -50,6 +50,24 @@ UIPushButton::UIPushButton( const std::string& tag ) : applyDefaultTheme(); } +Rectf UIPushButton::calculatePadding() const { + Rectf autoPadding; + if ( mFlags & UI_AUTO_PADDING ) { + autoPadding = makePadding( true, true, true, true ); + if ( autoPadding != Rectf() ) + autoPadding = PixelDensity::dpToPx( autoPadding ); + } + if ( mPaddingPx.Top > autoPadding.Top ) + autoPadding.Top = mPaddingPx.Top; + if ( mPaddingPx.Bottom > autoPadding.Bottom ) + autoPadding.Bottom = mPaddingPx.Bottom; + if ( mPaddingPx.Left > autoPadding.Left ) + autoPadding.Left = mPaddingPx.Left; + if ( mPaddingPx.Right > autoPadding.Right ) + autoPadding.Right = mPaddingPx.Right; + return autoPadding; +} + UIPushButton::UIPushButton() : UIPushButton( "pushbutton" ) {} UIPushButton::~UIPushButton() {} @@ -76,18 +94,34 @@ void UIPushButton::onAutoSize() { } if ( ( mFlags & UI_AUTO_SIZE ) || mWidthPolicy == SizePolicy::WrapContent ) { - Int32 minSize = - getContentSize().getWidth() + - ( NULL != getSkin() ? PixelDensity::dpToPxI( getSkin()->getBorderSize().Left + - getSkin()->getBorderSize().Right ) - : 0 ); - - if ( minSize > mSize.getWidth() ) { - setInternalPixelsWidth( getContentSize().getWidth() ); - } + Float minSize = getContentSize().getWidth(); + if ( minSize > mSize.getWidth() ) + setInternalPixelsWidth( minSize ); } } +Vector2f UIPushButton::calcLayoutSize( const std::vector& widgets, + const Rectf& padding ) const { + Vector2f totSize{padding.Left, padding.Top + padding.Bottom}; + UIWidget* widget; + for ( size_t i = 0; i < widgets.size(); i++ ) { + if ( !widgets[i] || !widgets[i]->isVisible() ) + continue; + widget = widgets[i]; + if ( widget->getPixelsSize().getWidth() > 0 ) { + totSize.x += widget->getLayoutPixelsMargin().Left + widget->getPixelsSize().getWidth(); + if ( ( i + 1 < widgets.size() && widgets[i + 1] && widgets[i + 1]->isVisible() ) || + ( i + 2 < widgets.size() && widgets[i + 2] && widgets[i + 2]->isVisible() ) ) { + totSize.x += widget->getLayoutPixelsMargin().Right; + } + } + totSize.y = eemax( totSize.y, padding.Top + padding.Bottom + + widget->getPixelsSize().getHeight() ); + } + totSize.x += padding.Right; + return totSize; +} + Vector2f UIPushButton::packLayout( const std::vector& widgets, const Rectf& padding ) { std::vector pos( widgets.size() ); Vector2f totSize{padding.Left, padding.Top + padding.Bottom}; @@ -165,33 +199,21 @@ UIWidget* UIPushButton::getFirstInnerItem() const { return mChild->isWidget() ? mChild->asType() : nullptr; } -void UIPushButton::updateLayout() { - Rectf autoPadding; - if ( mFlags & UI_AUTO_PADDING ) { - autoPadding = makePadding( true, true, true, true ); - if ( autoPadding != Rectf() ) - autoPadding = PixelDensity::dpToPx( autoPadding ); - } - if ( mPaddingPx.Top > autoPadding.Top ) - autoPadding.Top = mPaddingPx.Top; - if ( mPaddingPx.Bottom > autoPadding.Bottom ) - autoPadding.Bottom = mPaddingPx.Bottom; - if ( mPaddingPx.Left > autoPadding.Left ) - autoPadding.Left = mPaddingPx.Left; - if ( mPaddingPx.Right > autoPadding.Right ) - autoPadding.Right = mPaddingPx.Right; - +Sizef UIPushButton::updateLayout() { + Sizef size; + Rectf autoPadding = calculatePadding(); switch ( mInnerWidgetOrientation ) { case InnerWidgetOrientation::Left: - packLayout( {getExtraInnerWidget(), mIcon, mTextBox}, autoPadding ); + size = packLayout( {getExtraInnerWidget(), mIcon, mTextBox}, autoPadding ); break; case InnerWidgetOrientation::Center: - packLayout( {mIcon, getExtraInnerWidget(), mTextBox}, autoPadding ); + size = packLayout( {mIcon, getExtraInnerWidget(), mTextBox}, autoPadding ); break; case InnerWidgetOrientation::Right: - packLayout( {mIcon, mTextBox, getExtraInnerWidget()}, autoPadding ); + size = packLayout( {mIcon, mTextBox, getExtraInnerWidget()}, autoPadding ); break; } + return size; } void UIPushButton::onPaddingChange() { @@ -321,28 +343,23 @@ void UIPushButton::setTextAlign( const Uint32& align ) { } Sizef UIPushButton::getContentSize() const { - Float sH = getSkinSize().getHeight(); - Float sHS = getSkinSize( UIState::StateFlagSelected ).getHeight(); - Float tH = mTextBox->getPixelsSize().getHeight(); - Float eH = - NULL != getExtraInnerWidget() ? getExtraInnerWidget()->getPixelsSize().getHeight() : 0; - Float minHeight = eeceil( eemax( eemax( PixelDensity::dpToPx( eemax( sH, sHS ) ), tH ), eH ) ); - Int32 txtW = mTextBox->getPixelsSize().getWidth(); - Int32 iconSize = mIcon->getPixelsSize().getWidth() > 0 - ? mIcon->getPixelsSize().getWidth() + - PixelDensity::dpToPxI( mIcon->getLayoutMargin().Left + - mIcon->getLayoutMargin().Right ) - : 0; - UIWidget* eWidget = getExtraInnerWidget(); - Int32 eWidgetSize = NULL != eWidget ? PixelDensity::dpToPxI( eWidget->getSize().getWidth() + - eWidget->getLayoutMargin().Left + - eWidget->getLayoutMargin().Right ) - : 0; - Int32 minWidth = txtW + iconSize + eWidgetSize + mPaddingPx.Left + mPaddingPx.Right + - ( NULL != getSkin() ? PixelDensity::dpToPxI( getSkin()->getBorderSize().Left + - getSkin()->getBorderSize().Right ) - : 0 ); - return Sizef( minWidth, minHeight ); + Sizef size; + Rectf autoPadding = calculatePadding(); + switch ( mInnerWidgetOrientation ) { + case InnerWidgetOrientation::Left: + size = calcLayoutSize( {getExtraInnerWidget(), mIcon, mTextBox}, autoPadding ); + break; + case InnerWidgetOrientation::Center: + size = calcLayoutSize( {mIcon, getExtraInnerWidget(), mTextBox}, autoPadding ); + break; + case InnerWidgetOrientation::Right: + size = calcLayoutSize( {mIcon, mTextBox, getExtraInnerWidget()}, autoPadding ); + break; + } + if ( getSkin() ) + size.x += PixelDensity::dpToPxI( getSkin()->getBorderSize().Left + + getSkin()->getBorderSize().Right ); + return size; } const InnerWidgetOrientation& UIPushButton::getInnerWidgetOrientation() const { diff --git a/src/eepp/ui/uiscrollablewidget.cpp b/src/eepp/ui/uiscrollablewidget.cpp index df69126d6..35333becb 100644 --- a/src/eepp/ui/uiscrollablewidget.cpp +++ b/src/eepp/ui/uiscrollablewidget.cpp @@ -151,8 +151,8 @@ void UIScrollableWidget::onContentSizeChange() { mPaddingPx.Right, mPaddingPx.Top ); mHScroll->setPixelsPosition( mPaddingPx.Left, getPixelsSize().getHeight() - - mHScroll->getPixelsSize().getHeight() - - mPaddingPx.Bottom ); + mHScroll->getPixelsSize().getHeight() - + mPaddingPx.Bottom ); mVScroll->setPixelsSize( mVScroll->getPixelsSize().getWidth(), getPixelsSize().getHeight() - mPaddingPx.Top - mPaddingPx.Bottom ); diff --git a/src/eepp/ui/uitableview.cpp b/src/eepp/ui/uitableview.cpp index e2619cf81..dee6bc7cc 100644 --- a/src/eepp/ui/uitableview.cpp +++ b/src/eepp/ui/uitableview.cpp @@ -167,11 +167,56 @@ Uint32 UITableView::onKeyDown( const KeyEvent& event ) { return 1; } case KEY_UP: { - moveSelection( -1 ); + if ( !getModel() ) + return 0; + auto& model = *this->getModel(); + ModelIndex foundIndex; + if ( !getSelection().isEmpty() ) { + auto oldIndex = getSelection().first(); + if ( oldIndex.row() == 0 ) { + getSelection().set( getModel()->index( 0, 0 ) ); + scrollToTop(); + return 1; + } + foundIndex = model.index( oldIndex.row() - 1, oldIndex.column() ); + } else { + foundIndex = model.index( 0, 0 ); + } + if ( model.isValid( foundIndex ) ) { + Float curY = getHeaderHeight() + getRowHeight() * foundIndex.row(); + getSelection().set( foundIndex ); + if ( curY < mScrollOffset.y + getHeaderHeight() + getRowHeight() || + curY > mScrollOffset.y + getPixelsSize().getHeight() - mPaddingPx.Top - + mPaddingPx.Bottom - getRowHeight() ) { + curY -= getHeaderHeight(); + mVScroll->setValue( curY / getScrollableArea().getHeight() ); + } + } return 1; } case KEY_DOWN: { - moveSelection( 1 ); + if ( !getModel() ) + return 0; + auto& model = *this->getModel(); + ModelIndex foundIndex; + if ( !getSelection().isEmpty() ) { + auto oldIndex = getSelection().first(); + foundIndex = model.index( oldIndex.row() + 1, oldIndex.column() ); + } else { + foundIndex = model.index( 0, 0 ); + } + if ( model.isValid( foundIndex ) ) { + Float curY = getHeaderHeight() + getRowHeight() * foundIndex.row(); + getSelection().set( foundIndex ); + if ( curY < mScrollOffset.y || + curY > mScrollOffset.y + getPixelsSize().getHeight() - mPaddingPx.Top - + mPaddingPx.Bottom - getRowHeight() ) { + curY -= + eefloor( getVisibleArea().getHeight() / getRowHeight() ) * getRowHeight() - + getRowHeight(); + mVScroll->setValue( curY / getScrollableArea().getHeight() ); + } + } return 1; } case KEY_END: { diff --git a/src/eepp/ui/uitreeview.cpp b/src/eepp/ui/uitreeview.cpp index 75691c9e4..9ad483bfd 100644 --- a/src/eepp/ui/uitreeview.cpp +++ b/src/eepp/ui/uitreeview.cpp @@ -118,7 +118,8 @@ class UITreeViewCell : public UITableCell { UIImage* getImage() const { return mImage; } - void updateLayout() { + Rectf calculatePadding() const { + Sizef size; Rectf autoPadding; if ( mFlags & UI_AUTO_PADDING ) { autoPadding = makePadding( true, true, true, true ); @@ -134,17 +135,7 @@ class UITreeViewCell : public UITableCell { if ( mPaddingPx.Right > autoPadding.Right ) autoPadding.Right = mPaddingPx.Right; autoPadding.Left += mIndent; - switch ( mInnerWidgetOrientation ) { - case InnerWidgetOrientation::Left: - packLayout( {getExtraInnerWidget(), mIcon, mTextBox}, autoPadding ); - break; - case InnerWidgetOrientation::Center: - packLayout( {mIcon, getExtraInnerWidget(), mTextBox}, autoPadding ); - break; - case InnerWidgetOrientation::Right: - packLayout( {mIcon, mTextBox, getExtraInnerWidget()}, autoPadding ); - break; - } + return autoPadding; } void setIndentation( const Float& indent ) { diff --git a/src/tools/codeeditor/autocompletemodule.cpp b/src/tools/codeeditor/autocompletemodule.cpp index 36314d431..22d2cf8a3 100644 --- a/src/tools/codeeditor/autocompletemodule.cpp +++ b/src/tools/codeeditor/autocompletemodule.cpp @@ -388,13 +388,11 @@ void AutoCompleteModule::setSymbolPattern( const std::string& symbolPattern ) { mSymbolPattern = symbolPattern; } -bool AutoCompleteModule::isDirty() const -{ +bool AutoCompleteModule::isDirty() const { return mDirty; } -void AutoCompleteModule::setDirty(bool dirty) -{ +void AutoCompleteModule::setDirty( bool dirty ) { mDirty = dirty; } @@ -418,10 +416,11 @@ AutoCompleteModule::SymbolsList AutoCompleteModule::getDocumentSymbols( TextDocu for ( Int64 i = 0; i < lc; i++ ) { const auto& string = doc->line( i ).getText().toUtf8(); for ( auto& match : pattern.gmatch( string ) ) { + std::string matchStr( match[0] ); // Ignore the symbol if is actually the current symbol being written - if ( end.line() == i && current == match[0] ) + if ( matchStr.size() < 3 || ( end.line() == i && current == matchStr ) ) continue; - symbols.insert( match[0] ); + symbols.insert( std::move( matchStr ) ); } } return symbols; diff --git a/src/tools/codeeditor/codeeditor.cpp b/src/tools/codeeditor/codeeditor.cpp index 917607469..086590a66 100644 --- a/src/tools/codeeditor/codeeditor.cpp +++ b/src/tools/codeeditor/codeeditor.cpp @@ -1631,6 +1631,9 @@ void App::loadFolder( const std::string& path ) { mRecentFolders.resize( 10 ); updateRecentFolders(); + + if ( mEditorSplitter->getCurEditor() ) + mEditorSplitter->getCurEditor()->setFocus(); } void App::init( const std::string& file, const Float& pidelDensity ) {