Added SortingProxyModel to allow sorting tables by column.

Some minor improvements to ecode.
Added "delete-current-line" to text document.
This commit is contained in:
Martín Lucas Golini
2020-08-13 02:22:17 -03:00
parent 07358c225f
commit 8f430076ef
24 changed files with 485 additions and 19 deletions

View File

@@ -786,6 +786,10 @@ TableView > ScrollBar {
background-color: var(--list-back);
}
table::header::column::arrow {
margin-left: 2dp;
}
.appbackground {
background-color: var(--back);
}

View File

@@ -74,6 +74,7 @@ class EE_API Event {
OnNodeDropped,
OnSave,
OnModelEvent,
OnResourceChange,
UserEvent,
NoEvent = eeINDEX_NOT_FOUND
};

View File

@@ -76,6 +76,7 @@
#include <eepp/ui/models/filesystemmodel.hpp>
#include <eepp/ui/models/model.hpp>
#include <eepp/ui/models/modelselection.hpp>
#include <eepp/ui/models/sortingproxymodel.hpp>
#include <eepp/ui/models/widgettreemodel.hpp>
#endif

View File

@@ -125,6 +125,8 @@ class EE_API UIAbstractTableView : public UIAbstractView {
virtual void onOpenModelIndex( const ModelIndex& index );
virtual void onSortColumn( const size_t& colIndex );
void updateHeaderSize();
int visibleColumn();

View File

@@ -189,6 +189,8 @@ class EE_API TextDocument {
void deleteToNextWord();
void deleteCurrentLine();
void selectToPreviousChar();
void selectToNextChar();

View File

@@ -22,6 +22,13 @@ enum class SortOrder { None, Ascending, Descending };
class EE_API Model {
public:
class Client {
public:
virtual ~Client() {}
virtual void onModelUpdated( unsigned flags ) = 0;
};
enum UpdateFlag {
DontInvalidateIndexes = 0,
InvalidateAllIndexes = 1 << 0,
@@ -75,6 +82,10 @@ class EE_API Model {
void unregisterView( UIAbstractView* );
void registerClient( Client* );
void unregisterClient( Client* );
void refreshView();
void setOnUpdate( const std::function<void()>& onUpdate );
@@ -91,6 +102,7 @@ class EE_API Model {
private:
std::unordered_set<UIAbstractView*> mViews;
std::unordered_set<Client*> mClients;
std::function<void()> mOnUpdate;
};

View File

@@ -62,11 +62,25 @@ class EE_API ModelSelection {
void removeMatching( std::function<bool( const ModelIndex& )> );
template <typename Function> void changeFromModel( Function f ) {
{
mDisableNotify = true;
mNotifyPending = false;
f( *this );
mDisableNotify = false;
}
if ( mNotifyPending )
notifySelectionChanged();
}
protected:
UIAbstractView* mView;
std::vector<ModelIndex> mIndexes;
bool mDisableNotify{false};
bool mNotifyPending{false};
void notifySelectionChanged();
};
}}} // namespace EE::UI::Model
}}} // namespace EE::UI::Models
#endif // EE_UI_MODEL_MODELSELECTION_HPP

View File

