Added UIListView.

UIFileDialog now uses UIListView.
UITreeView/UITableView/UIListView allow selecting row by writing its name.
Styling fixes.
This commit is contained in:
Martín Lucas Golini
2020-08-17 22:22:10 -03:00
parent a5a55481dc
commit 1250fc9972
32 changed files with 369 additions and 126 deletions

View File

@@ -186,7 +186,7 @@ its submodules, in order to achieve this easily you can simply clone with:
### ecode - Text Editor
Text editor inspired in [lite](https://github.com/rxi/lite) (in development, already fully functional).
Text editor inspired in [lite](https://github.com/rxi/lite).
It's using the newest pure CSS theme based on the default [Plasma](https://kde.org/plasma-desktop)
dark theme: Breeze Dark.
@@ -635,7 +635,7 @@ Probably deprecate the Maps module, since I will focus my efforts on the UI syst
* Yuri Kobets for [litehtml](https://github.com/litehtml/litehtml)
* Michael R. P. Ragazzon [RmlUI](https://github.com/mikke89/RmlUi)
* Michael R. P. Ragazzon for [RmlUI](https://github.com/mikke89/RmlUi)
* rxi for [lite](https://github.com/rxi/lite)

View File

@@ -59,7 +59,8 @@ TextInputPassword,
TextView,
Tooltip,
MenuBar::button,
Window::title {
Window::title,
ListView::cell {
color: var(--font);
}
@@ -157,7 +158,8 @@ RadioButton::active {
ListBox,
DropDownList::ListBox,
ComboBox::DropDownList::ListBox,
Table {
Table,
ListView {
background-color: var(--list-back);
border-color: var(--button-border);
border-radius: var(--button-radius);
@@ -173,15 +175,29 @@ ListBox::item {
background-position: left bottom, right bottom;
}
ListBox:hover {
ListView::row {
background-color: transparent;
background-image: linear-gradient( to right, var(--list-back), var(--separator) ), linear-gradient( to right, var(--separator), var(--list-back) );
background-size: 50% 1dp, 50% 1dp;
background-position: left bottom, right bottom;
}
ListView::cell {
padding-left: 4dp;
}
ListBox:hover,
ListView:hover {
border-color: var(--primary);
}
ListBox::item:hover {
ListBox::item:hover,
ListView::row:hover {
background-color: var(--item-hover);
}
ListBox::item:selected {
ListBox::item:selected,
ListView::row:selected {
background-color: var(--primary);
}
@@ -734,11 +750,14 @@ Splitter::separator:hover {
background-color: var(--primary);
}
table::header {
tableview::header,
listview::header {
background-color: var(--back);
}
table::header::column {
tableview::header::column,
treeview::header::column,
listview::header::column {
background-color: var(--back);
border-right-color: var(--tab-line);
border-right-width: 1dp;
@@ -751,24 +770,29 @@ table::header::column {
text-align: left;
}
table::header::column:hover {
tableview::header::column:hover,
treeview::header::column:hover,
listview::header::column:hover {
background-color: var(--tab-hover);
}
table::row {
tableview::row,
treeview::row {
background-color: var(--list-back);
}
table::row:hover {
tableview::row:hover,
treeview::row:hover {
background-color: var(--tab-hover);
}
table::row:selected {
tableview::row:selected,
treeview::row:selected {
background-color: var(--primary);
}
table::cell,
TreeView::cell {
tableview::cell,
treeview::cell {
padding-left: 6dp;
padding-right: 6dp;
}
@@ -783,13 +807,17 @@ TableView > ScrollBar {
background-color: var(--list-back);
}
table::header::column::arrow-up {
tableview::header::column::arrow-up,
treeview::header::column::arrow-up,
listview::header::column::arrow-up {
width: 16dp;
height: 12dp;
foreground-image: poly(line, var(--icon), "1dp 4dp, 5dp 7dp"), poly(line, var(--icon), "5dp 7dp, 9dp 4dp");
}
table::header::column::arrow-down {
tableview::header::column::arrow-down,
treeview::header::column::arrow-down,
listview::header::column::arrow-down {
width: 16dp;
height: 12dp;
foreground-image: poly(line, var(--icon), "1dp 7dp, 5dp 4dp"), poly(line, var(--icon), "5dp 4dp, 9dp 7dp");

View File

@@ -65,7 +65,8 @@ Menu::SubMenu:hover,
ListBox::item:hover,
Tab:selected,
Tab:hover,
Tab:pressed {
Tab:pressed,
ListView::cell:hover, {
color: #FFF;
}
@@ -92,6 +93,18 @@ Tab::text {
padding-right: 4dp;
}
ListView {
row-height: 16dp;
}
ListView::cell {
padding-left: 4dp;
}
ListView::row {
skin: listboxitem;
}
Tooltip {
padding: 8dp;
color: #020203;

View File

@@ -1282,7 +1282,7 @@ rotation-origin-point-y: 100%;
Sets the row height in any element that contains fixed size rows.
* Applicable to: EE::UI::UIListBox (ListBox), EE::UI::UIDropDownList (DropDownList), EE::UI::UIWidgetTable (WidgetTable), EE::UI::UIGridLayout (GridLayout)
* Applicable to: EE::UI::UIListBox (ListBox), EE::UI::UIDropDownList (DropDownList), EE::UI::UIWidgetTable (WidgetTable), EE::UI::UIGridLayout (GridLayout), EE::UI::TableView (TableView), EE::UI::TreeView (TreeView), EE::UI::ListView (ListView)
* Data Type: [length](#length-data-type)
* Default value: Varies on each case. ListBox and DropDownList will guess the value based on the [font-size](#font-size). Table requires this value to be manually set in order to work. GridLayout
will require the value only if [row-mode](#row-mode) is `size`.

View File

@@ -78,6 +78,15 @@ class EE_API UIAbstractTableView : public UIAbstractView {
void setColumnsVisible( const std::vector<size_t> columns );
virtual bool applyProperty( const StyleSheetProperty& attribute );
virtual std::string getPropertyString( const PropertyDefinition* propertyDef,
const Uint32& propertyIndex = 0 );
bool getRowSearchByName() const;
void setRowSearchByName( bool rowSearchByName );
protected:
friend class EE::UI::UITableHeaderColumn;
@@ -97,6 +106,9 @@ class EE_API UIAbstractTableView : public UIAbstractView {
size_t mIconSize{12};
size_t mSortIconSize{16};
bool mAutoExpandOnSingleColumn{false};
bool mRowSearchByName{true};
Action* mSearchTextAction{nullptr};
std::string mSearchText;
virtual ~UIAbstractTableView();
@@ -134,6 +146,10 @@ class EE_API UIAbstractTableView : public UIAbstractView {
virtual void onSortColumn( const size_t& colIndex );
virtual Uint32 onTextInput( const TextInputEvent& event );
virtual ModelIndex findRowWithText( const std::string& text );
void updateHeaderSize();
int visibleColumn();

View File

@@ -14,14 +14,20 @@ class EE_API FileSystemModel : public Model {
struct DisplayConfig {
DisplayConfig() {}
DisplayConfig( bool sortByName, bool foldersFirst, bool ignoreHidden ) :
sortByName( sortByName ), foldersFirst( foldersFirst ), ignoreHidden( ignoreHidden ) {}
DisplayConfig( bool sortByName, bool foldersFirst, bool ignoreHidden,
std::vector<std::string> acceptedExtensions = {} ) :
sortByName( sortByName ),
foldersFirst( foldersFirst ),
ignoreHidden( ignoreHidden ),
acceptedExtensions( acceptedExtensions ) {}
bool sortByName{true};
bool foldersFirst{true};
bool ignoreHidden{false};
std::vector<std::string> acceptedExtensions;
bool operator==( const DisplayConfig& other ) {
return sortByName == other.sortByName && foldersFirst == other.foldersFirst &&
ignoreHidden == other.ignoreHidden;
ignoreHidden == other.ignoreHidden &&
acceptedExtensions == other.acceptedExtensions;
}
bool operator!=( const DisplayConfig& other ) { return !( *this == other ); }
};

View File

@@ -76,6 +76,8 @@ class EE_API Model {
virtual SortOrder sortOrder() const { return SortOrder::None; }
virtual bool isSortable() { return false; }
virtual void setKeyColumnAndSortOrder( const size_t& /*column*/, const SortOrder& /*order*/ ) {}
void registerView( UIAbstractView* );

View File

@@ -28,6 +28,10 @@ class EE_API SortingProxyModel final : public Model, private Model::Client {
virtual int keyColumn() const;
virtual size_t treeColumn() const;
virtual bool isSortable() { return true; }
virtual SortOrder sortOrder() const;
virtual void setKeyColumnAndSortOrder( const size_t&, const SortOrder& );

View File

@@ -4,7 +4,7 @@
#include <eepp/ui/base.hpp>
#include <eepp/ui/keyboardshortcut.hpp>
#include <eepp/ui/uicombobox.hpp>
#include <eepp/ui/uilistbox.hpp>
#include <eepp/ui/uilistview.hpp>
#include <eepp/ui/uipushbutton.hpp>
#include <eepp/ui/uitextinput.hpp>
#include <eepp/ui/uiwidget.hpp>
@@ -60,7 +60,7 @@ class EE_API UIFileDialog : public UIWindow {
UIPushButton* getButtonUp() const;
UIListBox* getList() const;
UIListView* getList() const;
UITextInput* getPathInput() const;
@@ -103,7 +103,7 @@ class EE_API UIFileDialog : public UIWindow {
UIPushButton* mButtonOpen;
UIPushButton* mButtonCancel;
UIPushButton* mButtonUp;
UIListBox* mList;
UIListView* mList;
UITextInput* mPath;
UITextInput* mFile;
UIDropDownList* mFiletype;
@@ -120,8 +120,6 @@ class EE_API UIFileDialog : public UIWindow {
void openSaveClick();
std::string getTempFullPath();
void disableButtons();
void openFileOrFolder();

View File

@@ -97,6 +97,7 @@ enum UINodeType {
UI_TYPE_TREEVIEW_CELL,
UI_TYPE_TABLEVIEW,
UI_TYPE_TABLECELL,
UI_TYPE_LISTVIEW,
UI_TYPE_USER = 10000
};

View File

@@ -0,0 +1,24 @@
#ifndef EE_UI_UILISTVIEW_HPP
#define EE_UI_UILISTVIEW_HPP
#include <eepp/ui/uitableview.hpp>
namespace EE { namespace UI {
class EE_API UIListView : public UITableView {
public:
static UIListView* New();
Uint32 getType() const;
bool isType( const Uint32& type ) const;
void setTheme( UITheme* Theme );
protected:
UIListView();
};
}} // namespace EE::UI
#endif // EE_UI_UILISTVIEW_HPP

View File

@@ -24,12 +24,18 @@ class EE_API UITableCell : public UIPushButton {
void setCurIndex( const ModelIndex& curIndex ) { mCurIndex = curIndex; }
void setTheme( UITheme* Theme ) {
UIPushButton::setTheme( Theme );
setThemeSkin( Theme, "tablerow" );
onThemeLoaded();
}
protected:
ModelIndex mCurIndex;
UITableCell() : UIPushButton( "table::cell" ) {}
UITableCell() : UITableCell( "table::cell" ) {}
UITableCell( const std::string& tag ) : UIPushButton( tag ) {}
UITableCell( const std::string& tag ) : UIPushButton( tag ) { applyDefaultTheme(); }
};
}} // namespace EE::UI

View File

@@ -12,7 +12,8 @@ using namespace Abstract;
class EE_API UITableHeaderColumn : public UIPushButton {
public:
UITableHeaderColumn( UIAbstractTableView* view, const size_t& colIndex );
UITableHeaderColumn( const std::string& parentTag, UIAbstractTableView* view,
const size_t& colIndex );
virtual UIWidget* getExtraInnerWidget() const;

View File

@@ -18,8 +18,14 @@ class EE_API UITableRow : public UIWidget {
void setCurIndex( const ModelIndex& curIndex ) { mCurIndex = curIndex; }
void setTheme( UITheme* Theme ) {
UIWidget::setTheme( Theme );
setThemeSkin( Theme, "tablerow" );
onThemeLoaded();
}
protected:
UITableRow( const std::string& tag ) : UIWidget( tag ) {}
UITableRow( const std::string& tag ) : UIWidget( tag ) { applyDefaultTheme(); }
UITableRow() : UIWidget( "table::row" ) {}

View File

@@ -26,6 +26,8 @@ class EE_API UITableView : public UIAbstractTableView {
UITableView();
UITableView( const std::string& tag );
virtual void createOrUpdateColumns();
void updateContentSize();
@@ -34,6 +36,7 @@ class EE_API UITableView : public UIAbstractTableView {
virtual Uint32 onKeyDown( const KeyEvent& event );
virtual ModelIndex findRowWithText( const std::string& text );
};
}} // namespace EE::UI

View File

@@ -100,6 +100,10 @@ class EE_API UITreeView : public UIAbstractTableView {
virtual void onOpenTreeModelIndex( const ModelIndex& index, bool open );
virtual void onSortColumn( const size_t& colIndex );
virtual ModelIndex findRowWithText( const std::string& text );
void updateContentSize();
void setAllExpanded( const ModelIndex& index = {}, bool expanded = true );

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.12.2, 2020-08-16T20:36:39. -->
<!-- Written by QtCreator 4.12.2, 2020-08-17T01:30:18. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
@@ -89,7 +89,7 @@
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{6d057187-158a-4883-8d5b-d470a6b6b025}</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">10</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">15</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">19</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">../../make/linux</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">

View File

@@ -369,6 +369,7 @@
../../include/eepp/ui/uilinearlayout.hpp
../../include/eepp/ui/uilistbox.hpp
../../include/eepp/ui/uilistboxitem.hpp
../../include/eepp/ui/uilistview.hpp
../../include/eepp/ui/uiloader.hpp
../../include/eepp/ui/uimanager.hpp
../../include/eepp/ui/uimenubar.hpp
@@ -842,6 +843,7 @@
../../src/eepp/ui/uilinearlayout.cpp
../../src/eepp/ui/uilistbox.cpp
../../src/eepp/ui/uilistboxitem.cpp
../../src/eepp/ui/uilistview.cpp
../../src/eepp/ui/uiloader.cpp
../../src/eepp/ui/uimanager.cpp
../../src/eepp/ui/uimenubar.cpp

View File

@@ -13,7 +13,7 @@ UIAbstractTableView::UIAbstractTableView( const std::string& tag ) :
mDragBorderDistance( PixelDensity::dpToPx( 4 ) ),
mIconSize( PixelDensity::dpToPxI( 12 ) ),
mSortIconSize( PixelDensity::dpToPxI( 20 ) ) {
mHeader = UILinearLayout::NewWithTag( "table::header", UIOrientation::Horizontal );
mHeader = UILinearLayout::NewWithTag( mTag + "::header", UIOrientation::Horizontal );
mHeader->setLayoutSizePolicy( SizePolicy::Fixed, SizePolicy::Fixed );
mHeader->setParent( this );
mHeader->setVisible( true );
@@ -87,7 +87,7 @@ void UIAbstractTableView::createOrUpdateColumns() {
for ( size_t i = 0; i < count; i++ ) {
ColumnData& col = columnData( i );
if ( !col.widget ) {
col.widget = eeNew( UITableHeaderColumn, ( this, i ) );
col.widget = eeNew( UITableHeaderColumn, ( mTag, this, i ) );
col.widget->setParent( mHeader );
col.widget->setEnabled( true );
col.widget->setVisible( true );
@@ -273,7 +273,7 @@ void UIAbstractTableView::setColumnsVisible( const std::vector<size_t> columns )
if ( !getModel() )
return;
for ( size_t i = 0; i < getModel()->columnCount(); i++ )
columnData( i).visible = false;
columnData( i ).visible = false;
for ( auto col : columns )
columnData( col ).visible = true;
createOrUpdateColumns();
@@ -282,7 +282,7 @@ void UIAbstractTableView::setColumnsVisible( const std::vector<size_t> columns )
UITableRow* UIAbstractTableView::createRow() {
mUISceneNode->invalidateStyle( this );
mUISceneNode->invalidateStyleState( this, true );
UITableRow* rowWidget = UITableRow::New();
UITableRow* rowWidget = UITableRow::New( mTag + "::row" );
rowWidget->setParent( this );
rowWidget->setLayoutSizePolicy( SizePolicy::Fixed, SizePolicy::Fixed );
rowWidget->reloadStyle( true, true, true );
@@ -324,7 +324,7 @@ void UIAbstractTableView::onScrollChange() {
}
UIWidget* UIAbstractTableView::createCell( UIWidget* rowWidget, const ModelIndex& index ) {
UITableCell* widget = UITableCell::New();
UITableCell* widget = UITableCell::New( mTag + "::cell" );
widget->setParent( rowWidget );
widget->unsetFlags( UI_AUTO_SIZE );
widget->clipEnable();
@@ -424,7 +424,7 @@ void UIAbstractTableView::onSortColumn( const size_t& colIndex ) {
Model* model = getModel();
if ( !model )
return;
if ( model->isColumnSortable( colIndex ) ) {
if ( model->isSortable() && model->isColumnSortable( colIndex ) ) {
if ( -1 != model->keyColumn() && (Int64)colIndex != model->keyColumn() &&
columnData( model->keyColumn() ).widget ) {
UIImage* image =
@@ -448,4 +448,63 @@ void UIAbstractTableView::onSortColumn( const size_t& colIndex ) {
}
}
Uint32 UIAbstractTableView::onTextInput( const TextInputEvent& event ) {
if ( !mRowSearchByName )
return 0;
if ( mSearchTextAction )
removeAction( mSearchTextAction );
mSearchTextAction = Actions::Runnable::New(
[&] {
mSearchTextAction = nullptr;
mSearchText = "";
},
Milliseconds( 350 ) );
runAction( mSearchTextAction );
mSearchText += String::toLower( event.getText() );
ModelIndex index = findRowWithText( mSearchText );
if ( index.isValid() )
getSelection().set( index );
return 1;
}
ModelIndex UIAbstractTableView::findRowWithText( const std::string& ) {
return {};
}
bool UIAbstractTableView::applyProperty( const StyleSheetProperty& attribute ) {
if ( !checkPropertyDefinition( attribute ) )
return false;
switch ( attribute.getPropertyDefinition()->getPropertyId() ) {
case PropertyId::RowHeight:
setRowHeight( lengthFromValue( attribute.getValue(), PropertyRelativeTarget::None ) );
break;
default:
return UIAbstractView::applyProperty( attribute );
}
return true;
}
std::string UIAbstractTableView::getPropertyString( const PropertyDefinition* propertyDef,
const Uint32& propertyIndex ) {
if ( NULL == propertyDef )
return "";
switch ( propertyDef->getPropertyId() ) {
case PropertyId::RowHeight:
return String::format( "%.2fdp", getRowHeight() );
default:
return UIAbstractView::getPropertyString( propertyDef, propertyIndex );
}
}
bool UIAbstractTableView::getRowSearchByName() const {
return mRowSearchByName;
}
void UIAbstractTableView::setRowSearchByName( bool rowSearchByName ) {
mRowSearchByName = rowSearchByName;
}
}}} // namespace EE::UI::Abstract

View File

@@ -54,10 +54,29 @@ void FileSystemModel::Node::traverseIfNeeded( const FileSystemModel& model ) {
mInfo.getFilepath(), true, model.getDisplayConfig().sortByName,
model.getDisplayConfig().foldersFirst, model.getDisplayConfig().ignoreHidden );
const auto& patterns = model.getDisplayConfig().acceptedExtensions;
bool accepted;
for ( auto file : files ) {
if ( ( model.getMode() == Mode::DirectoriesOnly && file.isDirectory() ) ||
model.getMode() == Mode::FilesAndDirectories )
mChildren.emplace_back( Node( std::move( file ), this ) );
model.getMode() == Mode::FilesAndDirectories ) {
if ( file.isDirectory() || patterns.empty() ) {
mChildren.emplace_back( Node( std::move( file ), this ) );
} else {
accepted = false;
if ( patterns.size() ) {
for ( size_t z = 0; z < patterns.size(); z++ ) {
if ( patterns[z] == FileSystem::fileExtension( file.getFilepath() ) ) {
accepted = true;
break;
}
}
} else {
accepted = true;
}
if ( accepted )
mChildren.emplace_back( Node( std::move( file ), this ) );
}
}
}
}
@@ -266,13 +285,8 @@ UIIcon* FileSystemModel::iconFor( const Node& node, const ModelIndex& index ) co
if ( index.column() == (Int64)treeColumn() || Column::Icon == index.column() ) {
auto* scene = SceneManager::instance()->getUISceneNode();
auto* d = scene->findIcon( node.getMimeType() );
if ( !d ) {
if ( !node.info().isDirectory() ) {
return scene->findIcon( "file" );
} else {
return scene->findIcon( "folder" );
}
}
if ( !d )
return scene->findIcon( !node.info().isDirectory() ? "file" : "folder" );
return d;
}
return nullptr;

View File

@@ -75,6 +75,10 @@ int SortingProxyModel::keyColumn() const {
return mKeyColumn;
}
size_t SortingProxyModel::treeColumn() const {
return target().treeColumn();
}
SortOrder SortingProxyModel::sortOrder() const {
return mSortOrder;
}

View File

@@ -1,5 +1,6 @@
#include <algorithm>
#include <eepp/system/filesystem.hpp>
#include <eepp/ui/models/filesystemmodel.hpp>
#include <eepp/ui/uifiledialog.hpp>
#include <eepp/ui/uilinearlayout.hpp>
#include <eepp/ui/uilistboxitem.hpp>
@@ -83,7 +84,7 @@ UIFileDialog::UIFileDialog( Uint32 dialogFlags, const std::string& defaultFilePa
->setLayoutSizePolicy( SizePolicy::WrapContent, SizePolicy::MatchParent )
->setParent( hLayout );
mList = UIListBox::New();
mList = UIListView::New();
mList->setParent( linearLayout );
mList->setLayoutSizePolicy( SizePolicy::MatchParent, SizePolicy::WrapContent )
->setLayoutWeight( 1 )
@@ -94,14 +95,27 @@ UIFileDialog::UIFileDialog( Uint32 dialogFlags, const std::string& defaultFilePa
goFolderUp();
}
} );
mList->addEventListener( Event::OnItemKeyDown, [&]( const Event* event ) {
const KeyEvent* KEvent = reinterpret_cast<const KeyEvent*>( event );
if ( KEvent->getKeyCode() == KEY_RETURN || KEvent->getKeyCode() == KEY_KP_ENTER ) {
openFileOrFolder();
} else if ( KEvent->getKeyCode() == KEY_BACKSPACE ) {
goFolderUp();
mList->addEventListener( Event::OnModelEvent, [&]( const Event* event ) {
const ModelEvent* modelEvent = static_cast<const ModelEvent*>( event );
if ( modelEvent->getModelEventType() == ModelEventType::Open ) {
Variant vPath(
modelEvent->getModel()->data( modelEvent->getModelIndex(), Model::Role::Custom ) );
if ( vPath.isValid() && vPath.is( Variant::Type::cstr ) )
openFileOrFolder();
}
} );
mList->setOnSelectionChange( [&] {
if ( mList->getSelection().isEmpty() )
return;
auto* node = (FileSystemModel::Node*)mList->getSelection().first().data();
if ( !isSaveDialog() ) {
if ( getAllowFolderSelect() || !FileSystem::isDirectory( node->fullPath() ) )
mFile->setText( node->getName() );
} else if ( !FileSystem::isDirectory( node->fullPath() ) ) {
mFile->setText( node->getName() );
}
} );
mList->setAutoExpandOnSingleColumn( true );
hLayout = UILinearLayout::NewHorizontal();
hLayout->setLayoutSizePolicy( SizePolicy::MatchParent, SizePolicy::WrapContent )
@@ -203,41 +217,23 @@ void UIFileDialog::refreshFolder() {
String( mCurPath ), getSortAlphabetically(), getFoldersFirst(), !getShowHidden() );
std::vector<String> files;
std::vector<std::string> patterns;
bool accepted;
Uint32 i, z;
if ( "*" != mFiletype->getText() ) {
patterns = String::split( mFiletype->getText().toUtf8(), ';' );
for ( i = 0; i < patterns.size(); i++ )
for ( size_t i = 0; i < patterns.size(); i++ )
patterns[i] = FileSystem::fileExtension( patterns[i] );
}
for ( i = 0; i < flist.size(); i++ ) {
if ( FileSystem::isDirectory( mCurPath + flist[i] ) ) {
files.push_back( flist[i] );
} else if ( !getShowOnlyFolders() ) {
accepted = false;
mList->setModel( FileSystemModel::New(
mCurPath,
getShowOnlyFolders() ? FileSystemModel::Mode::DirectoriesOnly
: FileSystemModel::Mode::FilesAndDirectories,
FileSystemModel::DisplayConfig( getSortAlphabetically(), getFoldersFirst(),
!getShowHidden(), patterns ) ) );
if ( patterns.size() ) {
for ( z = 0; z < patterns.size(); z++ ) {
if ( patterns[z] == FileSystem::fileExtension( flist[i] ) ) {
accepted = true;
break;
}
}
} else {
accepted = true;
}
if ( accepted )
files.push_back( flist[i] );
}
}
mList->clear();
mList->addListBoxItems( files );
mList->setColumnsVisible( {FileSystemModel::Name} );
mList->setHeadersVisible( false );
updateClickStep();
@@ -247,7 +243,7 @@ void UIFileDialog::refreshFolder() {
void UIFileDialog::updateClickStep() {
if ( NULL != mList->getVerticalScrollBar() ) {
mList->getVerticalScrollBar()->setClickStep(
1.f / ( ( mList->getCount() * mList->getRowHeight() ) /
1.f / ( ( mList->getModel()->rowCount() * mList->getRowHeight() ) /
(Float)mList->getSize().getHeight() ) );
}
}
@@ -287,7 +283,11 @@ void UIFileDialog::disableButtons() {
}
void UIFileDialog::openFileOrFolder() {
std::string newPath = mCurPath + mList->getItemSelectedText();
if ( mList->getSelection().isEmpty() )
return;
auto* node = (FileSystemModel::Node*)mList->getSelection().first().data();
std::string newPath = mCurPath + node->getName();
if ( FileSystem::isDirectory( newPath ) ) {
setCurPath( newPath );
@@ -327,21 +327,7 @@ Uint32 UIFileDialog::onMessage( const NodeMessage* Msg ) {
break;
}
case NodeMessage::Selected: {
if ( Msg->getSender() == mList ) {
if ( !isSaveDialog() ) {
if ( getAllowFolderSelect() ) {
mFile->setText( mList->getItemSelectedText() );
} else {
if ( !FileSystem::isDirectory( getTempFullPath() ) ) {
mFile->setText( mList->getItemSelectedText() );
}
}
} else {
if ( !FileSystem::isDirectory( getTempFullPath() ) ) {
mFile->setText( mList->getItemSelectedText() );
}
}
} else if ( Msg->getSender() == mFiletype ) {
if ( Msg->getSender() == mFiletype ) {
refreshFolder();
}
@@ -361,7 +347,12 @@ void UIFileDialog::save() {
}
void UIFileDialog::open() {
if ( "" != mList->getItemSelectedText() || getAllowFolderSelect() ) {
if ( mList->getSelection().isEmpty() )
return;
auto* node = (FileSystemModel::Node*)mList->getSelection().first().data();
if ( "" != node->getName() || getAllowFolderSelect() ) {
if ( !getAllowFolderSelect() ) {
if ( FileSystem::isDirectory( getFullPath() ) )
return;
@@ -453,16 +444,6 @@ std::string UIFileDialog::getFullPath() {
return tPath;
}
std::string UIFileDialog::getTempFullPath() {
std::string tPath = mCurPath;
FileSystem::dirAddSlashAtEnd( tPath );
tPath += mList->getItemSelectedText().toUtf8();
return tPath;
}
std::string UIFileDialog::getCurPath() const {
return mCurPath;
}
@@ -470,8 +451,10 @@ std::string UIFileDialog::getCurPath() const {
std::string UIFileDialog::getCurFile() const {
if ( mDialogFlags & SaveDialog )
return mFile->getText();
return mList->getItemSelectedText().toUtf8();
if ( mList->getSelection().isEmpty() )
return "";
auto* node = (FileSystemModel::Node*)mList->getSelection().first().data();
return node->getName();
}
UIPushButton* UIFileDialog::getButtonOpen() const {
@@ -486,7 +469,7 @@ UIPushButton* UIFileDialog::getButtonUp() const {
return mButtonUp;
}
UIListBox* UIFileDialog::getList() const {
UIListView* UIFileDialog::getList() const {
return mList;
}
@@ -518,9 +501,8 @@ const KeyBindings::Shortcut& UIFileDialog::getCloseShortcut() const {
}
void UIFileDialog::setFileName( const std::string& name ) {
if ( mFile ) {
if ( mFile )
mFile->setText( name );
}
}
void UIFileDialog::setCloseShortcut( const KeyBindings::Shortcut& closeWithKey ) {

View File

@@ -306,7 +306,7 @@ void UIListBox::setRowHeight() {
FontSize = fontStyleConfig.getFont()->getFontHeight(
PixelDensity::dpToPxI( fontStyleConfig.getFontCharacterSize() ) );
mRowHeight = (Uint32)PixelDensity::pxToDpI( FontSize ) + 4;
mRowHeight = (Uint32)PixelDensity::pxToDpI( FontSize + 4 );
}
if ( tOldRowHeight != mRowHeight ) {

View File

@@ -0,0 +1,28 @@
#include <eepp/ui/uilistview.hpp>
namespace EE { namespace UI {
UIListView* UIListView::New() {
return eeNew( UIListView, () );
}
UIListView::UIListView() : UITableView( "listview" ) {
setHeadersVisible( false );
applyDefaultTheme();
}
Uint32 UIListView::getType() const {
return UI_TYPE_LISTVIEW;
}
bool UIListView::isType( const Uint32& type ) const {
return UIListView::getType() == type ? true : UITableView::isType( type );
}
void UIListView::setTheme( UITheme* Theme ) {
UIWidget::setTheme( Theme );
setThemeSkin( Theme, "listbox" );
onThemeLoaded();
}
}} // namespace EE::UI

View File

@@ -4,8 +4,9 @@
namespace EE { namespace UI {
UITableHeaderColumn::UITableHeaderColumn( UIAbstractTableView* view, const size_t& colIndex ) :
UIPushButton( "table::header::column" ), mView( view ), mColIndex( colIndex ) {
UITableHeaderColumn::UITableHeaderColumn( const std::string& parentTag, UIAbstractTableView* view,
const size_t& colIndex ) :
UIPushButton( parentTag + "::header::column" ), mView( view ), mColIndex( colIndex ) {
setDragEnabled( true );
mInnerWidgetOrientation = InnerWidgetOrientation::Right;
auto cb = [&]( const Event* ) { updateLayout(); };

View File

@@ -10,10 +10,12 @@ UITableView* UITableView::New() {
return eeNew( UITableView, () );
}
UITableView::UITableView() : UIAbstractTableView( "tableview" ) {
UITableView::UITableView( const std::string& tag ) : UIAbstractTableView( tag ) {
clipEnable();
}
UITableView::UITableView() : UITableView( "tableview" ) {}
Uint32 UITableView::getType() const {
return UI_TYPE_TABLEVIEW;
}
@@ -238,4 +240,20 @@ Uint32 UITableView::onKeyDown( const KeyEvent& event ) {
return UIAbstractTableView::onKeyDown( event );
}
ModelIndex UITableView::findRowWithText( const std::string& text ) {
Model* model = getModel();
if ( !model || model->rowCount() == 0 )
return {};
size_t rc = model->rowCount();
for ( size_t i = 0; i < rc; i++ ) {
ModelIndex index = model->index(
i, model->keyColumn() != -1 ? model->keyColumn()
: ( model->treeColumn() >= 0 ? model->treeColumn() : 0 ) );
Variant var = model->data( index );
if ( var.isValid() && String::startsWith( String::toLower( var.toString() ), text ) )
return model->index( index.row(), 0 );
}
return {};
}
}} // namespace EE::UI

View File

@@ -664,4 +664,25 @@ void UITreeView::onOpenTreeModelIndex( const ModelIndex& index, bool open ) {
sendEvent( &event );
}
void UITreeView::onSortColumn( const size_t& ) {
// Do nothing.
return;
}
ModelIndex UITreeView::findRowWithText( const std::string& text ) {
Model* model = getModel();
if ( !model || model->rowCount() == 0 )
return {};
ModelIndex foundIndex = {};
traverseTree( [&]( const int&, const ModelIndex& index, const size_t&, const Float& ) {
Variant var = model->data( index );
if ( var.isValid() && String::startsWith( String::toLower( var.toString() ), text ) ) {
foundIndex = index;
return IterationDecision::Stop;
}
return IterationDecision::Continue;
} );
return foundIndex;
}
}} // namespace EE::UI

View File

@@ -6,6 +6,7 @@
#include <eepp/ui/uiimage.hpp>
#include <eepp/ui/uilinearlayout.hpp>
#include <eepp/ui/uilistbox.hpp>
#include <eepp/ui/uilistview.hpp>
#include <eepp/ui/uiloader.hpp>
#include <eepp/ui/uimenubar.hpp>
#include <eepp/ui/uiprogressbar.hpp>
@@ -20,8 +21,6 @@
#include <eepp/ui/uisplitter.hpp>
#include <eepp/ui/uisprite.hpp>
#include <eepp/ui/uitab.hpp>
#include <eepp/ui/uiwidgettable.hpp>
#include <eepp/ui/uiwidgettablerow.hpp>
#include <eepp/ui/uitableview.hpp>
#include <eepp/ui/uitabwidget.hpp>
#include <eepp/ui/uitextedit.hpp>
@@ -33,6 +32,8 @@
#include <eepp/ui/uitreeview.hpp>
#include <eepp/ui/uiviewpager.hpp>
#include <eepp/ui/uiwidgetcreator.hpp>
#include <eepp/ui/uiwidgettable.hpp>
#include <eepp/ui/uiwidgettablerow.hpp>
#include <eepp/ui/uiwindow.hpp>
namespace EE { namespace UI {
@@ -84,6 +85,7 @@ void UIWidgetCreator::createBaseWidgetList() {
registeredWidget["splitter"] = UISplitter::New;
registeredWidget["treeview"] = UITreeView::New;
registeredWidget["tableview"] = UITableView::New;
registeredWidget["listview"] = UIListView::New;
registeredWidget["hbox"] = UILinearLayout::NewHorizontal;
registeredWidget["vbox"] = UILinearLayout::NewVertical;

View File

@@ -203,6 +203,7 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) {
view->setLayoutSizePolicy( SizePolicy::MatchParent, SizePolicy::MatchParent );
view->setParent( vlay );
view->setModel( SortingProxyModel::New( model ) );
//view->setModel( model );
eePRINTL( "Total time: %.2fms", clock.getElapsedTime().asMilliseconds() );
UIWindow* uiWin = UIWindow::NewOpt( UIWindow::LINEAR_LAYOUT );

View File

@@ -2016,10 +2016,10 @@ void App::init( const std::string& file, const Float& pidelDensity ) {
#search_replace.error {
border-color: #ff4040;
}
TableView#locate_bar_table > table::row > table::cell:nth-child(2) {
TableView#locate_bar_table > tableview::row > tableview::cell:nth-child(2) {
color: var(--font-hint);
}
TableView#locate_bar_table > table::row:selected > table::cell:nth-child(2) {
TableView#locate_bar_table > tableview::row:selected > tableview::cell:nth-child(2) {
color: var(--font);
}
#search_tree treeview::cell {
@@ -2127,7 +2127,6 @@ void App::init( const std::string& file, const Float& pidelDensity ) {
addIcon( "tree-expanded", 0xea50 );
addIcon( "tree-contracted", 0xea54 );
addIcon( "search", 0xf0d1 );
addIcon( "go-up", 0xea78 );
addIcon( "ok", 0xeb7a );
addIcon( "cancel", 0xeb98 );