UITreeView improvements.

Added Drawable::getPixelsSize.
Improved UIPushButton.
This commit is contained in:
Martín Lucas Golini
2020-07-23 00:48:16 -03:00
parent ad4e4b5367
commit 54d520dba6
57 changed files with 540 additions and 256 deletions

View File

@@ -110,7 +110,9 @@ SelectButton:selectedpressed {
}
PushButton::icon,
SelectButton::icon {
SelectButton::icon,
TreeView::cell::icon,
TreeView::cell::expander {
margin-right: 4dp;
}
@@ -770,6 +772,12 @@ table::row:selected {
background-color: var(--primary);
}
table::cell,
TreeView::cell {
padding-left: 6dp;
padding-right: 6dp;
}
TreeView {
background-color: var(--list-back);
}

View File

@@ -20,6 +20,8 @@ class EE_API ArcDrawable : public PrimitiveDrawable {
virtual Sizef getSize();
virtual Sizef getPixelsSize();
virtual void draw();
virtual void draw( const Vector2f& position );

View File

@@ -14,6 +14,8 @@ class EE_API ConvexShapeDrawable : public PrimitiveDrawable {
virtual Sizef getSize();
virtual Sizef getPixelsSize();
virtual void draw();
virtual void draw( const Vector2f& position );

View File

@@ -38,6 +38,8 @@ class EE_API Drawable {
virtual Sizef getSize() = 0;
virtual Sizef getPixelsSize() = 0;
virtual void draw() = 0;
virtual void draw( const Vector2f& position ) = 0;

View File

@@ -16,6 +16,8 @@ class EE_API DrawableGroup : public Drawable {
virtual Sizef getSize();
virtual Sizef getPixelsSize();
virtual void draw();
virtual void draw( const Vector2f& position );

View File

@@ -36,12 +36,12 @@ class EE_API GlyphDrawable : public DrawableResource {
/** @return This is the same as Destination Size but with the values rounded as integers. */
Sizef getSize();
Sizef getPixelsSize();
const Float& getPixelDensity() const;
void setPixelDensity( const Float& pixelDensity );
Sizef getPxSize() const;
const Vector2f& getGlyphOffset() const;
void setGlyphOffset( const Vector2f& glyphOffset );

View File

@@ -38,6 +38,8 @@ class EE_API NinePatch : public DrawableResource {
virtual Sizef getSize();
virtual Sizef getPixelsSize();
virtual void draw();
virtual void draw( const Vector2f& position );

View File

@@ -18,6 +18,8 @@ class EE_API RectangleDrawable : public PrimitiveDrawable {
virtual Sizef getSize();
virtual Sizef getPixelsSize();
virtual void draw();
virtual void draw( const Vector2f& position );

View File

@@ -22,7 +22,7 @@ class EE_API Sprite : public Drawable {
SPRITE_EVENT_LAST_FRAME,
SPRITE_EVENT_FIRST_FRAME,
SPRITE_EVENT_END_ANIM_TO,
SPRITE_EVENT_USER // User Events
SPRITE_EVENT_USER // User vents
};
static Sprite* New();
@@ -119,6 +119,8 @@ class EE_API Sprite : public Drawable {
/** @return The current Frame Size */
Sizef getSize();
Sizef getPixelsSize();
/** Set the sprite animation speed ( AnimSpeed equals to Animation Frames per Second ) */
void setAnimationSpeed( const Float& animSpeed );

View File

@@ -16,8 +16,12 @@ class EE_API StateListDrawable : public StatefulDrawable {
virtual Sizef getSize();
virtual Sizef getPixelsSize();
virtual Sizef getSize( const Uint32& state );
virtual Sizef getPixelsSize( const Uint32& state );
virtual void draw();
virtual void draw( const Vector2f& position );

View File

@@ -273,7 +273,7 @@ class EE_API Texture : public DrawableResource, public Image, private NonCopyabl
Sizef getSize();
Sizef getPxSize();
Sizef getPixelsSize();
void draw();

View File

@@ -183,7 +183,7 @@ class EE_API TextureRegion : public DrawableResource {
Sizei getDpSize();
Sizef getPxSize();
Sizef getPixelsSize();
Sizef getOriDestSize() const;

View File

@@ -18,6 +18,8 @@ class EE_API TriangleDrawable : public PrimitiveDrawable {
virtual Sizef getSize();
virtual Sizef getPixelsSize();
virtual void draw();
virtual void draw( const Vector2f& position );

View File

@@ -49,11 +49,21 @@ class EE_API UIAbstractTableView : public UIAbstractView {
/** In pixels. */
void setRowHeight( const Float& rowHeight );
void columnResizeToContent( const size_t& colIndex );
/** In pixels. */
void setColumnWidth( const size_t& colIndex, const Float& width );
const Float& getColumnWidth( const size_t& colIndex ) const;
virtual Float getMaxColumnContentWidth( const size_t& colIndex );
bool getAutoExpandOnSingleColumn() const;
void setAutoExpandOnSingleColumn( bool autoExpandOnSingleColumn );
void columnResizeToContent( const size_t& colIndex );
Float getContentSpaceWidth() const;
protected:
friend class EE::UI::UITableHeaderColumn;
@@ -87,14 +97,13 @@ class EE_API UIAbstractTableView : public UIAbstractView {
virtual void updateColumnsWidth();
virtual void updateScroll();
void updateHeaderSize();
int visibleColumn();
UILinearLayout* mHeader;
Float mDragBorderDistance{8};
bool mAutoExpandOnSingleColumn{false};
};
}}} // namespace EE::UI::Abstract

View File

@@ -11,7 +11,7 @@ using namespace EE::UI::Models;
namespace EE { namespace UI { namespace Abstract {
enum class ModelEventType { Open };
enum class ModelEventType { Open, OpenTree, CloseTree };
class EE_API ModelEvent : public Event {
public:

View File

@@ -22,6 +22,8 @@ class EE_API UIBackgroundDrawable : public Drawable {
virtual Sizef getSize();
virtual Sizef getPixelsSize();
virtual void draw();
virtual void draw( const Vector2f& position );

View File

@@ -18,6 +18,8 @@ class EE_API UIBorderDrawable : public Drawable {
virtual Sizef getSize();
virtual Sizef getPixelsSize();
virtual void draw();
virtual void draw( const Vector2f& position );

View File

@@ -93,6 +93,7 @@ enum UINodeType {
UI_TYPE_ABSTRACTTABLEVIEW,
UI_TYPE_TREEVIEW,
UI_TYPE_SCROLLABLEWIDGET,
UI_TYPE_TREEVIEW_CELL,
UI_TYPE_USER = 10000
};

View File

@@ -23,6 +23,8 @@ class EE_API UIMenuItem : public UIPushButton {
UITextView* getShortcutView() const;
virtual UIWidget* getExtraInnerWidget() const;
protected:
UITextView* mShortcutView;
@@ -36,8 +38,6 @@ class EE_API UIMenuItem : public UIPushButton {
virtual Uint32 onMouseClick( const Vector2i& pos, const Uint32& flags );
virtual UIWidget* getExtraInnerWidget() const;
void createShortcutView();
};

View File

@@ -33,6 +33,8 @@ class EE_API UIMenuSubMenu : public UIMenuItem {
void setMouseOverTimeShowMenu( const Time& maxTime );
virtual UIWidget* getExtraInnerWidget() const;
protected:
UIMenu* mSubMenu;
UIWidget* mArrow;
@@ -51,8 +53,6 @@ class EE_API UIMenuSubMenu : public UIMenuItem {
virtual void onAlphaChange();
virtual UIWidget* getExtraInnerWidget() const;
void onSubMenuFocusLoss( const Event* Event );
void onHideByClick( const Event* Event );

View File

@@ -39,6 +39,8 @@ class EE_API UINodeDrawable : public Drawable {
virtual Sizef getSize();
virtual Sizef getPixelsSize();
virtual void setSize( const Sizef& size );
Drawable* getDrawable() const;
@@ -113,6 +115,8 @@ class EE_API UINodeDrawable : public Drawable {
virtual Sizef getSize();
virtual Sizef getPixelsSize();
virtual void setSize( const Sizef& size );
virtual void draw();

View File

@@ -7,6 +7,8 @@
namespace EE { namespace UI {
enum class InnerWidgetOrientation { Left, Right, Center };
class EE_API UIPushButton : public UIWidget {
public:
static UIPushButton* New();
@@ -46,10 +48,19 @@ class EE_API UIPushButton : public UIWidget {
virtual Sizef getContentSize() const;
const InnerWidgetOrientation& getInnerWidgetOrientation() const;
void setInnerWidgetOrientation( const InnerWidgetOrientation& innerWidgetOrientation );
virtual UIWidget* getExtraInnerWidget() const;
UIWidget* getFirstInnerItem() const;
protected:
UIImage* mIcon;
UITextView* mTextBox;
Sizei mIconMinSize;
InnerWidgetOrientation mInnerWidgetOrientation{InnerWidgetOrientation::Right};
explicit UIPushButton( const std::string& tag );
@@ -73,7 +84,7 @@ class EE_API UIPushButton : public UIWidget {
virtual Uint32 onKeyUp( const KeyEvent& Event );
virtual UIWidget* getExtraInnerWidget() const;
Vector2f packLayout( const std::vector<UIWidget*>& widgets, const Rectf& padding );
};
}} // namespace EE::UI

View File

@@ -16,8 +16,12 @@ class EE_API UISkin : public StateListDrawable {
virtual Sizef getSize( const Uint32& state );
virtual Sizef getPixelsSize( const Uint32& state );
virtual Sizef getSize();
virtual Sizef getPixelsSize();
virtual UISkin* clone();
virtual UISkin* clone( const std::string& NewName );

View File

@@ -36,13 +36,15 @@ class EE_API UITab : public UISelectButton {
UITabWidget* getTabWidget();
virtual UIWidget* getExtraInnerWidget() const;
protected:
friend class UITabWidget;
Node* mOwnedWidget;
String mText;
std::string mOwnedName;
UIWidget* mCloseButton;
mutable UIWidget* mCloseButton{nullptr};
Float mDragTotalDiff;
UITabWidget* mTabWidget;
@@ -62,8 +64,6 @@ class EE_API UITab : public UISelectButton {
virtual void onSizeChange();
virtual UIWidget* getExtraInnerWidget() const;
void setOwnedNode();
void updateTab();

View File

@@ -40,6 +40,12 @@ class EE_API UITreeView : public UIAbstractTableView {
void setContractedIcon( Drawable* contractIcon );
bool getExpandersAsIcons() const;
void setExpandersAsIcons( bool expandersAsIcons );
Float getMaxColumnContentWidth( const size_t& colIndex );
protected:
enum class IterationDecision {
Continue,
@@ -51,6 +57,7 @@ class EE_API UITreeView : public UIAbstractTableView {
Sizef mContentSize;
Drawable* mExpandIcon{nullptr};
Drawable* mContractIcon{nullptr};
bool mExpandersAsIcons{false};
UITreeView();
@@ -77,21 +84,21 @@ class EE_API UITreeView : public UIAbstractTableView {
virtual UITableRow* updateRow( const int& rowIndex, const ModelIndex& index,
const Float& yOffset );
virtual UIWidget* updateCell( const int& rowIndex, const ModelIndex& index, const size_t& col,
virtual UIWidget* updateCell( const int& rowIndex, const ModelIndex& index,
const size_t& indentLevel, const Float& yOffset );
virtual UIWidget* createCell( UIWidget* rowWidget, const ModelIndex& index, const size_t& col );
virtual void onScrollChange();
virtual void onColumnResizeToContent( const size_t& colIndex );
virtual void onModelSelectionChange();
virtual Uint32 onKeyDown( const KeyEvent& event );
virtual void onOpenModelIndex( const ModelIndex& index );
virtual void onOpenTreeModelIndex( const ModelIndex& index, bool open );
void updateContentSize();
};

View File

@@ -35,6 +35,10 @@ Sizef ArcDrawable::getSize() {
return Sizef( mRadius * 2, mRadius * 2 );
}
Sizef ArcDrawable::getPixelsSize() {
return Sizef( mRadius * 2, mRadius * 2 );
}
void ArcDrawable::draw() {
draw( mPosition );
}

View File

@@ -13,6 +13,10 @@ Sizef ConvexShapeDrawable::getSize() {
return mPolygon.getBounds().getSize();
}
Sizef ConvexShapeDrawable::getPixelsSize() {
return mPolygon.getBounds().getSize();
}
void ConvexShapeDrawable::draw() {
draw( mPosition, getSize() );
}

View File

@@ -64,6 +64,10 @@ Sizef DrawableGroup::getSize() {
return mSize;
}
Sizef DrawableGroup::getPixelsSize() {
return mSize;
}
void DrawableGroup::draw( const Vector2f& position, const Sizef& size ) {
if ( position != mPosition ) {
mPosition = position;

View File

@@ -668,7 +668,7 @@ Rect FontTrueType::findGlyphRect( Page& page, unsigned int width, unsigned int h
continue;
// Check if there's enough horizontal space left in the row
if ( width > page.texture->getPxSize().x - it->width )
if ( width > page.texture->getPixelsSize().x - it->width )
continue;
// Make sure that this new row is the best found so far
@@ -683,11 +683,11 @@ Rect FontTrueType::findGlyphRect( Page& page, unsigned int width, unsigned int h
// If we didn't find a matching row, create a new one (10% taller than the glyph)
if ( !row ) {
int rowHeight = height + height / 10;
while ( ( page.nextRow + rowHeight >= (Uint32)page.texture->getPxSize().y ) ||
( width >= (Uint32)page.texture->getPxSize().x ) ) {
while ( ( page.nextRow + rowHeight >= (Uint32)page.texture->getPixelsSize().y ) ||
( width >= (Uint32)page.texture->getPixelsSize().x ) ) {
// Not enough space: resize the texture if possible
unsigned int textureWidth = page.texture->getPxSize().x;
unsigned int textureHeight = page.texture->getPxSize().y;
unsigned int textureWidth = page.texture->getPixelsSize().x;
unsigned int textureHeight = page.texture->getPixelsSize().y;
if ( ( textureWidth * 2 <= Texture::getMaximumSize() ) &&
( textureHeight * 2 <= Texture::getMaximumSize() ) ) {
// Make the texture 2 times bigger

View File

@@ -57,6 +57,10 @@ Sizef GlyphDrawable::getSize() {
return Sizef( mSrcRect.Right / mPixelDensity, mSrcRect.Bottom / mPixelDensity );
}
Sizef GlyphDrawable::getPixelsSize() {
return Sizef( mSrcRect.Right, mSrcRect.Bottom );
}
const Float& GlyphDrawable::getPixelDensity() const {
return mPixelDensity;
}
@@ -65,10 +69,6 @@ void GlyphDrawable::setPixelDensity( const Float& pixelDensity ) {
mPixelDensity = pixelDensity;
}
Sizef GlyphDrawable::getPxSize() const {
return Sizef( mSrcRect.Right, mSrcRect.Bottom );
}
const Vector2f& GlyphDrawable::getGlyphOffset() const {
return mGlyphOffset;
}

View File

@@ -25,7 +25,7 @@ NinePatch::NinePatch( const Uint32& TexId, int left, int top, int right, int bot
Texture* tex = TextureFactory::instance()->getTexture( TexId );
if ( NULL != tex ) {
mSize = tex->getPxSize();
mSize = tex->getPixelsSize();
createFromTexture( TexId, left, top, right, bottom );
}
@@ -77,6 +77,10 @@ Sizef NinePatch::getSize() {
( Float )( ( Int32 )( mSize.getHeight() / mPixelDensity ) ) );
}
Sizef NinePatch::getPixelsSize() {
return mSize;
}
void NinePatch::draw() {
draw( mPosition );
}

View File

@@ -33,6 +33,10 @@ Sizef RectangleDrawable::getSize() {
return mSize;
}
Sizef RectangleDrawable::getPixelsSize() {
return mSize;
}
void RectangleDrawable::draw() {
draw( mPosition );
}

View File

@@ -27,8 +27,8 @@ void ScrollParallax::setTextureRegion( TextureRegion* textureRegion ) {
void ScrollParallax::setTextureRegion() {
if ( NULL != mTextureRegion ) {
mRect = mTextureRegion->getSrcRect();
mRealSize = Vector2f( (Float)mTextureRegion->getPxSize().getWidth(),
(Float)mTextureRegion->getPxSize().getHeight() );
mRealSize = Vector2f( (Float)mTextureRegion->getPixelsSize().getWidth(),
(Float)mTextureRegion->getPixelsSize().getHeight() );
mTiles.x = ( (Int32)mSize.getWidth() / (Int32)mRealSize.getWidth() ) + 1;
mTiles.y = ( (Int32)mSize.getHeight() / (Int32)mRealSize.getHeight() ) + 1;

View File

@@ -690,6 +690,10 @@ Sizef Sprite::getSize() {
return mFrames[mCurrentFrame].Spr[mCurrentSubFrame]->getSize();
}
Sizef Sprite::getPixelsSize() {
return mFrames[mCurrentFrame].Spr[mCurrentSubFrame]->getPixelsSize();
}
void Sprite::setRepetitions( const int& Repeations ) {
mRepetitions = Repeations;
}

View File

@@ -40,6 +40,10 @@ Sizef StateListDrawable::getSize() {
return NULL != mCurrentDrawable ? mCurrentDrawable->getSize() : Sizef();
}
Sizef StateListDrawable::getPixelsSize() {
return mCurrentDrawable ? mCurrentDrawable->getPixelsSize() : Sizef();
}
Sizef StateListDrawable::getSize( const Uint32& state ) {
auto it = mDrawables.find( state );
@@ -50,6 +54,16 @@ Sizef StateListDrawable::getSize( const Uint32& state ) {
return Sizef();
}
Sizef StateListDrawable::getPixelsSize( const Uint32& state ) {
auto it = mDrawables.find( state );
if ( it != mDrawables.end() ) {
return it->second->getPixelsSize();
}
return Sizef();
}
void StateListDrawable::draw() {
draw( mPosition );
}

View File

@@ -929,7 +929,7 @@ Sizef Texture::getSize() {
return Sizef( PixelDensity::pxToDp( mImgWidth ), PixelDensity::pxToDp( mImgHeight ) );
}
Sizef Texture::getPxSize() {
Sizef Texture::getPixelsSize() {
return Sizef( mImgWidth, mImgHeight );
}

View File

@@ -160,8 +160,8 @@ void TextureFactory::bind( const Texture* texture, Texture::CoordinateType coord
GLfloat matrix[16] = {1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f,
0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f};
matrix[0] = 1.f / const_cast<Texture*>( texture )->getPxSize().x;
matrix[5] = 1.f / const_cast<Texture*>( texture )->getPxSize().y;
matrix[0] = 1.f / const_cast<Texture*>( texture )->getPixelsSize().x;
matrix[5] = 1.f / const_cast<Texture*>( texture )->getPixelsSize().y;
GLi->matrixMode( GL_TEXTURE );
GLi->loadMatrixf( matrix );

View File

@@ -387,7 +387,7 @@ Sizei TextureRegion::getDpSize() {
( Int32 )( mOriDestSize.getHeight() / mPixelDensity ) );
}
Sizef TextureRegion::getPxSize() {
Sizef TextureRegion::getPixelsSize() {
return Sizef(
( Int32 )( mOriDestSize.getWidth() / mPixelDensity * PixelDensity::getPixelDensity() ),
( Int32 )( mOriDestSize.getHeight() / mPixelDensity * PixelDensity::getPixelDensity() ) );

View File

@@ -22,6 +22,10 @@ Sizef TriangleDrawable::getSize() {
return mTriangle.getSize();
}
Sizef TriangleDrawable::getPixelsSize() {
return mTriangle.getSize();
}
void TriangleDrawable::draw() {
draw( mPosition );
}

View File

@@ -267,6 +267,7 @@ const Uint32& EventDispatcher::getReleaseTrigger() const {
}
void EventDispatcher::setNodeDragging( Node* dragging ) {
eeASSERT( mNodeDragging == nullptr || mNodeDragging == dragging || dragging == nullptr );
mNodeDragging = dragging;
}

View File

@@ -39,10 +39,6 @@ void UIAbstractTableView::setRowHeight( const Float& rowHeight ) {
}
}
void UIAbstractTableView::columnResizeToContent( const size_t& colIndex ) {
onColumnResizeToContent( colIndex );
}
void UIAbstractTableView::setColumnWidth( const size_t& colIndex, const Float& width ) {
if ( columnData( colIndex ).width != width ) {
columnData( colIndex ).width = width;
@@ -51,6 +47,10 @@ void UIAbstractTableView::setColumnWidth( const size_t& colIndex, const Float& w
}
}
const Float& UIAbstractTableView::getColumnWidth( const size_t& colIndex ) const {
return columnData( colIndex ).width;
}
void UIAbstractTableView::selectAll() {
getSelection().clear();
for ( size_t itemIndex = 0; itemIndex < getItemCount(); ++itemIndex ) {
@@ -150,7 +150,14 @@ void UIAbstractTableView::onSizeChange() {
void UIAbstractTableView::onColumnSizeChange( const size_t& ) {}
void UIAbstractTableView::onColumnResizeToContent( const size_t& ) {}
Float UIAbstractTableView::getMaxColumnContentWidth( const size_t& ) {
return 0;
}
void UIAbstractTableView::onColumnResizeToContent( const size_t& colIndex ) {
columnData( colIndex ).width = getMaxColumnContentWidth( colIndex );
createOrUpdateColumns();
}
void UIAbstractTableView::updateHeaderSize() {
size_t count = getModel()->columnCount();
@@ -170,22 +177,37 @@ int UIAbstractTableView::visibleColumn() {
return -1;
}
void UIAbstractTableView::updateColumnsWidth() {
int col = 0;
Float width =
eefloor( getPixelsSize().getWidth() - getPixelsPadding().Left - getPixelsPadding().Right -
( mVScroll->isVisible() ? mVScroll->getPixelsSize().getWidth() : 0 ) );
bool UIAbstractTableView::getAutoExpandOnSingleColumn() const {
return mAutoExpandOnSingleColumn;
}
if ( visibleColumnCount() == 1 && ( col = visibleColumn() ) != -1 ) {
columnData( col ).width = width;
updateHeaderSize();
onColumnSizeChange( col );
void UIAbstractTableView::setAutoExpandOnSingleColumn( bool autoExpandOnSingleColumn ) {
if ( autoExpandOnSingleColumn != mAutoExpandOnSingleColumn ) {
mAutoExpandOnSingleColumn = autoExpandOnSingleColumn;
updateColumnsWidth();
}
}
void UIAbstractTableView::updateScroll() {
UIAbstractView::updateScroll();
updateColumnsWidth();
void UIAbstractTableView::columnResizeToContent( const size_t& colIndex ) {
onColumnResizeToContent( colIndex );
}
Float UIAbstractTableView::getContentSpaceWidth() const {
return eefloor( getPixelsSize().getWidth() - getPixelsPadding().Left -
getPixelsPadding().Right -
( mVScroll->isVisible() ? mVScroll->getPixelsSize().getWidth() : 0 ) );
}
void UIAbstractTableView::updateColumnsWidth() {
if ( mAutoExpandOnSingleColumn ) {
int col = 0;
if ( visibleColumnCount() == 1 && ( col = visibleColumn() ) != -1 ) {
Float width = eemax( getContentSpaceWidth(), getMaxColumnContentWidth( col ) );
columnData( col ).width = width;
updateHeaderSize();
onColumnSizeChange( col );
}
}
}
const Float& UIAbstractTableView::getDragBorderDistance() const {

View File

@@ -261,10 +261,18 @@ ModelIndex FileSystemModel::index( int row, int column, const ModelIndex& parent
}
Drawable* FileSystemModel::iconFor( const Node& node, const ModelIndex& index ) const {
auto* scene = SceneManager::instance()->getUISceneNode();
Drawable* d = scene->findIcon( node.getMimeType() );
if ( !d && !node.info().isDirectory() && index.column() == (Int64)treeColumn() )
return scene->findIcon( "file" );
if ( index.column() == (Int64)treeColumn() ) {
auto* scene = SceneManager::instance()->getUISceneNode();
Drawable* d = scene->findIcon( node.getMimeType() );
if ( !d ) {
if ( !node.info().isDirectory() ) {
return scene->findIcon( "file" );
} else {
return scene->findIcon( "folder" );
}
}
return d;
}
return nullptr;
}

View File

@@ -138,6 +138,10 @@ Sizef UIBackgroundDrawable::getSize() {
return mSize;
}
Sizef UIBackgroundDrawable::getPixelsSize() {
return mSize;
}
void UIBackgroundDrawable::onAlphaChange() {
mColorNeedsUpdate = true;
}

View File

@@ -70,6 +70,10 @@ Sizef UIBorderDrawable::getSize() {
return mSize;
}
Sizef UIBorderDrawable::getPixelsSize() {
return mSize;
}
Float UIBorderDrawable::getLineWidth() const {
return mBorders.top.width;
}

View File

@@ -1832,7 +1832,7 @@ void UICodeEditor::drawWhitespaces( const std::pair<int, int>& lineRange,
// We use the GlyphDrawable since can batch the draw calls instead of Text.
GlyphDrawable* adv = mFont->getGlyphDrawable( 187 /*'»'*/, fontSize );
GlyphDrawable* cpoint = mFont->getGlyphDrawable( 183 /*'·'*/, fontSize );
Float tabCenter = ( tabWidth - adv->getPxSize().getWidth() ) * 0.5f;
Float tabCenter = ( tabWidth - adv->getPixelsSize().getWidth() ) * 0.5f;
adv->setDrawMode( GlyphDrawable::DrawMode::Text );
cpoint->setDrawMode( GlyphDrawable::DrawMode::Text );
adv->setColor( color );

View File

@@ -61,10 +61,6 @@ UIImage* UIImage::setDrawable( Drawable* drawable, bool ownIt ) {
onAutoSize();
if ( NULL != mDrawable && getSize().getWidth() == 0 && getSize().getHeight() == 0 ) {
setSize( mDrawable->getSize() );
}
autoAlign();
invalidateDraw();
@@ -79,13 +75,13 @@ void UIImage::onAutoSize() {
}
if ( mWidthPolicy == SizePolicy::WrapContent ) {
setInternalPixelsWidth( (int)mDrawable->getSize().getWidth() + mRealPadding.Left +
mRealPadding.Right );
setInternalWidth( (int)mDrawable->getSize().getWidth() + mPadding.Left +
mPadding.Right );
}
if ( mHeightPolicy == SizePolicy::WrapContent ) {
setInternalPixelsHeight( (int)mDrawable->getSize().getHeight() + mRealPadding.Top +
mRealPadding.Bottom );
setInternalHeight( (int)mDrawable->getSize().getHeight() + mPadding.Top +
mPadding.Bottom );
}
}
}
@@ -98,7 +94,7 @@ void UIImage::calcDestSize() {
if ( NULL == mDrawable )
return;
Sizef pxSize( PixelDensity::dpToPx( mDrawable->getSize() ) );
Sizef pxSize( mDrawable->getPixelsSize() );
Float Scale1 = ( mSize.x - mRealPadding.Left - mRealPadding.Right ) / pxSize.x;
Float Scale2 = ( mSize.y - mRealPadding.Top - mRealPadding.Bottom ) / pxSize.y;
@@ -110,10 +106,7 @@ void UIImage::calcDestSize() {
} else {
mDestSize = pxSize;
}
} else {
if ( NULL == mDrawable )
return;
} else if ( mDrawable ) {
mDestSize = mDrawable->getSize();
}

View File

@@ -46,6 +46,7 @@ UINode::UINode() :
if ( NULL != mUISceneNode )
setParent( (Node*)mUISceneNode->getRoot() );
}
UINode::~UINode() {
removeSkin();
@@ -53,7 +54,7 @@ UINode::~UINode() {
eeSAFE_DELETE( mForeground );
eeSAFE_DELETE( mBorder );
if ( isDragging() )
if ( isDragging() && getEventDispatcher() )
getEventDispatcher()->setNodeDragging( NULL );
}

View File

@@ -132,6 +132,10 @@ Sizef UINodeDrawable::getSize() {
return mSize;
}
Sizef UINodeDrawable::getPixelsSize() {
return mSize;
}
void UINodeDrawable::setSize( const Sizef& size ) {
if ( size != mSize ) {
mSize = size;
@@ -348,6 +352,10 @@ Sizef UINodeDrawable::LayerDrawable::getSize() {
return mSize;
}
Sizef UINodeDrawable::LayerDrawable::getPixelsSize() {
return mSize;
}
void UINodeDrawable::LayerDrawable::setSize( const Sizef& size ) {
if ( size != mSize ) {
mSize = size;

View File

@@ -32,6 +32,7 @@ UIPushButton::UIPushButton( const std::string& tag ) :
mIcon->addEventListener( Event::OnPaddingChange, cb );
mIcon->addEventListener( Event::OnMarginChange, cb );
mIcon->addEventListener( Event::OnSizeChange, cb );
mIcon->addEventListener( Event::OnVisibleChange, cb );
mTextBox = UITextView::NewWithTag( "pushbutton::text" );
mTextBox->setLayoutSizePolicy( SizePolicy::WrapContent, SizePolicy::WrapContent )
@@ -44,12 +45,6 @@ UIPushButton::UIPushButton( const std::string& tag ) :
mTextBox->addEventListener( Event::OnTextChanged, cb );
mTextBox->addEventListener( Event::OnVisibleChange, cb );
if ( NULL != getExtraInnerWidget() ) {
getExtraInnerWidget()->addEventListener( Event::OnPaddingChange, cb );
getExtraInnerWidget()->addEventListener( Event::OnMarginChange, cb );
getExtraInnerWidget()->addEventListener( Event::OnSizeChange, cb );
}
onSizeChange();
applyDefaultTheme();
@@ -73,8 +68,7 @@ void UIPushButton::onAutoSize() {
Float sH = getSkinSize().getHeight();
Float sHS = getSkinSize( UIState::StateFlagSelected ).getHeight();
Float tH = mTextBox->getPixelsSize().getHeight();
Float eH =
NULL != getExtraInnerWidget() ? getExtraInnerWidget()->getPixelsSize().getHeight() : 0;
Float eH = getExtraInnerWidget() ? getExtraInnerWidget()->getPixelsSize().getHeight() : 0;
Float h = eemax( eemax( PixelDensity::dpToPx( eemax( sH, sHS ) ), tH ), eH );
setInternalPixelsHeight( h + mRealPadding.Top + mRealPadding.Bottom );
} else if ( ( mFlags & UI_AUTO_SIZE ) && NULL != getSkin() ) {
@@ -82,39 +76,100 @@ void UIPushButton::onAutoSize() {
}
if ( ( mFlags & UI_AUTO_SIZE ) || mWidthPolicy == SizePolicy::WrapContent ) {
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 minSize =
txtW + iconSize + eWidgetSize + mRealPadding.Left + mRealPadding.Right +
getContentSize().getWidth() +
( NULL != getSkin() ? PixelDensity::dpToPxI( getSkin()->getBorderSize().Left +
getSkin()->getBorderSize().Right )
: 0 );
if ( minSize > mSize.getWidth() ) {
setInternalPixelsWidth( minSize );
setInternalPixelsWidth( getContentSize().getWidth() );
}
}
}
Vector2f UIPushButton::packLayout( const std::vector<UIWidget*>& widgets, const Rectf& padding ) {
std::vector<Vector2f> pos( widgets.size() );
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];
pos[i].x = totSize.x;
switch ( Font::getVerticalAlign( getFlags() ) ) {
case UI_VALIGN_CENTER:
pos[i].y =
eefloor( ( mSize.getHeight() - widget->getPixelsSize().getHeight() ) * 0.5f );
break;
case UI_VALIGN_BOTTOM:
pos[i].y = mSize.y - widget->getPixelsSize().getHeight() - padding.Bottom;
break;
case UI_VALIGN_TOP:
pos[i].y = padding.Top;
break;
}
if ( 0 == i )
pos[i].x += PixelDensity::dpToPxI( widget->getLayoutMargin().Left );
totSize.x += widget->getPixelsSize().getWidth() > 0
? PixelDensity::dpToPxI( widget->getLayoutMargin().Left +
widget->getLayoutMargin().Right ) +
widget->getPixelsSize().getWidth()
: 0;
totSize.y = eemax<Float>( totSize.y, padding.Top + padding.Bottom +
widget->getPixelsSize().getHeight() );
}
totSize.x += padding.Right;
Vector2f align;
switch ( Font::getHorizontalAlign( getFlags() ) ) {
case UI_HALIGN_RIGHT:
align.x = mSize.getWidth() - totSize.x;
break;
case UI_HALIGN_CENTER:
if ( mSize.getWidth() > totSize.x ) {
align.x = ( mSize.getWidth() - totSize.x ) * 0.5f;
} else {
align.x = ( totSize.x - mSize.getWidth() ) * 0.5f;
}
break;
case UI_HALIGN_LEFT:
break;
}
for ( size_t i = 0; i < widgets.size(); i++ ) {
if ( widgets[i] && widgets[i]->isVisible() )
widgets[i]->setPixelsPosition( pos[i] + align );
}
return totSize;
}
UIWidget* UIPushButton::getFirstInnerItem() const {
switch ( mInnerWidgetOrientation ) {
case InnerWidgetOrientation::Left:
return getExtraInnerWidget() && getExtraInnerWidget()->isVisible()
? getExtraInnerWidget()
: mIcon;
case InnerWidgetOrientation::Center:
return mIcon->isVisible()
? mIcon
: ( getExtraInnerWidget() && getExtraInnerWidget()->isVisible()
? getExtraInnerWidget()
: mTextBox );
case InnerWidgetOrientation::Right:
if ( mIcon->isVisible() )
return mIcon;
else
return mTextBox;
}
return mChild->isWidget() ? mChild->asType<UIWidget>() : 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 ( mRealPadding.Top > autoPadding.Top )
autoPadding.Top = mRealPadding.Top;
if ( mRealPadding.Bottom > autoPadding.Bottom )
@@ -124,99 +179,17 @@ void UIPushButton::updateLayout() {
if ( mRealPadding.Right > autoPadding.Right )
autoPadding.Right = mRealPadding.Right;
Vector2f position;
Vector2f iconPos;
Vector2f ePos;
UIWidget* eWidget = getExtraInnerWidget();
Float textBoxWidth = mTextBox->getPixelsSize().getWidth();
Float iconWidth = mIcon->getPixelsSize().getWidth() > 0
? mIcon->getPixelsSize().getWidth() +
PixelDensity::dpToPxI( mIcon->getLayoutMargin().Left +
mIcon->getLayoutMargin().Right )
: 0;
Float eWidth =
NULL != eWidget && eWidget->isVisible() && eWidget->getPixelsSize().getWidth() > 0
? eWidget->getPixelsSize().getWidth() +
PixelDensity::dpToPxI( eWidget->getLayoutMargin().Left +
eWidget->getLayoutMargin().Right )
: 0;
if ( iconWidth > 0 && textBoxWidth <= 0 &&
Font::getHorizontalAlign( getFlags() ) == UI_HALIGN_CENTER && eWidth == 0 &&
mIcon->getLayoutMargin().Left != mIcon->getLayoutMargin().Right ) {
iconWidth = mIcon->getPixelsSize().getWidth();
}
Float totalWidth = textBoxWidth + iconWidth + eWidth;
switch ( Font::getVerticalAlign( getFlags() ) ) {
case UI_VALIGN_CENTER:
iconPos.y =
eefloor( ( mSize.getHeight() - mIcon->getPixelsSize().getHeight() ) * 0.5f );
position.y =
eefloor( ( mSize.getHeight() - mTextBox->getPixelsSize().getHeight() ) * 0.5f );
ePos.y =
NULL != eWidget && eWidget->isVisible()
? eefloor( ( mSize.getHeight() - eWidget->getPixelsSize().getHeight() ) * 0.5f )
: 0;
switch ( mInnerWidgetOrientation ) {
case InnerWidgetOrientation::Left:
packLayout( {getExtraInnerWidget(), mIcon, mTextBox}, autoPadding );
break;
case UI_VALIGN_BOTTOM:
iconPos.y = mSize.y - mIcon->getPixelsSize().getHeight() - autoPadding.Bottom;
position.y = mSize.y - mTextBox->getPixelsSize().getHeight() - autoPadding.Bottom;
ePos.y = NULL != eWidget && eWidget->isVisible()
? mSize.y - eWidget->getPixelsSize().getHeight() - autoPadding.Bottom
: 0;
case InnerWidgetOrientation::Center:
packLayout( {mIcon, getExtraInnerWidget(), mTextBox}, autoPadding );
break;
case UI_VALIGN_TOP:
iconPos.y = autoPadding.Top;
position.y = autoPadding.Top;
ePos.y = autoPadding.Top;
case InnerWidgetOrientation::Right:
packLayout( {mIcon, mTextBox, getExtraInnerWidget()}, autoPadding );
break;
}
switch ( Font::getHorizontalAlign( getFlags() ) ) {
case UI_HALIGN_RIGHT:
position.x = mSize.getWidth() - autoPadding.Right;
ePos.x = position.x;
if ( NULL != eWidget && eWidget->isVisible() ) {
ePos.x = position.x - PixelDensity::dpToPx( eWidget->getLayoutMargin().Right ) -
eWidget->getPixelsSize().getWidth();
position.x = ePos.x - PixelDensity::dpToPx( eWidget->getLayoutMargin().Left );
}
position.x -= textBoxWidth;
iconPos.x = position.x - PixelDensity::dpToPxI( mIcon->getLayoutMargin().Right ) -
mIcon->getPixelsSize().getWidth();
break;
case UI_HALIGN_CENTER:
position.x = ( mSize.getWidth() - totalWidth ) / 2 + iconWidth;
iconPos.x = ( mSize.getWidth() - totalWidth ) / 2 +
PixelDensity::dpToPxI( mIcon->getLayoutMargin().Left );
if ( NULL != eWidget && eWidget->isVisible() ) {
ePos.x = position.x + textBoxWidth +
PixelDensity::dpToPx( eWidget->getLayoutMargin().Left );
}
break;
case UI_HALIGN_LEFT:
position.x = autoPadding.Left + iconWidth;
iconPos.x = autoPadding.Left + PixelDensity::dpToPxI( mIcon->getLayoutMargin().Left );
if ( NULL != eWidget && eWidget->isVisible() ) {
ePos.x = position.x + textBoxWidth +
PixelDensity::dpToPx( eWidget->getLayoutMargin().Left );
}
break;
}
mTextBox->setPixelsPosition( position );
mIcon->setPixelsPosition( iconPos );
if ( NULL != eWidget && eWidget->isVisible() ) {
eWidget->setPixelsPosition( ePos );
}
}
void UIPushButton::onPaddingChange() {
@@ -246,9 +219,10 @@ void UIPushButton::onThemeLoaded() {
UIWidget::onThemeLoaded();
}
UIPushButton* UIPushButton::setIcon( Drawable* Icon ) {
if ( mIcon->getDrawable() != Icon ) {
mIcon->setDrawable( Icon );
UIPushButton* UIPushButton::setIcon( Drawable* icon ) {
if ( mIcon->getDrawable() != icon ) {
mIcon->setSize( icon->getSize() );
mIcon->setDrawable( icon );
updateLayout();
}
return this;
@@ -367,6 +341,18 @@ Sizef UIPushButton::getContentSize() const {
return Sizef( minWidth, minHeight );
}
const InnerWidgetOrientation& UIPushButton::getInnerWidgetOrientation() const {
return mInnerWidgetOrientation;
}
void UIPushButton::setInnerWidgetOrientation(
const InnerWidgetOrientation& innerWidgetOrientation ) {
if ( mInnerWidgetOrientation != innerWidgetOrientation ) {
mInnerWidgetOrientation = innerWidgetOrientation;
updateLayout();
}
}
std::string UIPushButton::getPropertyString( const PropertyDefinition* propertyDef,
const Uint32& propertyIndex ) {
if ( NULL == propertyDef )

View File

@@ -19,10 +19,18 @@ Sizef UISkin::getSize() {
return getSize( UIState::StateFlagNormal );
}
Sizef UISkin::getPixelsSize() {
return StateListDrawable::getPixelsSize( UIState::StateFlagNormal );
}
Sizef UISkin::getSize( const Uint32& state ) {
return StateListDrawable::getSize( state );
}
Sizef UISkin::getPixelsSize( const Uint32& state ) {
return StateListDrawable::getPixelsSize( state );
}
UISkin* UISkin::clone( const std::string& NewName ) {
UISkin* SkinS = UISkin::New( NewName );
@@ -52,8 +60,8 @@ Rectf UISkin::getBorderSize( const Uint32& state ) {
TextureRegion* str( ninePatch->getTextureRegion( NinePatch::Right ) );
TextureRegion* stt( ninePatch->getTextureRegion( NinePatch::Up ) );
TextureRegion* stb( ninePatch->getTextureRegion( NinePatch::Down ) );
Rectf size( stl->getPxSize().getWidth(), stt->getPxSize().getHeight(),
str->getPxSize().getWidth(), stb->getPxSize().getHeight() );
Rectf size( stl->getPixelsSize().getWidth(), stt->getPixelsSize().getHeight(),
str->getPixelsSize().getWidth(), stb->getPixelsSize().getHeight() );
return size;
}

View File

@@ -128,15 +128,16 @@ void UISlider::onPaddingChange() {
}
Uint32 UISlider::onMouseDown( const Vector2i& position, const Uint32& flags ) {
Vector2f mouseDownInitPos(
getUISceneNode()->getEventDispatcher()->getMouseDownPos().asFloat() );
worldToNode( mouseDownInitPos );
if ( getLocalDpBounds().contains( mouseDownInitPos ) ) {
Vector2f localPos( position.asFloat() );
worldToNode( localPos );
if ( localPos.y >= mSlider->getPosition().y &&
localPos.y <= mSlider->getPosition().y + mSlider->getSize().getHeight() ) {
mSlider->startDragging( position.asFloat() );
if ( !getEventDispatcher()->isNodeDragging() ) {
Vector2f mouseDownInitPos( getEventDispatcher()->getMouseDownPos().asFloat() );
worldToNode( mouseDownInitPos );
if ( getLocalDpBounds().contains( mouseDownInitPos ) ) {
Vector2f localPos( position.asFloat() );
worldToNode( localPos );
if ( localPos.y >= mSlider->getPosition().y &&
localPos.y <= mSlider->getPosition().y + mSlider->getSize().getHeight() ) {
mSlider->startDragging( position.asFloat() );
}
}
}
return UIWidget::onMouseDown( position, flags );

View File

@@ -61,7 +61,7 @@ void UISprite::draw() {
if ( NULL != textureRegion ) {
Sizef oDestSize = textureRegion->getDestSize();
Sizef pxSize = textureRegion->getPxSize();
Sizef pxSize = textureRegion->getPixelsSize();
textureRegion->setDestSize( Sizef( (Float)pxSize.x, (Float)pxSize.y ) );
@@ -137,13 +137,13 @@ void UISprite::updateSize() {
if ( NULL != mSprite->getCurrentTextureRegion() ) {
if ( mWidthPolicy == SizePolicy::WrapContent ) {
setInternalPixelsWidth( mSprite->getCurrentTextureRegion()->getPxSize().getWidth() +
setInternalPixelsWidth( mSprite->getCurrentTextureRegion()->getPixelsSize().getWidth() +
mRealPadding.Left + mRealPadding.Right );
}
if ( mHeightPolicy == SizePolicy::WrapContent ) {
setInternalPixelsHeight(
mSprite->getCurrentTextureRegion()->getPxSize().getHeight() + mRealPadding.Top +
mSprite->getCurrentTextureRegion()->getPixelsSize().getHeight() + mRealPadding.Top +
mRealPadding.Bottom );
}
}
@@ -157,19 +157,19 @@ void UISprite::autoAlign() {
TextureRegion* tTextureRegion = mSprite->getCurrentTextureRegion();
if ( Font::getHorizontalAlign( mFlags ) == UI_HALIGN_CENTER ) {
mAlignOffset.x = ( mSize.getWidth() - tTextureRegion->getPxSize().getWidth() ) / 2;
mAlignOffset.x = ( mSize.getWidth() - tTextureRegion->getPixelsSize().getWidth() ) / 2;
} else if ( Font::getHorizontalAlign( mFlags ) == UI_HALIGN_RIGHT ) {
mAlignOffset.x =
mSize.getWidth() - tTextureRegion->getPxSize().getWidth() - mRealPadding.Right;
mSize.getWidth() - tTextureRegion->getPixelsSize().getWidth() - mRealPadding.Right;
} else {
mAlignOffset.x = mRealPadding.Left;
}
if ( Font::getVerticalAlign( mFlags ) == UI_VALIGN_CENTER ) {
mAlignOffset.y = ( mSize.getHeight() - tTextureRegion->getPxSize().getHeight() ) / 2;
mAlignOffset.y = ( mSize.getHeight() - tTextureRegion->getPixelsSize().getHeight() ) / 2;
} else if ( Font::getVerticalAlign( mFlags ) == UI_VALIGN_BOTTOM ) {
mAlignOffset.y =
mSize.getHeight() - tTextureRegion->getPxSize().getHeight() - mRealPadding.Bottom;
mSize.getHeight() - tTextureRegion->getPixelsSize().getHeight() - mRealPadding.Bottom;
} else {
mAlignOffset.y = mRealPadding.Top;
}

View File

@@ -17,9 +17,12 @@ UITab::UITab() :
mTextBox->addEventListener( Event::OnSizeChange, cb );
mIcon->addEventListener( Event::OnSizeChange, cb );
mCloseButton = UIWidget::NewWithTag( mTag + "::close" );
mCloseButton->setParent( this );
mCloseButton->setParent( const_cast<UITab*>( this ) );
mCloseButton->setEnabled( false );
mCloseButton->setVisible( false );
mCloseButton->addEventListener( Event::OnPaddingChange, cb );
mCloseButton->addEventListener( Event::OnMarginChange, cb );
mCloseButton->addEventListener( Event::OnSizeChange, cb );
applyDefaultTheme();
unsetFlags( UI_DRAG_VERTICAL );
}

View File

@@ -56,12 +56,12 @@ void UITextureRegion::onAutoSize() {
if ( mWidthPolicy == SizePolicy::WrapContent || mHeightPolicy == SizePolicy::WrapContent ) {
if ( mWidthPolicy == SizePolicy::WrapContent ) {
setInternalPixelsWidth( mTextureRegion->getPxSize().getWidth() + mRealPadding.Left +
setInternalPixelsWidth( mTextureRegion->getPixelsSize().getWidth() + mRealPadding.Left +
mRealPadding.Right );
}
if ( mHeightPolicy == SizePolicy::WrapContent ) {
setInternalPixelsHeight( mTextureRegion->getPxSize().getHeight() +
setInternalPixelsHeight( mTextureRegion->getPixelsSize().getHeight() +
mRealPadding.Top + mRealPadding.Bottom );
}
@@ -91,7 +91,7 @@ void UITextureRegion::draw() {
} else if ( mScaleType == UIScaleType::FitInside ) {
mTextureRegion->setOffset( Vector2i( 0, 0 ) );
Sizef pxSize = mTextureRegion->getPxSize();
Sizef pxSize = mTextureRegion->getPixelsSize();
Float Scale1 =
( mSize.x - mRealPadding.Left - mRealPadding.Right ) / (Float)pxSize.x;
Float Scale2 =
@@ -121,8 +121,8 @@ void UITextureRegion::draw() {
( Int32 )( (Float)oOff.y / mTextureRegion->getPixelDensity() *
PixelDensity::getPixelDensity() ) ) );
mTextureRegion->setDestSize( Vector2f( (Float)mTextureRegion->getPxSize().x,
(Float)mTextureRegion->getPxSize().y ) );
mTextureRegion->setDestSize( Vector2f( (Float)mTextureRegion->getPixelsSize().x,
(Float)mTextureRegion->getPixelsSize().y ) );
autoAlign();

View File

@@ -12,7 +12,8 @@ UITreeView* UITreeView::New() {
return eeNew( UITreeView, () );
}
UITreeView::UITreeView() : UIAbstractTableView( "treeview" ), mIndentWidth( 16 ) {
UITreeView::UITreeView() :
UIAbstractTableView( "treeview" ), mIndentWidth( PixelDensity::dpToPx( 12 ) ) {
mExpandIcon = getUISceneNode()->findIcon( "tree-expanded" );
mContractIcon = getUISceneNode()->findIcon( "tree-contracted" );
}
@@ -39,7 +40,7 @@ template <typename Callback> void UITreeView::traverseTree( Callback callback )
if ( !getModel() )
return;
auto& model = *getModel();
int indentLevel = 1;
int indentLevel = 0;
Float yOffset = getHeaderHeight();
int rowIndex = -1;
std::function<IterationDecision( const ModelIndex& )> traverseIndex =
@@ -55,7 +56,7 @@ template <typename Callback> void UITreeView::traverseTree( Callback callback )
return IterationDecision::Continue;
}
}
if ( indentLevel > 0 && !index.isValid() )
if ( indentLevel >= 0 && !index.isValid() )
return IterationDecision::Continue;
++indentLevel;
int rowCount = model.rowCount( index );
@@ -135,8 +136,85 @@ UITableRow* UITreeView::updateRow( const int& rowIndex, const ModelIndex& index,
return rowWidget;
}
class UITreeViewCell : public UIPushButton {
public:
static UITreeViewCell* New() { return eeNew( UITreeViewCell, () ); }
Uint32 getType() const { return UI_TYPE_TREEVIEW_CELL; }
bool isType( const Uint32& type ) const {
return UITreeViewCell::getType() == type ? true : UIPushButton::isType( type );
}
UIImage* getImage() const { return mImage; }
void updateLayout() {
Rectf autoPadding;
if ( mFlags & UI_AUTO_PADDING ) {
autoPadding = makePadding( true, true, true, true );
if ( autoPadding != Rectf() )
autoPadding = PixelDensity::dpToPx( autoPadding );
}
if ( mRealPadding.Top > autoPadding.Top )
autoPadding.Top = mRealPadding.Top;
if ( mRealPadding.Bottom > autoPadding.Bottom )
autoPadding.Bottom = mRealPadding.Bottom;
if ( mRealPadding.Left > autoPadding.Left )
autoPadding.Left = mRealPadding.Left;
if ( mRealPadding.Right > autoPadding.Right )
autoPadding.Right = mRealPadding.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;
}
}
void setIndentation( const Float& indent ) {
if ( mIndent != indent ) {
mIndent = indent;
updateLayout();
}
}
const Float& getIndentation() const { return mIndent; }
protected:
mutable UIImage* mImage{nullptr};
Float mIndent{0};
UITreeViewCell() : UIPushButton( "treeview::cell" ) {
mTextBox->setElementTag( mTag + "::text" );
mIcon->setElementTag( mTag + "::icon" );
mInnerWidgetOrientation = InnerWidgetOrientation::Left;
auto cb = [&]( const Event* ) { updateLayout(); };
mImage = UIImage::NewWithTag( mTag + "::expander" );
mImage->setScaleType( UIScaleType::FitInside )
->setLayoutSizePolicy( SizePolicy::WrapContent, SizePolicy::WrapContent )
->setFlags( UI_VALIGN_CENTER | UI_HALIGN_CENTER )
->setParent( const_cast<UITreeViewCell*>( this ) )
->setVisible( false )
->setEnabled( false );
mImage->addEventListener( Event::OnPaddingChange, cb );
mImage->addEventListener( Event::OnMarginChange, cb );
mImage->addEventListener( Event::OnSizeChange, cb );
mImage->addEventListener( Event::OnVisibleChange, cb );
}
virtual UIWidget* getExtraInnerWidget() const { return mImage; }
};
UIWidget* UITreeView::createCell( UIWidget* rowWidget, const ModelIndex&, const size_t& col ) {
UIPushButton* widget = UIPushButton::NewWithTag( "table::cell" );
UIPushButton* widget = col == getModel()->treeColumn()
? UITreeViewCell::New()
: UIPushButton::NewWithTag( "table::cell" );
widget->setParent( rowWidget );
widget->unsetFlags( UI_AUTO_SIZE );
widget->clipEnable();
@@ -151,6 +229,7 @@ UIWidget* UITreeView::createCell( UIWidget* rowWidget, const ModelIndex&, const
auto& data = getIndexMetadata( idx );
data.open = !data.open;
createOrUpdateColumns();
onOpenTreeModelIndex( idx, data.open );
} else {
onOpenModelIndex( idx );
}
@@ -158,7 +237,7 @@ UIWidget* UITreeView::createCell( UIWidget* rowWidget, const ModelIndex&, const
} );
widget->addEventListener( Event::MouseClick, [&]( const Event* event ) {
auto mouseEvent = static_cast<const MouseEvent*>( event );
UIImage* icon = mouseEvent->getNode()->asType<UIPushButton>()->getIcon();
UIWidget* icon = mouseEvent->getNode()->asType<UIPushButton>()->getExtraInnerWidget();
if ( icon ) {
Vector2f pos( icon->convertToNodeSpace( mouseEvent->getPosition().asFloat() ) );
if ( pos >= Vector2f::Zero && pos <= icon->getPixelsSize() ) {
@@ -168,6 +247,7 @@ UIWidget* UITreeView::createCell( UIWidget* rowWidget, const ModelIndex&, const
auto& data = getIndexMetadata( idx );
data.open = !data.open;
createOrUpdateColumns();
onOpenTreeModelIndex( idx, data.open );
}
}
}
@@ -188,40 +268,75 @@ void UITreeView::updateContentSize() {
onContentSizeChange();
}
UIWidget* UITreeView::updateCell( const int& rowIndex, const ModelIndex& index, const size_t& col,
UIWidget* UITreeView::updateCell( const int& rowIndex, const ModelIndex& index,
const size_t& indentLevel, const Float& yOffset ) {
if ( rowIndex >= (int)mWidgets.size() )
mWidgets.resize( rowIndex + 1 );
auto* widget = mWidgets[rowIndex][col];
auto* widget = mWidgets[rowIndex][index.column()];
if ( !widget ) {
UIWidget* rowWidget = updateRow( rowIndex, index, yOffset );
widget = createCell( rowWidget, index, col );
mWidgets[rowIndex][col] = widget;
widget = createCell( rowWidget, index, index.column() );
mWidgets[rowIndex][index.column()] = widget;
widget->reloadStyle( true, true, true );
}
widget->setPixelsSize( columnData( col ).width, getRowHeight() );
widget->setPixelsPosition( {getColumnPosition( col ).x, 0} );
if ( col == getModel()->treeColumn() )
widget->setPaddingLeft( getIndentWidth() * indentLevel );
ModelIndex idx( getModel()->index( index.row(), col, index.parent() ) );
Variant txt( getModel()->data( idx, Model::Role::Display ) );
widget->setPixelsSize( columnData( index.column() ).width, getRowHeight() );
widget->setPixelsPosition( {getColumnPosition( index.column() ).x, 0} );
if ( widget->isType( UI_TYPE_PUSHBUTTON ) ) {
UIPushButton* pushButton = widget->asType<UIPushButton>();
Variant txt( getModel()->data( index, Model::Role::Display ) );
if ( txt.isValid() ) {
if ( txt.is( Variant::Type::String ) )
pushButton->setText( txt.asString() );
else if ( txt.is( Variant::Type::cstr ) )
pushButton->setText( txt.asCStr() );
}
pushButton->setIcon( nullptr );
if ( col == getModel()->treeColumn() )
pushButton->setIcon( getIndexMetadata( index ).open ? mExpandIcon : mContractIcon );
Variant icon( getModel()->data( idx, Model::Role::Icon ) );
if ( icon.is( Variant::Type::Drawable ) && icon.asDrawable() )
bool hasChilds = false;
if ( widget->isType( UI_TYPE_TREEVIEW_CELL ) ) {
UITreeViewCell* cell = widget->asType<UITreeViewCell>();
UIImage* image = widget->asType<UITreeViewCell>()->getImage();
Float minIndent = !mExpandersAsIcons
? eemax( mExpandIcon->getPixelsSize().getWidth(),
mContractIcon->getPixelsSize().getWidth() ) +
PixelDensity::dpToPx( image->getLayoutMargin().Right )
: 0;
if ( index.column() == (Int64)getModel()->treeColumn() )
cell->setIndentation( minIndent + getIndentWidth() * indentLevel );
hasChilds = getModel()->rowCount( index ) > 0;
if ( hasChilds ) {
Drawable* icon = getIndexMetadata( index ).open ? mExpandIcon : mContractIcon;
image->setVisible( true );
image->setDrawable( icon );
if ( !mExpandersAsIcons ) {
cell->setIndentation( cell->getIndentation() -
image->getPixelsSize().getWidth() -
PixelDensity::dpToPx( image->getLayoutMargin().Right ) );
}
} else {
image->setVisible( false );
}
}
if ( hasChilds && mExpandersAsIcons ) {
pushButton->getIcon()->setVisible( false );
return widget;
}
bool isVisible = false;
Variant icon( getModel()->data( index, Model::Role::Icon ) );
if ( icon.is( Variant::Type::Drawable ) && icon.asDrawable() ) {
isVisible = true;
pushButton->setIcon( icon.asDrawable() );
}
pushButton->getIcon()->setVisible( isVisible );
}
return widget;
@@ -250,8 +365,15 @@ void UITreeView::drawChilds() {
if ( yOffset - mScrollOffset.y + getRowHeight() < 0 )
return IterationDecision::Continue;
for ( size_t colIndex = 0; colIndex < getModel()->columnCount(); colIndex++ ) {
if ( columnData( colIndex ).visible )
updateCell( rowIndex, index, colIndex, indentLevel, yOffset );
if ( columnData( colIndex ).visible ) {
if ( (Int64)colIndex != index.column() ) {
updateCell( rowIndex,
getModel()->index( index.row(), colIndex, index.parent() ),
indentLevel, yOffset );
} else {
updateCell( rowIndex, index, indentLevel, yOffset );
}
}
}
updateRow( rowIndex, index, yOffset )->nodeDraw();
return IterationDecision::Continue;
@@ -321,27 +443,31 @@ void UITreeView::setContractedIcon( Drawable* contractIcon ) {
}
}
void UITreeView::onColumnResizeToContent( const size_t& colIndex ) {
UIWidget* lWidget = nullptr;
bool UITreeView::getExpandersAsIcons() const {
return mExpandersAsIcons;
}
void UITreeView::setExpandersAsIcons( bool expandersAsIcons ) {
mExpandersAsIcons = expandersAsIcons;
}
Float UITreeView::getMaxColumnContentWidth( const size_t& colIndex ) {
Float lWidth = 0;
getUISceneNode()->setIsLoading( true );
traverseTree( [&, colIndex]( const int& rowIndex, const ModelIndex& index,
const size_t& indentLevel, const Float& yOffset ) {
UIWidget* widget = updateCell( rowIndex, index, colIndex, indentLevel, yOffset );
UIWidget* widget =
updateCell( rowIndex, 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 ) {
lWidget = widget;
if ( w > lWidth )
lWidth = w;
}
}
return IterationDecision::Continue;
} );
getUISceneNode()->setIsLoading( false );
if ( lWidget ) {
columnData( colIndex ).width = lWidth;
createOrUpdateColumns();
}
return lWidth;
}
void UITreeView::onModelSelectionChange() {
@@ -529,4 +655,10 @@ void UITreeView::onOpenModelIndex( const ModelIndex& index ) {
sendEvent( &event );
}
void UITreeView::onOpenTreeModelIndex( const ModelIndex& index, bool open ) {
ModelEvent event( getModel(), index, this,
open ? ModelEventType::OpenTree : ModelEventType::CloseTree );
sendEvent( &event );
}
}} // namespace EE::UI

View File

@@ -163,11 +163,11 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) {
iconTheme->add( name, ic );
return ic;
};
Drawable* closed = addIcon( "folder", 0xed6a, 16 );
Drawable* open = addIcon( "folder-open", 0xed70, 16 );
addIcon( "folder", 0xed6a, 16 );
addIcon( "folder-open", 0xed70, 16 );
addIcon( "tree-expanded", 0xea50, 24 );
addIcon( "tree-contracted", 0xea54, 24 );
addIcon( "file", 0xecc3, 24 );
addIcon( "file", 0xecc3, 16 );
UISceneNode* uiSceneNode = UISceneNode::New();
SceneManager::instance()->add( uiSceneNode );
uiSceneNode->getUIThemeManager()->setDefaultFont( font );
@@ -198,8 +198,8 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) {
auto model = FileSystemModel::New( "." ); // std::make_shared<TestModel>();
UITreeView* view = UITreeView::New();
view->setId( "treeview" );
view->setExpandedIcon( open );
view->setContractedIcon( closed );
/*view->setExpandedIcon( open );
view->setContractedIcon( closed );*/
view->setLayoutSizePolicy( SizePolicy::MatchParent, SizePolicy::MatchParent );
view->setParent( vlay );
view->setModel( model );

View File

@@ -1599,6 +1599,7 @@ void App::init( const std::string& file, const Float& pidelDensity ) {
FileSystemModel::Path},
true );
tree->setHeadersVisible( false );
tree->setExpandersAsIcons( true );
tree->addEventListener( Event::OnModelEvent, [&]( const Event* event ) {
const ModelEvent* modelEvent = static_cast<const ModelEvent*>( event );
if ( modelEvent->getModelEventType() == ModelEventType::Open ) {
@@ -1628,6 +1629,8 @@ void App::init( const std::string& file, const Float& pidelDensity ) {
tree->setModel( FileSystemModel::New( "." ) );
}
tree->setAutoExpandOnSingleColumn( true );
mWindow->runMainLoop( &appLoop );
}
}