@@ -0,0 +1,69 @@
#ifndef EE_UI_MODELS_SORTINGPROXYMODEL_HPP
#define EE_UI_MODELS_SORTINGPROXYMODEL_HPP
#include <eepp/ui/models/model.hpp>
#include <memory>
namespace EE { namespace UI { namespace Models {
class EE_API SortingProxyModel final : public Model, private Model::Client {
public:
template <typename T>
static std::shared_ptr<SortingProxyModel> New( std::shared_ptr<T> model ) {
return std::shared_ptr<SortingProxyModel>(
new SortingProxyModel( std::static_pointer_cast<Model>( model ) ) );
}
virtual ~SortingProxyModel();
virtual size_t rowCount( const ModelIndex& = ModelIndex() ) const;
virtual size_t columnCount( const ModelIndex& = ModelIndex() ) const;
virtual std::string columnName( const size_t& ) const;
virtual Variant data( const ModelIndex&, Role = Role::Display ) const;
virtual void update();
virtual int keyColumn() const;
virtual SortOrder sortOrder() const;
virtual void setKeyColumnAndSortOrder( const size_t&, const SortOrder& );
virtual bool isColumnSortable( const size_t& columnIndex ) const;
ModelIndex mapToTarget( const ModelIndex& ) const;
Role sortRole() const;
void setSortRrole( Role role );
private:
SortingProxyModel( std::shared_ptr<Model> );
virtual void onModelUpdated( unsigned );
Model& target();
const Model& target() const;
void resort( unsigned flags = Model::UpdateFlag::DontInvalidateIndexes );
void setSortingCaseSensitive( bool b );
bool isSortingCaseSensitive();
std::shared_ptr<Model> mTarget;
std::vector<int> mRowMappings;
int mKeyColumn{-1};
SortOrder mSortOrder{SortOrder::Ascending};
Role mSortRole{Role::Sort};
bool mSortingCaseSensitive{false};
bool mSorting{false};
};
}}} // namespace EE::UI::Models
#endif // EE_UI_MODELS_SORTINGPROXYMODEL_HPP

View File

@@ -3,6 +3,7 @@
#include <eepp/core/core.hpp>
#include <eepp/graphics/drawable.hpp>
#include <eepp/graphics/drawableresource.hpp>
#include <eepp/math/rect.hpp>
#include <eepp/ui/uiicon.hpp>
#include <string>
@@ -57,12 +58,14 @@ class EE_API Variant {
const bool& asBool() const { return mValue.asBool; }
const Float& asFloat() const { return mValue.asFloat; }
const int& asInt() const { return mValue.asInt; }
const unsigned int& asUint() const { return mValue.asUint; }
const Int64& asInt64() const { return mValue.asInt64; }
const Uint64& asUint64() const { return mValue.asUint64; }
const Vector2f& asVector2f() const { return *mValue.asVector2f; }
const Rectf& asRectf() const { return *mValue.asRectf; }
const char* asCStr() const { return mValue.asCStr; }
UIIcon* asIcon() const { return mValue.asIcon; }
void* asDataPtr() const { return mValue.asDataPtr; }
bool is( const Type& type ) const { return type == mType; }
void reset() {
switch ( mType ) {
@@ -86,6 +89,115 @@ class EE_API Variant {
}
bool isValid() { return mType != Type::Invalid; }
std::string toString() const {
switch ( mType ) {
case Type::Bool:
return asBool() ? "true" : "false";
case Type::Int:
return String::toString( asInt() );
case Type::Uint:
return String::toString( asUint() );
case Type::Int64:
return String::toString( asInt64() );
case Type::Uint64:
return String::toString( asUint64() );
case Type::Float:
return String::toString( asFloat() );
case Type::String:
return asString();
case Type::Drawable:
return asDrawable()->isDrawableResource()
? static_cast<DrawableResource*>( asDrawable() )->getName()
: "Drawable";
case Type::Icon:
return asIcon()->getName();
case Type::DataPtr:
return String::format( "%p", asDataPtr() );
case Type::Vector2f:
return String::format( "%.2f-%.2f", asVector2f().x, asVector2f().y );
case Type::Rectf:
return String::format( "%.2f-%.2f-%.2f-%.2f", asRectf().Top, asRectf().Right,
asRectf().Bottom, asRectf().Left );
case Type::cstr:
return asCStr();
case Type::Invalid:
break;
}
return "";
}
bool operator<( const Variant& other ) const {
if ( mType != other.mType )
return toString() < other.toString();
switch ( mType ) {
case Type::Bool:
return asBool() < other.asBool();
case Type::Int:
return asInt() < other.asInt();
case Type::Uint:
return asUint() < other.asUint();
case Type::Int64:
return asInt64() < other.asInt64();
case Type::Uint64:
return asUint64() < other.asUint64();
case Type::Float:
return asFloat() < other.asFloat();
case Type::String:
return asString() < other.asString();
case Type::Drawable:
return asDrawable() < other.asDrawable();
case Type::Icon:
return asIcon() < other.asIcon();
case Type::DataPtr:
return asDataPtr() < other.asDataPtr();
case Type::Vector2f:
return asVector2f() < other.asVector2f();
case Type::Rectf:
return asRectf().getSize() < other.asRectf().getSize();
case Type::cstr:
return strcmp( asCStr(), other.asCStr() ) < 0;
case Type::Invalid:
break;
}
return false;
}
bool operator==( const Variant& other ) const {
if ( mType != other.mType )
return toString() == other.toString();
switch ( mType ) {
case Type::Bool:
return asBool() == other.asBool();
case Type::Int:
return asInt() == other.asInt();
case Type::Uint:
return asUint() == other.asUint();
case Type::Int64:
return asInt64() == other.asInt64();
case Type::Uint64:
return asUint64() == other.asUint64();
case Type::Float:
return asFloat() == other.asFloat();
case Type::String:
return asString() == other.asString();
case Type::Drawable:
return asDrawable() == other.asDrawable();
case Type::Icon:
return asIcon() == other.asIcon();
case Type::DataPtr:
return asDataPtr() == other.asDataPtr();
case Type::Vector2f:
return asVector2f() == other.asVector2f();
case Type::Rectf:
return asRectf().getSize() == other.asRectf().getSize();
case Type::cstr:
return strcmp( asCStr(), other.asCStr() ) == 0;
case Type::Invalid:
break;
}
return false;
}
private:
union {
void* asDataPtr;

View File

@@ -14,9 +14,12 @@ class EE_API UITableHeaderColumn : public UIPushButton {
public:
UITableHeaderColumn( UIAbstractTableView* view, const size_t& colIndex );
virtual UIWidget* getExtraInnerWidget() const;
protected:
UIAbstractTableView* mView;
size_t mColIndex;
mutable UIImage* mImage{nullptr};
Uint32 onCalculateDrag( const Vector2f& position, const Uint32& flags );
@@ -28,11 +31,13 @@ class EE_API UITableHeaderColumn : public UIPushButton {
Uint32 onMouseMove( const Vector2i& position, const Uint32& flags );
Uint32 onMouseClick( const Vector2i& position, const Uint32& flags );
Uint32 onMouseDoubleClick( const Vector2i& position, const Uint32& flags );
Uint32 onDragStop( const Vector2i& pos, const Uint32& flags );
};
}}
}} // namespace EE::UI
#endif // EE_UI_UITABLEHEADERCOLUMN_HPP

View File

@@ -343,6 +343,7 @@
../../include/eepp/ui/models/model.hpp
../../include/eepp/ui/models/modelindex.hpp
../../include/eepp/ui/models/modelselection.hpp
../../include/eepp/ui/models/sortingproxymodel.hpp
../../include/eepp/ui/models/widgettreemodel.hpp
../../include/eepp/ui/tools/textureatlaseditor.hpp
../../include/eepp/ui/tools/uicodeeditorsplitter.hpp
@@ -814,6 +815,7 @@
../../src/eepp/ui/models/filesystemmodel.cpp
../../src/eepp/ui/models/model.cpp
../../src/eepp/ui/models/modelselection.cpp
../../src/eepp/ui/models/sortingproxymodel.cpp
../../src/eepp/ui/models/widgettreemodel.cpp
../../src/eepp/ui/tools/textureatlaseditor.cpp
../../src/eepp/ui/tools/textureatlasnew.cpp

View File

@@ -1,4 +1,5 @@
#include <eepp/ui/abstract/uiabstracttableview.hpp>
#include <eepp/ui/uiimage.hpp>
#include <eepp/ui/uilinearlayout.hpp>
#include <eepp/ui/uipushbutton.hpp>
#include <eepp/ui/uiscenenode.hpp>
@@ -399,4 +400,26 @@ void UIAbstractTableView::onOpenModelIndex( const ModelIndex& index ) {
sendEvent( &event );
}
void UIAbstractTableView::onSortColumn( const size_t& colIndex ) {
Model* model = getModel();
if ( !model )
return;
if ( model->isColumnSortable( colIndex ) ) {
if ( -1 != model->keyColumn() && (Int64)colIndex != model->keyColumn() &&
columnData( model->keyColumn() ).widget ) {
UIImage* image =
columnData( model->keyColumn() ).widget->getExtraInnerWidget()->asType<UIImage>();
image->setDrawable( nullptr );
}
SortOrder sortOrder = model->sortOrder() == SortOrder::Ascending ? SortOrder::Descending
: SortOrder::Ascending;
Drawable* icon = mUISceneNode->findIconDrawable(
sortOrder == SortOrder::Ascending ? "arrow-down" : "arrow-up", mIconSize );
UIImage* image = columnData( colIndex ).widget->getExtraInnerWidget()->asType<UIImage>();
if ( image && icon )
image->setDrawable( icon );
model->setKeyColumnAndSortOrder( colIndex, sortOrder );
}
}
}}} // namespace EE::UI::Abstract

View File

@@ -841,6 +841,22 @@ void TextDocument::deleteToNextWord() {
deleteTo( nextWordBoundary( getSelection().start() ) );
}
void TextDocument::deleteCurrentLine() {
if ( hasSelection() ) {
deleteSelection();
return;
}
if ( getSelection().start().line() + 1 >= (Int64)linesCount() ) {
remove( {startOfLine( getSelection().start() ),
startOfLine( {getSelection().start().line() - 1, 0} )} );
setSelection( startOfLine( getSelection().start() ) );
} else {
remove( {startOfLine( getSelection().start() ),
startOfLine( {getSelection().start().line() + 1, 0} )} );
setSelection( startOfLine( getSelection().start() ) );
}
}
void TextDocument::selectToPreviousChar() {
selectTo( -1 );
}
@@ -1366,6 +1382,7 @@ void TextDocument::initializeCommands() {
mCommands["delete-to-previous-char"] = [&] { deleteToPreviousChar(); };
mCommands["delete-to-next-word"] = [&] { deleteToNextWord(); };
mCommands["delete-to-next-char"] = [&] { deleteToNextChar(); };
mCommands["delete-current-line"] = [&] { deleteCurrentLine(); };
mCommands["delete-selection"] = [&] { deleteSelection(); };
mCommands["move-to-previous-char"] = [&] { moveToPreviousChar(); };
mCommands["move-to-previous-word"] = [&] { moveToPreviousWord(); };

View File

@@ -6,6 +6,8 @@ namespace EE { namespace UI { namespace Models {
void Model::onModelUpdate( unsigned flags ) {
if ( mOnUpdate )
mOnUpdate();
for ( auto client : mClients )
client->onModelUpdated( flags );
forEachView( [&]( UIAbstractView* view ) { view->onModelUpdate( flags ); } );
}
@@ -18,6 +20,14 @@ void Model::unregisterView( UIAbstractView* view ) {
mViews.erase( view );
}
void Model::registerClient( Model::Client* client ) {
mClients.insert( client );
}
void Model::unregisterClient( Model::Client* client ) {
mClients.erase( client );
}
void Model::refreshView() {
forEachView( [&]( UIAbstractView* view ) { view->invalidateDraw(); } );
}

View File

@@ -1,6 +1,6 @@
#include <eepp/core.hpp>
#include <eepp/ui/models/modelselection.hpp>
#include <eepp/ui/abstract/uiabstractview.hpp>
#include <eepp/ui/models/modelselection.hpp>
namespace EE { namespace UI { namespace Models {
@@ -59,4 +59,13 @@ void ModelSelection::clear() {
mView->notifySelectionChange();
}
}}} // namespace EE::UI::Model
void ModelSelection::notifySelectionChanged() {
if ( !mDisableNotify ) {
mView->notifySelectionChange();
mNotifyPending = false;
} else {
mNotifyPending = true;
}
}
}}} // namespace EE::UI::Models

View File

@@ -0,0 +1,156 @@
#include <algorithm>
#include <eepp/ui/abstract/uiabstractview.hpp>
#include <eepp/ui/models/modelselection.hpp>
#include <eepp/ui/models/sortingproxymodel.hpp>
#include <eepp/ui/models/variant.hpp>
using namespace EE::UI::Abstract;
namespace EE { namespace UI { namespace Models {
SortingProxyModel::SortingProxyModel( std::shared_ptr<Model> target ) :
mTarget( target ), mKeyColumn( -1 ) {
mTarget->registerClient( this );
resort();
}
SortingProxyModel::~SortingProxyModel() {
mTarget->unregisterClient( this );
}
void SortingProxyModel::onModelUpdated( unsigned flags ) {
resort( flags );
}
Model& SortingProxyModel::target() {
return *mTarget;
}
const Model& SortingProxyModel::target() const {
return *mTarget;
}
size_t SortingProxyModel::rowCount( const ModelIndex& index ) const {
auto targetIndex = mapToTarget( index );
return target().rowCount( targetIndex );
}
size_t SortingProxyModel::columnCount( const ModelIndex& index ) const {
auto targetIndex = mapToTarget( index );
return target().columnCount( targetIndex );
}
ModelIndex SortingProxyModel::mapToTarget( const ModelIndex& index ) const {
if ( !index.isValid() )
return {};
if ( static_cast<size_t>( index.row() ) >= mRowMappings.size() ||
static_cast<size_t>( index.column() ) >= columnCount() )
return {};
return target().index( mRowMappings[index.row()], index.column() );
}
Model::Role SortingProxyModel::sortRole() const {
return mSortRole;
}
void SortingProxyModel::setSortRrole( Model::Role role ) {
mSortRole = role;
}
std::string SortingProxyModel::columnName( const size_t& column ) const {
return target().columnName( column );
}
Variant SortingProxyModel::data( const ModelIndex& index, Role role ) const {
auto targetIndex = mapToTarget( index );
eeASSERT( targetIndex.isValid() );
return target().data( targetIndex, role );
}
void SortingProxyModel::update() {
target().update();
}
int SortingProxyModel::keyColumn() const {
return mKeyColumn;
}
SortOrder SortingProxyModel::sortOrder() const {
return mSortOrder;
}
void SortingProxyModel::setKeyColumnAndSortOrder( const size_t& column,
const SortOrder& sortOrder ) {
if ( column == (size_t)mKeyColumn && sortOrder == mSortOrder )
return;
eeASSERT( column >= 0 && column < columnCount() );
mKeyColumn = column;
mSortOrder = sortOrder;
resort();
}
void SortingProxyModel::resort( unsigned flags ) {
mSorting = true;
auto old_row_mappings = mRowMappings;
int rowCount = target().rowCount();
mRowMappings.resize( rowCount );
for ( int i = 0; i < rowCount; ++i )
mRowMappings[i] = i;
if ( mKeyColumn == -1 ) {
onModelUpdate( flags );
return;
}
std::sort( mRowMappings.begin(), mRowMappings.end(), [&]( auto row1, auto row2 ) -> bool {
Variant data1 = target().data( target().index( row1, mKeyColumn ), mSortRole );
Variant data2 = target().data( target().index( row2, mKeyColumn ), mSortRole );
if ( data1 == data2 )
return 0;
bool isLessThan;
if ( !mSortingCaseSensitive && data1.is( Variant::Type::String ) &&
data2.is( Variant::Type::String ) ) {
isLessThan = String::toLower( data1.asString() ) < String::toLower( data2.asString() );
} else if ( !mSortingCaseSensitive && data1.is( Variant::Type::cstr ) &&
data2.is( Variant::Type::cstr ) ) {
isLessThan = String::toLower( std::string( data1.asCStr() ) ) <
String::toLower( std::string( data2.asCStr() ) );
} else {
isLessThan = data1 < data2;
}
return mSortOrder == SortOrder::Ascending ? isLessThan : !isLessThan;
} );
forEachView( [&]( UIAbstractView* view ) {
view->getSelection().changeFromModel( [&]( ModelSelection& selection ) {
std::vector<ModelIndex> selectedIndexesInTarget;
selection.forEachIndex( [&]( const ModelIndex& index ) {
selectedIndexesInTarget.emplace_back(
target().index( old_row_mappings[index.row()], index.column() ) );
} );
selection.clear();
for ( auto& index : selectedIndexesInTarget ) {
for ( size_t i = 0; i < mRowMappings.size(); ++i ) {
if ( mRowMappings[i] == index.row() ) {
selection.add( this->index( i, index.column() ) );
continue;
}
}
}
} );
} );
onModelUpdate( flags );
mSorting = false;
}
void SortingProxyModel::setSortingCaseSensitive( bool b ) {
mSortingCaseSensitive = b;
}
bool SortingProxyModel::isSortingCaseSensitive() {
return mSortingCaseSensitive;
}
bool SortingProxyModel::isColumnSortable( const size_t& columnIndex ) const {
return target().isColumnSortable( columnIndex );
}
}}} // namespace EE::UI::Models

View File

@@ -34,7 +34,7 @@ const std::map<KeyBindings::Shortcut, std::string> UICodeEditor::getDefaultKeybi
{{KEY_BACKSPACE, KEYMOD_SHIFT}, "delete-to-previous-char"},
{{KEY_BACKSPACE, 0}, "delete-to-previous-char"},
{{KEY_DELETE, KEYMOD_CTRL}, "delete-to-next-word"},
{{KEY_DELETE, KEYMOD_SHIFT}, "delete-to-next-word"},
{{KEY_DELETE, KEYMOD_SHIFT}, "delete-current-line"},
{{KEY_DELETE, 0}, "delete-to-next-char"},
{{KEY_KP_ENTER, KEYMOD_CTRL | KEYMOD_SHIFT}, "new-line-above"},
{{KEY_RETURN, KEYMOD_CTRL | KEYMOD_SHIFT}, "new-line-above"},

View File

@@ -53,6 +53,7 @@ UIImage* UIImage::setDrawable( Drawable* drawable, bool ownIt ) {
mDrawable = drawable;
mDrawableOwner = ownIt;
sendCommonEvent( Event::OnResourceChange );
if ( NULL != mDrawable && mDrawable->isDrawableResource() ) {
mResourceChangeCb = static_cast<DrawableResource*>( mDrawable )

View File

@@ -144,10 +144,9 @@ Vector2f UIPushButton::packLayout( const std::vector<UIWidget*>& widgets, const
pos[i].y = padding.Top;
break;
}
if ( 0 == i )
pos[i].x += widget->getLayoutPixelsMargin().Left;
if ( widget->getPixelsSize().getWidth() > 0 ) {
totSize.x += widget->getLayoutPixelsMargin().Left + widget->getPixelsSize().getWidth();
pos[i].x += 0 == i || widget->isVisible() ? widget->getLayoutPixelsMargin().Left : 0;
if ( widget->isVisible() && widget->getPixelsSize().getWidth() > 0 ) {
totSize.x += 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;

View File

@@ -7,6 +7,18 @@ namespace EE { namespace UI {
UITableHeaderColumn::UITableHeaderColumn( UIAbstractTableView* view, const size_t& colIndex ) :
UIPushButton( "table::header::column" ), mView( view ), mColIndex( colIndex ) {
setDragEnabled( true );
mInnerWidgetOrientation = InnerWidgetOrientation::Right;
auto cb = [&]( const Event* ) { updateLayout(); };
mImage = UIImage::NewWithTag( mTag + "::arrow" );
mImage->setScaleType( UIScaleType::FitInside )
->setLayoutSizePolicy( SizePolicy::WrapContent, SizePolicy::WrapContent )
->setFlags( UI_VALIGN_CENTER | UI_HALIGN_CENTER )
->setParent( const_cast<UITableHeaderColumn*>( this ) );
mImage->setEnabled( false );
mImage->addEventListener( Event::OnPaddingChange, cb );
mImage->addEventListener( Event::OnMarginChange, cb );
mImage->addEventListener( Event::OnSizeChange, cb );
mImage->addEventListener( Event::OnVisibleChange, cb );
}
Uint32 UITableHeaderColumn::onCalculateDrag( const Vector2f& position, const Uint32& flags ) {
@@ -41,6 +53,16 @@ Uint32 UITableHeaderColumn::onMouseDown( const Vector2i& position, const Uint32&
return Node::onMouseDown( position, flags );
}
Uint32 UITableHeaderColumn::onMouseClick( const Vector2i& position, const Uint32& flags ) {
Vector2f localPos( convertToNodeSpace( position.asFloat() ) );
if ( ( flags & EE_BUTTON_LMASK ) && !isDragging() &&
localPos.x < mSize.getWidth() - mView->getDragBorderDistance() ) {
mView->onSortColumn( mColIndex );
return 1;
}
return UIPushButton::onMouseClick( position, flags );
}
Uint32 UITableHeaderColumn::onDrag( const Vector2f& position, const Uint32&,
const Sizef& dragDiff ) {
Vector2f localPos( convertToNodeSpace( position ) );
@@ -87,4 +109,8 @@ Uint32 UITableHeaderColumn::onDragStop( const Vector2i& pos, const Uint32& flags
return UIPushButton::onDragStop( pos, flags );
}
UIWidget* UITableHeaderColumn::getExtraInnerWidget() const {
return mImage;
}
}} // namespace EE::UI

View File

@@ -141,9 +141,6 @@ void UITableView::onColumnSizeChange( const size_t& ) {
}
Uint32 UITableView::onKeyDown( const KeyEvent& event ) {
if ( event.getMod() != 0 )
return UIAbstractTableView::onKeyDown( event );
auto curIndex = getSelection().first();
int pageSize = eefloor( getVisibleArea().getHeight() / getRowHeight() ) - 1;

View File

@@ -484,9 +484,6 @@ void UITreeView::setExpanderIconSize( const size_t& expanderSize ) {
}
Uint32 UITreeView::onKeyDown( const KeyEvent& event ) {
if ( event.getMod() != 0 )
return UIAbstractTableView::onKeyDown( event );
auto curIndex = getSelection().first();
switch ( event.getKeyCode() ) {

View File

@@ -164,6 +164,8 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) {
addIcon( "tree-expanded", 0xea50 );
addIcon( "tree-contracted", 0xea54 );
addIcon( "file", 0xecc3 );
addIcon( "arrow-up", 0xea77 );
addIcon( "arrow-down", 0xea4d );
UISceneNode* uiSceneNode = UISceneNode::New();
SceneManager::instance()->add( uiSceneNode );
uiSceneNode->getUIThemeManager()->setDefaultFont( font );
@@ -192,15 +194,15 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) {
Clock clock;
auto model = FileSystemModel::New( "." ); // std::make_shared<TestModel>();
UITreeView* view = UITreeView::New();
// UITableView* view = UITableView::New();
view->setExpanderIconSize( PixelDensity::dpToPx( 20 ) );
//UITreeView* view = UITreeView::New();
UITableView* view = UITableView::New();
//view->setExpanderIconSize( PixelDensity::dpToPx( 20 ) );
view->setId( "treeview" );
/*view->setExpandedIcon( open );
view->setContractedIcon( closed );*/
view->setLayoutSizePolicy( SizePolicy::MatchParent, SizePolicy::MatchParent );
view->setParent( vlay );
view->setModel( model );
view->setModel( SortingProxyModel::New( model ) );
eePRINTL( "Total time: %.2fms", clock.getElapsedTime().asMilliseconds() );
UIWindow* uiWin = UIWindow::NewOpt( UIWindow::LINEAR_LAYOUT );

View File

@@ -619,6 +619,11 @@ void App::showGlobalSearch() {
mGlobalSearchBarLayout->setVisible( true )->setEnabled( true );
mGlobalSearchInput->setFocus();
mGlobalSearchTree->setVisible( true );
if ( mEditorSplitter->getCurEditor() &&
mEditorSplitter->getCurEditor()->getDocument().hasSelection() ) {
mGlobalSearchInput->setText(
mEditorSplitter->getCurEditor()->getDocument().getSelectedText() );
}
mGlobalSearchInput->getDocument().selectAll();
updateGlobalSearchBar();
}