mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-27 00:28:34 +03:00
Sys added Sys::epochToString.
ecode: Update file system tree view on changes. Added a couple of linters. Allow to select global results in UITreeViewGlobalSearch (not used but implemented, it will be used for global search & replace).
This commit is contained in:
@@ -15,5 +15,17 @@
|
||||
"file_patterns": ["%.lua$"],
|
||||
"warning_pattern": "[^:]:(%d+):(%d+):[%s]?([^\n]+)",
|
||||
"command": "luacheck $FILENAME --formatter=plain -g --no-max-line-length"
|
||||
},
|
||||
{
|
||||
"file_patterns": ["%.py$"],
|
||||
"warning_pattern": "[^:]:(%d+):(%d+):%s([%w]+:%s[^\n]*)",
|
||||
"column_starts_at_zero": true,
|
||||
"command": "pylint --score=n $FILENAME"
|
||||
},
|
||||
{
|
||||
"file_patterns": ["%.sh$"],
|
||||
"warning_pattern": "[^:]:(%d+):(%d+):%s?([^%s]*)([^\n]*)",
|
||||
"warning_pattern_order": { "line": 1, "col": 2, "message": 4, "type": 3 },
|
||||
"command": "shellcheck -f gcc $FILENAME"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -11,8 +11,12 @@ class EE_API Sys {
|
||||
/** Returns the current date time */
|
||||
static std::string getDateTimeStr();
|
||||
|
||||
/** Converts any epoch timestmap to a formatted string. */
|
||||
static std::string epochToString( const Uint64& epochTimestamp,
|
||||
const std::string& format = "%Y-%m-%d %H:%M" );
|
||||
|
||||
/** @return A storage path for config files for every platform */
|
||||
static std::string getConfigPath( std::string appname );
|
||||
static std::string getConfigPath( const std::string& appname );
|
||||
|
||||
/** @return The path of the directory designated for temporary files. */
|
||||
static std::string getTempPath();
|
||||
|
||||
@@ -51,6 +51,8 @@ class EE_API UIAbstractView : public UIScrollableWidget {
|
||||
|
||||
const Model* getModel() const { return mModel.get(); }
|
||||
|
||||
std::shared_ptr<Model> getModelShared() const { return mModel; }
|
||||
|
||||
ModelSelection& getSelection() { return mSelection; }
|
||||
|
||||
const ModelSelection& getSelection() const { return mSelection; }
|
||||
|
||||
@@ -20,9 +20,9 @@ class EE_API FileSystemModel : public Model {
|
||||
foldersFirst( foldersFirst ),
|
||||
ignoreHidden( ignoreHidden ),
|
||||
acceptedExtensions( acceptedExtensions ) {}
|
||||
bool sortByName{true};
|
||||
bool foldersFirst{true};
|
||||
bool ignoreHidden{false};
|
||||
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 &&
|
||||
@@ -49,33 +49,49 @@ class EE_API FileSystemModel : public Model {
|
||||
struct Node {
|
||||
public:
|
||||
Node( const std::string& rootPath, const FileSystemModel& model );
|
||||
|
||||
Node( FileInfo&& info, Node* parent );
|
||||
|
||||
const std::string& getName() const { return mName; }
|
||||
|
||||
Node* getParent() const { return mParent; }
|
||||
|
||||
const FileInfo& info() const { return mInfo; }
|
||||
|
||||
bool isSelected() const { return mSelected; }
|
||||
|
||||
void setSelected( bool selected ) { mSelected = selected; };
|
||||
|
||||
const std::string& fullPath() const;
|
||||
|
||||
const std::string& getMimeType() const { return mMimeType; }
|
||||
|
||||
size_t childCount() const { return mChildren.size(); }
|
||||
const Node& getChild( const size_t& index ) {
|
||||
eeASSERT( index < mChildren.size() );
|
||||
return mChildren[index];
|
||||
}
|
||||
|
||||
const Node& getChild( const size_t& index );
|
||||
|
||||
void invalidate();
|
||||
|
||||
Node* findChildName( const std::string& name, const FileSystemModel& model,
|
||||
bool forceRefresh = false );
|
||||
|
||||
private:
|
||||
friend class FileSystemModel;
|
||||
std::string mName;
|
||||
std::string mMimeType;
|
||||
Node* mParent{nullptr};
|
||||
Node* mParent{ nullptr };
|
||||
FileInfo mInfo;
|
||||
std::vector<Node> mChildren;
|
||||
bool mHasTraversed{false};
|
||||
bool mInfoDirty{true};
|
||||
bool mSelected{false};
|
||||
bool mHasTraversed{ false };
|
||||
bool mInfoDirty{ true };
|
||||
bool mSelected{ false };
|
||||
|
||||
ModelIndex index( const FileSystemModel& model, int column ) const;
|
||||
|
||||
void traverseIfNeeded( const FileSystemModel& );
|
||||
|
||||
void refreshIfNeeded( const FileSystemModel& );
|
||||
|
||||
bool fetchData( const String& fullPath );
|
||||
};
|
||||
|
||||
@@ -85,10 +101,12 @@ class EE_API FileSystemModel : public Model {
|
||||
|
||||
const Mode& getMode() const { return mMode; }
|
||||
|
||||
std::string getRootPath() const;
|
||||
const std::string& getRootPath() const;
|
||||
|
||||
void setRootPath( const std::string& rootPath );
|
||||
|
||||
Node* getNodeFromPath( std::string path, bool folderNode = false, bool invalidateTree = true );
|
||||
|
||||
void reload();
|
||||
|
||||
void update();
|
||||
@@ -111,10 +129,15 @@ class EE_API FileSystemModel : public Model {
|
||||
|
||||
void setDisplayConfig( const DisplayConfig& displayConfig );
|
||||
|
||||
const ModelIndex& getPreviouslySelectedIndex() const;
|
||||
|
||||
void setPreviouslySelectedIndex( const ModelIndex& previouslySelectedIndex );
|
||||
|
||||
protected:
|
||||
std::string mRootPath;
|
||||
std::unique_ptr<Node> mRoot{nullptr};
|
||||
Mode mMode{Mode::FilesAndDirectories};
|
||||
std::string mRealRootPath;
|
||||
std::unique_ptr<Node> mRoot{ nullptr };
|
||||
Mode mMode{ Mode::FilesAndDirectories };
|
||||
DisplayConfig mDisplayConfig;
|
||||
|
||||
ModelIndex mPreviouslySelectedIndex{};
|
||||
|
||||
@@ -92,6 +92,8 @@ class EE_API Model {
|
||||
|
||||
void setOnUpdate( const std::function<void()>& onUpdate );
|
||||
|
||||
void invalidate();
|
||||
|
||||
protected:
|
||||
Model(){};
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ class EE_API UICheckBox : public UITextView {
|
||||
public:
|
||||
static UICheckBox* New();
|
||||
|
||||
UICheckBox();
|
||||
static UICheckBox* NewWithTag( const std::string& tag );
|
||||
|
||||
virtual ~UICheckBox();
|
||||
|
||||
@@ -28,6 +28,8 @@ class EE_API UICheckBox : public UITextView {
|
||||
|
||||
UIWidget* getInactiveButton() const;
|
||||
|
||||
UIWidget* getCurrentButton() const;
|
||||
|
||||
Int32 getTextSeparation() const;
|
||||
|
||||
void setTextSeparation( const Int32& textSeparation );
|
||||
@@ -44,6 +46,10 @@ class EE_API UICheckBox : public UITextView {
|
||||
Uint32 mLastTick;
|
||||
Int32 mTextSeparation;
|
||||
|
||||
UICheckBox();
|
||||
|
||||
UICheckBox( const std::string& tag );
|
||||
|
||||
virtual void onSizeChange();
|
||||
|
||||
void switchState();
|
||||
|
||||
@@ -78,6 +78,8 @@ class EE_API UINode : public Node {
|
||||
|
||||
Rect getRect() const;
|
||||
|
||||
Rectf getRectBox() const;
|
||||
|
||||
virtual void draw();
|
||||
|
||||
Uint32 getHorizontalAlign() const;
|
||||
|
||||
@@ -15,6 +15,9 @@ class EE_API UIPushButton : public UIWidget {
|
||||
|
||||
static UIPushButton* NewWithTag( const std::string& tag );
|
||||
|
||||
static UIPushButton* NewWithOpt( const std::string& tag,
|
||||
const std::function<UITextView*()>& newTextViewCb );
|
||||
|
||||
UIPushButton();
|
||||
|
||||
virtual ~UIPushButton();
|
||||
@@ -62,10 +65,12 @@ class EE_API UIPushButton : public UIWidget {
|
||||
UIImage* mIcon;
|
||||
UITextView* mTextBox;
|
||||
Sizei mIconMinSize;
|
||||
InnerWidgetOrientation mInnerWidgetOrientation{InnerWidgetOrientation::Right};
|
||||
InnerWidgetOrientation mInnerWidgetOrientation{ InnerWidgetOrientation::Right };
|
||||
|
||||
explicit UIPushButton( const std::string& tag );
|
||||
|
||||
explicit UIPushButton( const std::string& tag, const std::function<UITextView*()>& cb );
|
||||
|
||||
virtual Rectf calculatePadding() const;
|
||||
|
||||
virtual void onSizeChange();
|
||||
|
||||
@@ -30,12 +30,18 @@ class EE_API UITableCell : public UIPushButton {
|
||||
onThemeLoaded();
|
||||
}
|
||||
|
||||
virtual void updateCell( Model* ){};
|
||||
|
||||
protected:
|
||||
ModelIndex mCurIndex;
|
||||
|
||||
UITableCell() : UITableCell( "table::cell" ) {}
|
||||
|
||||
UITableCell( const std::string& tag ) : UIPushButton( tag ) { applyDefaultTheme(); }
|
||||
UITableCell( const std::string& tag,
|
||||
const std::function<UITextView*()>& newTextViewCb = nullptr ) :
|
||||
UIPushButton( tag, newTextViewCb ) {
|
||||
applyDefaultTheme();
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace EE::UI
|
||||
|
||||
@@ -94,7 +94,9 @@ class EE_API UITextView : public UIWidget {
|
||||
|
||||
const Text* getTextCache() const;
|
||||
|
||||
protected:
|
||||
const Vector2f& getRealAlignOffset() const;
|
||||
|
||||
protected:
|
||||
Text* mTextCache;
|
||||
String mString;
|
||||
UIFontStyleConfig mFontStyleConfig;
|
||||
|
||||
@@ -55,10 +55,11 @@ class EE_API UITreeViewCell : public UITableCell {
|
||||
const Float& getIndentation() const { return mIndent; }
|
||||
|
||||
protected:
|
||||
mutable UIImage* mImage{nullptr};
|
||||
Float mIndent{0};
|
||||
mutable UIImage* mImage{ nullptr };
|
||||
Float mIndent{ 0 };
|
||||
|
||||
UITreeViewCell() : UITableCell( "treeview::cell" ) {
|
||||
UITreeViewCell( const std::function<UITextView*()>& newTextViewCb = nullptr ) :
|
||||
UITableCell( "treeview::cell", newTextViewCb ) {
|
||||
mTextBox->setElementTag( mTag + "::text" );
|
||||
mIcon->setElementTag( mTag + "::icon" );
|
||||
mInnerWidgetOrientation = InnerWidgetOrientation::Left;
|
||||
@@ -137,17 +138,17 @@ class EE_API UITreeView : public UIAbstractTableView {
|
||||
|
||||
Float mIndentWidth;
|
||||
Sizef mContentSize;
|
||||
UIIcon* mExpandIcon{nullptr};
|
||||
UIIcon* mContractIcon{nullptr};
|
||||
size_t mExpanderIconSize{16};
|
||||
bool mExpandersAsIcons{false};
|
||||
UIIcon* mExpandIcon{ nullptr };
|
||||
UIIcon* mContractIcon{ nullptr };
|
||||
size_t mExpanderIconSize{ 16 };
|
||||
bool mExpandersAsIcons{ false };
|
||||
|
||||
UITreeView();
|
||||
|
||||
virtual void createOrUpdateColumns();
|
||||
|
||||
struct MetadataForIndex {
|
||||
bool open{false};
|
||||
bool open{ false };
|
||||
};
|
||||
|
||||
template <typename Callback> void traverseTree( Callback ) const;
|
||||
|
||||
+11
-2
@@ -6,6 +6,7 @@
|
||||
#include <eepp/system/filesystem.hpp>
|
||||
#include <eepp/system/log.hpp>
|
||||
#include <eepp/system/sys.hpp>
|
||||
#include <iomanip>
|
||||
|
||||
// This taints the System module!
|
||||
#if EE_PLATFORM == EE_PLATFORM_ANDROID
|
||||
@@ -578,7 +579,7 @@ double Sys::getSystemTime() {
|
||||
// High performance counter not available : use GetTickCount (less accurate)
|
||||
return GetTickCount() * 0.001;
|
||||
#else
|
||||
timeval Time = {0, 0};
|
||||
timeval Time = { 0, 0 };
|
||||
gettimeofday( &Time, NULL );
|
||||
|
||||
return Time.tv_sec + Time.tv_usec / 1000000.;
|
||||
@@ -599,8 +600,16 @@ std::string Sys::getDateTimeStr() {
|
||||
return std::string( buf );
|
||||
}
|
||||
|
||||
std::string Sys::epochToString( const Uint64& epochTimestamp, const std::string& format ) {
|
||||
std::time_t t = epochTimestamp;
|
||||
auto tm = *std::localtime( &t );
|
||||
std::ostringstream oss;
|
||||
oss << std::put_time( &tm, format.c_str() );
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
#define EE_MAX_CFG_PATH_LEN 1024
|
||||
std::string Sys::getConfigPath( std::string appname ) {
|
||||
std::string Sys::getConfigPath( const std::string& appname ) {
|
||||
char path[EE_MAX_CFG_PATH_LEN];
|
||||
|
||||
#if EE_PLATFORM == EE_PLATFORM_WIN
|
||||
|
||||
@@ -427,6 +427,8 @@ UIWidget* UIAbstractTableView::updateCell( const int& rowIndex, const ModelIndex
|
||||
cell->setIcon( icon.asIcon()->getSize( mIconSize ) );
|
||||
}
|
||||
cell->getIcon()->setVisible( isVisible );
|
||||
|
||||
cell->updateCell( getModel() );
|
||||
}
|
||||
|
||||
return widget;
|
||||
|
||||
@@ -34,6 +34,29 @@ const std::string& FileSystemModel::Node::fullPath() const {
|
||||
return mInfo.getFilepath();
|
||||
}
|
||||
|
||||
const FileSystemModel::Node& FileSystemModel::Node::getChild( const size_t& index ) {
|
||||
eeASSERT( index < mChildren.size() );
|
||||
return mChildren[index];
|
||||
}
|
||||
|
||||
void FileSystemModel::Node::invalidate() {
|
||||
mHasTraversed = false;
|
||||
mInfoDirty = true;
|
||||
mChildren.clear();
|
||||
}
|
||||
|
||||
FileSystemModel::Node* FileSystemModel::Node::findChildName( const std::string& name,
|
||||
const FileSystemModel& model,
|
||||
bool forceRefresh ) {
|
||||
if ( forceRefresh )
|
||||
refreshIfNeeded( model );
|
||||
for ( auto& child : mChildren ) {
|
||||
if ( child.getName() == name )
|
||||
return &child;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ModelIndex FileSystemModel::Node::index( const FileSystemModel& model, int column ) const {
|
||||
if ( !mParent )
|
||||
return {};
|
||||
@@ -103,19 +126,56 @@ std::shared_ptr<FileSystemModel> FileSystemModel::New( const std::string& rootPa
|
||||
|
||||
FileSystemModel::FileSystemModel( const std::string& rootPath, const FileSystemModel::Mode& mode,
|
||||
const DisplayConfig displayConfig ) :
|
||||
mRootPath( rootPath ), mMode( mode ), mDisplayConfig( displayConfig ) {
|
||||
mRootPath( rootPath ),
|
||||
mRealRootPath( FileSystem::getRealPath( rootPath ) ),
|
||||
mMode( mode ),
|
||||
mDisplayConfig( displayConfig ) {
|
||||
update();
|
||||
}
|
||||
|
||||
std::string FileSystemModel::getRootPath() const {
|
||||
const std::string& FileSystemModel::getRootPath() const {
|
||||
return mRootPath;
|
||||
}
|
||||
|
||||
void FileSystemModel::setRootPath( const std::string& rootPath ) {
|
||||
mRootPath = rootPath;
|
||||
mRealRootPath = FileSystem::getRealPath( mRootPath );
|
||||
update();
|
||||
}
|
||||
|
||||
FileSystemModel::Node* FileSystemModel::getNodeFromPath( std::string path, bool folderNode,
|
||||
bool invalidateTree ) {
|
||||
path = FileSystem::getRealPath( path );
|
||||
if ( folderNode && !FileSystem::isDirectory( path ) )
|
||||
path = FileSystem::fileRemoveFileName( path );
|
||||
if ( String::startsWith( path, mRealRootPath ) )
|
||||
path = path.substr( mRealRootPath.size() );
|
||||
else if ( path.empty() ||
|
||||
!( path[0] == '/' ||
|
||||
( path.size() >= 2 && String::isLetter( path[0] ) && path[1] == ':' ) ) ) {
|
||||
return nullptr;
|
||||
}
|
||||
if ( String::contains( path, "\\" ) )
|
||||
String::replaceAll( path, "\\", "/" );
|
||||
auto folders = String::split( path, '/' );
|
||||
Node* curNode = mRoot.get();
|
||||
Node* foundNode = nullptr;
|
||||
|
||||
if ( !folders.empty() ) {
|
||||
for ( size_t i = 0; i < folders.size(); i++ ) {
|
||||
auto& part = folders[i];
|
||||
if ( ( foundNode = curNode->findChildName(
|
||||
part, *this, invalidateTree || i == folders.size() - 1 ) ) ) {
|
||||
curNode = foundNode;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return curNode;
|
||||
}
|
||||
|
||||
void FileSystemModel::reload() {
|
||||
setRootPath( mRootPath );
|
||||
}
|
||||
@@ -187,14 +247,6 @@ static std::string permissionString( const FileInfo& info ) {
|
||||
return builder;
|
||||
}
|
||||
|
||||
static std::string timestampString( const Uint64& time ) {
|
||||
std::time_t t = time;
|
||||
auto tm = *std::localtime( &t );
|
||||
std::ostringstream oss;
|
||||
oss << std::put_time( &tm, "%Y-%m-%d %H:%M" );
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
Variant FileSystemModel::data( const ModelIndex& index, Model::Role role ) const {
|
||||
eeASSERT( index.isValid() );
|
||||
|
||||
@@ -245,7 +297,7 @@ Variant FileSystemModel::data( const ModelIndex& index, Model::Role role ) const
|
||||
case Column::Permissions:
|
||||
return Variant( permissionString( node.info() ) );
|
||||
case Column::ModificationTime:
|
||||
return Variant( timestampString( node.info().getModificationTime() ) );
|
||||
return Variant( Sys::epochToString( node.info().getModificationTime() ) );
|
||||
case Column::Inode:
|
||||
return Variant( String::toString( node.info().getInode() ) );
|
||||
case Column::Path:
|
||||
@@ -311,4 +363,12 @@ void FileSystemModel::setDisplayConfig( const DisplayConfig& displayConfig ) {
|
||||
}
|
||||
}
|
||||
|
||||
const ModelIndex& FileSystemModel::getPreviouslySelectedIndex() const {
|
||||
return mPreviouslySelectedIndex;
|
||||
}
|
||||
|
||||
void FileSystemModel::setPreviouslySelectedIndex( const ModelIndex& previouslySelectedIndex ) {
|
||||
mPreviouslySelectedIndex = previouslySelectedIndex;
|
||||
}
|
||||
|
||||
}}} // namespace EE::UI::Models
|
||||
|
||||
@@ -45,6 +45,10 @@ void Model::setOnUpdate( const std::function<void()>& onUpdate ) {
|
||||
mOnUpdate = onUpdate;
|
||||
}
|
||||
|
||||
void Model::invalidate() {
|
||||
onModelUpdate();
|
||||
}
|
||||
|
||||
ModelIndex Model::sibling( int row, int column, const ModelIndex& parent ) const {
|
||||
if ( !parent.isValid() )
|
||||
return index( row, column, {} );
|
||||
|
||||
@@ -9,10 +9,17 @@ UICheckBox* UICheckBox::New() {
|
||||
return eeNew( UICheckBox, () );
|
||||
}
|
||||
|
||||
UICheckBox::UICheckBox() : UITextView( "checkbox" ), mChecked( false ), mTextSeparation( 4 ) {
|
||||
UICheckBox* UICheckBox::NewWithTag( const std::string& tag ) {
|
||||
return eeNew( UICheckBox, ( tag ) );
|
||||
}
|
||||
|
||||
UICheckBox::UICheckBox() : UICheckBox( "checkbox" ) {}
|
||||
|
||||
UICheckBox::UICheckBox( const std::string& tag ) :
|
||||
UITextView( tag ), mChecked( false ), mTextSeparation( 4 ) {
|
||||
auto cb = [&]( const Event* ) { onAutoSize(); };
|
||||
|
||||
mActiveButton = UIWidget::NewWithTag( "checkbox::active" );
|
||||
mActiveButton = UIWidget::NewWithTag( tag + "::active" );
|
||||
mActiveButton->setVisible( false );
|
||||
mActiveButton->setEnabled( true );
|
||||
mActiveButton->setParent( this );
|
||||
@@ -20,7 +27,7 @@ UICheckBox::UICheckBox() : UITextView( "checkbox" ), mChecked( false ), mTextSep
|
||||
mActiveButton->setSize( 8, 8 );
|
||||
mActiveButton->addEventListener( Event::OnSizeChange, cb );
|
||||
|
||||
mInactiveButton = UIWidget::NewWithTag( "checkbox::inactive" );
|
||||
mInactiveButton = UIWidget::NewWithTag( tag + "::inactive" );
|
||||
mInactiveButton->setVisible( true );
|
||||
mInactiveButton->setEnabled( true );
|
||||
mInactiveButton->setParent( this );
|
||||
@@ -197,6 +204,10 @@ UIWidget* UICheckBox::getInactiveButton() const {
|
||||
return mInactiveButton;
|
||||
}
|
||||
|
||||
UIWidget* UICheckBox::getCurrentButton() const {
|
||||
return mChecked ? mActiveButton : mInactiveButton;
|
||||
}
|
||||
|
||||
Int32 UICheckBox::getTextSeparation() const {
|
||||
return mTextSeparation;
|
||||
}
|
||||
|
||||
@@ -300,6 +300,10 @@ Rect UINode::getRect() const {
|
||||
return Rect( Vector2i( mDpPos.x, mDpPos.y ), Sizei( mDpSize.x, mDpSize.y ) );
|
||||
}
|
||||
|
||||
Rectf UINode::getRectBox() const {
|
||||
return Rectf( mPosition, mSize );
|
||||
}
|
||||
|
||||
const Sizef& UINode::getSize() const {
|
||||
return mDpSize;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,15 @@ UIPushButton* UIPushButton::NewWithTag( const std::string& tag ) {
|
||||
return eeNew( UIPushButton, ( tag ) );
|
||||
}
|
||||
|
||||
UIPushButton::UIPushButton( const std::string& tag ) :
|
||||
UIPushButton* UIPushButton::NewWithOpt( const std::string& tag,
|
||||
const std::function<UITextView*()>& newTextViewCb ) {
|
||||
return eeNew( UIPushButton, ( tag, newTextViewCb ) );
|
||||
}
|
||||
|
||||
UIPushButton::UIPushButton( const std::string& tag ) : UIPushButton( tag, nullptr ) {}
|
||||
|
||||
UIPushButton::UIPushButton( const std::string& tag,
|
||||
const std::function<UITextView*()>& newTextViewCb ) :
|
||||
UIWidget( tag ), mIcon( NULL ), mTextBox( NULL ) {
|
||||
mFlags |= ( UI_AUTO_SIZE | UI_VALIGN_CENTER | UI_HALIGN_CENTER );
|
||||
|
||||
@@ -35,7 +43,7 @@ UIPushButton::UIPushButton( const std::string& tag ) :
|
||||
mIcon->addEventListener( Event::OnSizeChange, cb );
|
||||
mIcon->addEventListener( Event::OnVisibleChange, cb );
|
||||
|
||||
mTextBox = UITextView::NewWithTag( "pushbutton::text" );
|
||||
mTextBox = newTextViewCb ? newTextViewCb() : UITextView::NewWithTag( "pushbutton::text" );
|
||||
mTextBox->setLayoutSizePolicy( SizePolicy::WrapContent, SizePolicy::WrapContent )
|
||||
->setFlags( UI_VALIGN_CENTER | UI_HALIGN_CENTER )
|
||||
->setParent( this )
|
||||
|
||||
@@ -231,6 +231,10 @@ const Text* UITextView::getTextCache() const {
|
||||
return mTextCache;
|
||||
}
|
||||
|
||||
const Vector2f& UITextView::getRealAlignOffset() const {
|
||||
return mRealAlignOffset;
|
||||
}
|
||||
|
||||
const Color& UITextView::getFontShadowColor() const {
|
||||
return mFontStyleConfig.ShadowColor;
|
||||
}
|
||||
|
||||
@@ -237,6 +237,8 @@ UIWidget* UITreeView::updateCell( const int& rowIndex, const ModelIndex& index,
|
||||
cell->setIcon( icon.asIcon()->getSize( mIconSize ) );
|
||||
}
|
||||
cell->getIcon()->setVisible( isVisible );
|
||||
|
||||
cell->updateCell( getModel() );
|
||||
}
|
||||
|
||||
return widget;
|
||||
|
||||
@@ -823,7 +823,8 @@ void App::initGlobalSearchBar() {
|
||||
} );
|
||||
addClickListener( searchButton, "search-in-files" );
|
||||
addClickListener( searchBarClose, "close-global-searchbar" );
|
||||
mGlobalSearchTree = UITreeViewGlobalSearch::New( mEditorSplitter->getCurrentColorScheme() );
|
||||
mGlobalSearchTree =
|
||||
UITreeViewGlobalSearch::New( mEditorSplitter->getCurrentColorScheme(), false );
|
||||
mGlobalSearchTree->setId( "search_tree" );
|
||||
mGlobalSearchTree->setParent( mUISceneNode->getRoot() );
|
||||
mGlobalSearchTree->setExpanderIconSize( PixelDensity::dpToPx( 20 ) );
|
||||
@@ -1971,8 +1972,10 @@ bool App::setAutoComplete( bool enable ) {
|
||||
bool App::setLinter( bool enable ) {
|
||||
mConfig.editor.linter = enable;
|
||||
if ( enable && !mLinterModule ) {
|
||||
mLinterModule =
|
||||
eeNew( LinterModule, ( mResPath + "assets/linters/linters.json", mThreadPool ) );
|
||||
std::string path( mResPath + "assets/linters/linters.json" );
|
||||
if ( FileSystem::fileExists( mConfigPath + "linters.json" ) )
|
||||
path = mConfigPath + "linters.json";
|
||||
mLinterModule = eeNew( LinterModule, ( path, mThreadPool ) );
|
||||
mEditorSplitter->forEachEditor(
|
||||
[&]( UICodeEditor* editor ) { editor->registerModule( mLinterModule ); } );
|
||||
return true;
|
||||
@@ -2234,9 +2237,14 @@ void App::initProjectTreeView( const std::string& path ) {
|
||||
} else {
|
||||
std::string rpath( FileSystem::getRealPath( path ) );
|
||||
|
||||
mProjectTreeView->setModel( FileSystemModel::New(
|
||||
FileSystem::fileRemoveFileName( rpath ), FileSystemModel::Mode::FilesAndDirectories,
|
||||
{ true, true, true } ) );
|
||||
mFileSystemModel = FileSystemModel::New( FileSystem::fileRemoveFileName( rpath ),
|
||||
FileSystemModel::Mode::FilesAndDirectories,
|
||||
{ true, true, true } );
|
||||
|
||||
mProjectTreeView->setModel( mFileSystemModel );
|
||||
|
||||
if ( mFileSystemListener )
|
||||
mFileSystemListener->setFileSystemModel( mFileSystemModel );
|
||||
|
||||
mEditorSplitter->loadFileFromPath( rpath );
|
||||
}
|
||||
@@ -2257,8 +2265,13 @@ void App::loadFolder( const std::string& path ) {
|
||||
|
||||
mConfig.loadProject( rpath, mEditorSplitter, mConfigPath );
|
||||
|
||||
mProjectTreeView->setModel( FileSystemModel::New(
|
||||
rpath, FileSystemModel::Mode::FilesAndDirectories, { true, true, true } ) );
|
||||
mFileSystemModel = FileSystemModel::New( rpath, FileSystemModel::Mode::FilesAndDirectories,
|
||||
{ true, true, true } );
|
||||
|
||||
mProjectTreeView->setModel( mFileSystemModel );
|
||||
|
||||
if ( mFileSystemListener )
|
||||
mFileSystemListener->setFileSystemModel( mFileSystemModel );
|
||||
|
||||
auto found = std::find( mRecentFolders.begin(), mRecentFolders.end(), rpath );
|
||||
if ( found != mRecentFolders.end() )
|
||||
@@ -2592,7 +2605,7 @@ void App::init( const std::string& file, const Float& pidelDensity ) {
|
||||
|
||||
#if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN
|
||||
mFileWatcher = new efsw::FileWatcher();
|
||||
mFileSystemListener = new FileSystemListener( mEditorSplitter );
|
||||
mFileSystemListener = new FileSystemListener( mEditorSplitter, mFileSystemModel );
|
||||
mFileWatcher->watch();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -188,6 +188,7 @@ class App : public UICodeEditorSplitter::Client {
|
||||
std::shared_ptr<ThreadPool> mThreadPool;
|
||||
std::unique_ptr<ProjectDirectoryTree> mDirTree;
|
||||
UITreeView* mProjectTreeView{ nullptr };
|
||||
std::shared_ptr<FileSystemModel> mFileSystemModel;
|
||||
UITableView* mLocateTable{ nullptr };
|
||||
UITextInput* mLocateInput{ nullptr };
|
||||
UITreeViewGlobalSearch* mGlobalSearchTree{ nullptr };
|
||||
|
||||
@@ -1,16 +1,30 @@
|
||||
#include "filesystemlistener.hpp"
|
||||
|
||||
FileSystemListener::FileSystemListener( UICodeEditorSplitter* splitter ) : mSplitter( splitter ) {}
|
||||
FileSystemListener::FileSystemListener( UICodeEditorSplitter* splitter,
|
||||
std::shared_ptr<FileSystemModel> fileSystemModel ) :
|
||||
mSplitter( splitter ), mFileSystemModel( fileSystemModel ) {}
|
||||
|
||||
void FileSystemListener::handleFileAction( efsw::WatchID, const std::string& dir,
|
||||
const std::string& filename, efsw::Action action,
|
||||
std::string ) {
|
||||
if ( action == efsw::Actions::Modified ) {
|
||||
FileInfo file( dir + filename );
|
||||
if ( file.isLink() )
|
||||
file = FileInfo( file.linksTo() );
|
||||
if ( isFileOpen( file ) )
|
||||
notifyChange( file );
|
||||
FileInfo file( dir + filename );
|
||||
|
||||
switch ( action ) {
|
||||
case efsw::Actions::Add:
|
||||
case efsw::Actions::Delete:
|
||||
case efsw::Actions::Moved: {
|
||||
auto* node = mFileSystemModel.get()->getNodeFromPath( file.getFilepath(), true, false );
|
||||
if ( node ) {
|
||||
node->invalidate();
|
||||
mFileSystemModel.get()->invalidate();
|
||||
}
|
||||
}
|
||||
case efsw::Actions::Modified: {
|
||||
if ( file.isLink() )
|
||||
file = FileInfo( file.linksTo() );
|
||||
if ( isFileOpen( file ) )
|
||||
notifyChange( file );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,25 +2,31 @@
|
||||
#define FILESYSTEMLISTENER_HPP
|
||||
|
||||
#include <eepp/system/fileinfo.hpp>
|
||||
#include <eepp/ui/models/filesystemmodel.hpp>
|
||||
#include <eepp/ui/tools/uicodeeditorsplitter.hpp>
|
||||
#include <eepp/ui/uicodeeditor.hpp>
|
||||
#include <efsw/efsw.hpp>
|
||||
|
||||
using namespace EE::System;
|
||||
using namespace EE::UI;
|
||||
using namespace EE::UI::Models;
|
||||
using namespace EE::UI::Tools;
|
||||
|
||||
class FileSystemListener : public efsw::FileWatchListener {
|
||||
public:
|
||||
FileSystemListener( UICodeEditorSplitter* codeSplitter );
|
||||
FileSystemListener( UICodeEditorSplitter* codeSplitter,
|
||||
std::shared_ptr<FileSystemModel> fileSystemModel );
|
||||
|
||||
virtual ~FileSystemListener() {}
|
||||
|
||||
void handleFileAction( efsw::WatchID, const std::string& dir, const std::string& filename,
|
||||
efsw::Action action, std::string );
|
||||
|
||||
void setFileSystemModel( std::shared_ptr<FileSystemModel> model ) { mFileSystemModel = model; }
|
||||
|
||||
protected:
|
||||
UICodeEditorSplitter* mSplitter;
|
||||
std::shared_ptr<FileSystemModel> mFileSystemModel;
|
||||
|
||||
bool isFileOpen( const FileInfo& file );
|
||||
|
||||
|
||||
@@ -50,7 +50,15 @@ void LinterModule::load( const std::string& lintersPath ) {
|
||||
for ( auto& pattern : fp )
|
||||
linter.files.push_back( pattern.get<std::string>() );
|
||||
|
||||
linter.warningPattern = obj["warning_pattern"].get<std::string>();
|
||||
auto wp = obj["warning_pattern"];
|
||||
|
||||
if ( wp.is_array() ) {
|
||||
for ( auto& warningPattern : wp )
|
||||
linter.warningPattern.push_back( warningPattern.get<std::string>() );
|
||||
} else {
|
||||
linter.warningPattern = { wp.get<std::string>() };
|
||||
}
|
||||
|
||||
linter.command = obj["command"].get<std::string>();
|
||||
|
||||
if ( obj.contains( "warning_pattern_order" ) ) {
|
||||
@@ -65,6 +73,9 @@ void LinterModule::load( const std::string& lintersPath ) {
|
||||
linter.warningPatternOrder.type = wpo["type"].get<int>();
|
||||
}
|
||||
|
||||
if ( obj.contains( "column_starts_at_zero" ) )
|
||||
linter.columnsStartAtZero = obj["column_starts_at_zero"].get<bool>();
|
||||
|
||||
mLinters.emplace_back( std::move( linter ) );
|
||||
}
|
||||
|
||||
@@ -220,35 +231,41 @@ void LinterModule::runLinter( TextDocument* doc, const Linter& linter, const std
|
||||
|
||||
// Log::info( "Linter result:\n%s", data.c_str() );
|
||||
|
||||
LuaPattern pattern( linter.warningPattern );
|
||||
std::map<Int64, LinterMatch> matches;
|
||||
for ( auto& match : pattern.gmatch( data ) ) {
|
||||
LinterMatch linterMatch;
|
||||
std::string lineStr = match.group( linter.warningPatternOrder.line );
|
||||
std::string colStr = linter.warningPatternOrder.col >= 0
|
||||
? match.group( linter.warningPatternOrder.col )
|
||||
: "";
|
||||
linterMatch.text = match.group( linter.warningPatternOrder.message );
|
||||
|
||||
if ( linter.warningPatternOrder.type >= 0 ) {
|
||||
std::string type( match.group( linter.warningPatternOrder.type ) );
|
||||
String::toLowerInPlace( type );
|
||||
if ( String::startsWith( type, "warn" ) ) {
|
||||
linterMatch.type = LinterType::Warning;
|
||||
} else if ( String::startsWith( type, "notice" ) ) {
|
||||
linterMatch.type = LinterType::Notice;
|
||||
for ( auto& warningPatterm : linter.warningPattern ) {
|
||||
LuaPattern pattern( warningPatterm );
|
||||
for ( auto& match : pattern.gmatch( data ) ) {
|
||||
LinterMatch linterMatch;
|
||||
std::string lineStr = match.group( linter.warningPatternOrder.line );
|
||||
std::string colStr = linter.warningPatternOrder.col >= 0
|
||||
? match.group( linter.warningPatternOrder.col )
|
||||
: "";
|
||||
linterMatch.text = match.group( linter.warningPatternOrder.message );
|
||||
|
||||
if ( linter.warningPatternOrder.type >= 0 ) {
|
||||
std::string type( match.group( linter.warningPatternOrder.type ) );
|
||||
String::toLowerInPlace( type );
|
||||
if ( String::startsWith( type, "warn" ) ) {
|
||||
linterMatch.type = LinterType::Warning;
|
||||
} else if ( String::startsWith( type, "notice" ) ) {
|
||||
linterMatch.type = LinterType::Notice;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Int64 line;
|
||||
Int64 col = 1;
|
||||
if ( !linterMatch.text.empty() && !lineStr.empty() &&
|
||||
String::fromString( line, lineStr ) ) {
|
||||
if ( !colStr.empty() )
|
||||
String::fromString( col, colStr );
|
||||
linterMatch.pos = { line - 1, col > 0 ? col - 1 : 0 };
|
||||
linterMatch.lineCache = doc->line( line - 1 ).getHash();
|
||||
matches.insert( { line - 1, std::move( linterMatch ) } );
|
||||
Int64 line;
|
||||
Int64 col = 1;
|
||||
if ( !linterMatch.text.empty() && !lineStr.empty() &&
|
||||
String::fromString( line, lineStr ) ) {
|
||||
if ( !colStr.empty() ) {
|
||||
String::fromString( col, colStr );
|
||||
if ( linter.columnsStartAtZero )
|
||||
col++;
|
||||
}
|
||||
linterMatch.pos = { line - 1, col > 0 ? col - 1 : 0 };
|
||||
linterMatch.lineCache = doc->line( line - 1 ).getHash();
|
||||
matches.insert( { line - 1, std::move( linterMatch ) } );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,15 +10,12 @@ using namespace EE;
|
||||
using namespace EE::System;
|
||||
using namespace EE::UI;
|
||||
|
||||
enum class LinterType {
|
||||
Notice,
|
||||
Warning,
|
||||
Error
|
||||
};
|
||||
enum class LinterType { Notice, Warning, Error };
|
||||
|
||||
struct Linter {
|
||||
std::vector<std::string> files;
|
||||
std::string warningPattern;
|
||||
std::vector<std::string> warningPattern;
|
||||
bool columnsStartAtZero{ false };
|
||||
struct {
|
||||
int line{ 1 };
|
||||
int col{ 2 };
|
||||
@@ -87,7 +84,6 @@ class LinterModule : public UICodeEditorModule {
|
||||
void setDocDirty( UICodeEditor* editor );
|
||||
|
||||
void invalidateEditors( TextDocument* doc );
|
||||
|
||||
};
|
||||
|
||||
#endif // EE_TOOLS_LINTER_HPP
|
||||
|
||||
@@ -21,9 +21,33 @@ class ProjectSearch {
|
||||
Result( const String& line, const TextRange& pos ) : line( line ), position( pos ) {}
|
||||
String line;
|
||||
TextRange position;
|
||||
bool selected{ false };
|
||||
};
|
||||
std::string file;
|
||||
std::vector<Result> results;
|
||||
bool selected{ false };
|
||||
|
||||
void setResultsSelected( bool selected ) {
|
||||
this->selected = selected;
|
||||
for ( auto& res : results )
|
||||
res.selected = selected;
|
||||
}
|
||||
|
||||
bool allResultsSelected() {
|
||||
for ( const auto& res : results ) {
|
||||
if ( !res.selected )
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool noneResultsSelected() {
|
||||
for ( const auto& res : results ) {
|
||||
if ( res.selected )
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<ResultData> Result;
|
||||
@@ -31,7 +55,7 @@ class ProjectSearch {
|
||||
|
||||
class ResultModel : public Model {
|
||||
public:
|
||||
enum Column { FileOrPosition, Line, LineEnd, ColumnStart, ColumnEnd };
|
||||
enum Column { FileOrPosition, Line, LineEnd, ColumnStart, ColumnEnd, Selected, Data };
|
||||
|
||||
ResultModel( const Result& result ) : mResult( result ) {}
|
||||
|
||||
@@ -114,11 +138,19 @@ class ProjectSearch {
|
||||
.results[index.row()]
|
||||
.position.end()
|
||||
.column() );
|
||||
case Selected:
|
||||
return Variant(
|
||||
mResult[index.internalId()].results[index.row()].selected );
|
||||
case Data:
|
||||
return Variant(
|
||||
(void*)&mResult[index.internalId()].results[index.row()] );
|
||||
}
|
||||
} else {
|
||||
switch ( index.column() ) {
|
||||
case FileOrPosition:
|
||||
return Variant( mResult[index.row()].file.c_str() );
|
||||
case Data:
|
||||
return Variant( (void*)&mResult[index.row()] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,94 @@
|
||||
#include "uitreeviewglobalsearch.hpp"
|
||||
#include "projectsearch.hpp"
|
||||
#include <eepp/graphics/primitives.hpp>
|
||||
#include <eepp/ui/doc/syntaxdefinitionmanager.hpp>
|
||||
#include <eepp/ui/doc/syntaxtokenizer.hpp>
|
||||
#include <eepp/ui/uicheckbox.hpp>
|
||||
#include <eepp/ui/uiscenenode.hpp>
|
||||
#include <eepp/ui/uistyle.hpp>
|
||||
|
||||
UITreeViewGlobalSearch::UITreeViewGlobalSearch( const SyntaxColorScheme& colorScheme ) :
|
||||
UITreeView(), mColorScheme( colorScheme ) {
|
||||
UITreeViewGlobalSearch::UITreeViewGlobalSearch( const SyntaxColorScheme& colorScheme,
|
||||
bool searchReplace ) :
|
||||
UITreeView(), mColorScheme( colorScheme ), mSearchReplace( searchReplace ) {
|
||||
mLineNumColor = Color::fromString(
|
||||
mUISceneNode->getRoot()->getUIStyle()->getVariable( "--font-hint" ).getValue() );
|
||||
}
|
||||
|
||||
UIWidget* UITreeViewGlobalSearch::createCell( UIWidget* rowWidget, const ModelIndex& index ) {
|
||||
UITableCell* widget = index.column() == (Int64)getModel()->treeColumn()
|
||||
? UITreeViewCellGlobalSearch::New()
|
||||
? UITreeViewCellGlobalSearch::New( mSearchReplace )
|
||||
: UITableCell::New();
|
||||
return setupCell( widget, rowWidget, index );
|
||||
}
|
||||
|
||||
std::function<UITextView*()> UITreeViewCellGlobalSearch::getCheckBoxFn() {
|
||||
return [&]() -> UITextView* {
|
||||
UICheckBox* chk = UICheckBox::New();
|
||||
|
||||
addEventListener( Event::MouseClick, [&, chk]( const Event* event ) {
|
||||
const MouseEvent* mouseEvent = static_cast<const MouseEvent*>( event );
|
||||
|
||||
Vector2f pos = convertToNodeSpace( mouseEvent->getPosition().asFloat() );
|
||||
Rectf box( { convertToNodeSpace( chk->getCurrentButton()->convertToWorldSpace(
|
||||
chk->getCurrentButton()->getPixelsPosition() ) ),
|
||||
chk->getCurrentButton()->getPixelsSize() } );
|
||||
|
||||
if ( box.contains( pos ) ) {
|
||||
if ( getCurIndex().internalId() != -1 ) {
|
||||
ProjectSearch::ResultData::Result* result = getResultPtr();
|
||||
if ( result ) {
|
||||
result->selected = !result->selected;
|
||||
chk->setChecked( result->selected );
|
||||
|
||||
ProjectSearch::ResultData* parentData =
|
||||
(ProjectSearch::ResultData*)getDataPtr( getCurIndex().parent() );
|
||||
if ( parentData )
|
||||
parentData->selected = parentData->allResultsSelected();
|
||||
}
|
||||
} else {
|
||||
auto* result = getResultDataPtr();
|
||||
result->setResultsSelected( !result->selected );
|
||||
chk->setChecked( result->selected );
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
} );
|
||||
return chk;
|
||||
};
|
||||
}
|
||||
|
||||
void* UITreeViewCellGlobalSearch::getDataPtr( const ModelIndex& modelIndex ) {
|
||||
const ProjectSearch::ResultModel* model =
|
||||
static_cast<const ProjectSearch::ResultModel*>( modelIndex.model() );
|
||||
ModelIndex index =
|
||||
model->index( modelIndex.row(), ProjectSearch::ResultModel::Data, modelIndex.parent() );
|
||||
Variant var( model->data( index, Model::Role::Custom ) );
|
||||
if ( var.is( Variant::Type::DataPtr ) )
|
||||
return var.asDataPtr();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ProjectSearch::ResultData::Result* UITreeViewCellGlobalSearch::getResultPtr() {
|
||||
if ( getCurIndex().internalId() == -1 )
|
||||
return nullptr;
|
||||
void* ptr = getDataPtr( getCurIndex() );
|
||||
if ( ptr )
|
||||
return (ProjectSearch::ResultData::Result*)ptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ProjectSearch::ResultData* UITreeViewCellGlobalSearch::getResultDataPtr() {
|
||||
if ( getCurIndex().internalId() != -1 )
|
||||
return nullptr;
|
||||
void* ptr = getDataPtr( getCurIndex() );
|
||||
if ( ptr )
|
||||
return (ProjectSearch::ResultData*)ptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UITreeViewCellGlobalSearch::UITreeViewCellGlobalSearch( bool selectionEnabled ) :
|
||||
UITreeViewCell( selectionEnabled ? getCheckBoxFn() : nullptr ) {}
|
||||
|
||||
UIPushButton* UITreeViewCellGlobalSearch::setText( const String& text ) {
|
||||
if ( text != mTextBox->getText() ) {
|
||||
mTextBox->setVisible( !text.empty() );
|
||||
@@ -107,13 +178,30 @@ void UITreeViewCellGlobalSearch::draw() {
|
||||
mTextBox->getFont()->getGlyph( L' ', mTextBox->getPixelsFontSize(), false ).advance;
|
||||
Primitives p;
|
||||
p.setColor( pp->getColorScheme().getEditorSyntaxStyle( "selection" ).color );
|
||||
Vector2f screenPos( mScreenPos );
|
||||
if ( mTextBox->isType( UI_TYPE_CHECKBOX ) ) {
|
||||
UICheckBox* chk = mTextBox->asType<UICheckBox>();
|
||||
screenPos.x += chk->getRealAlignOffset().x;
|
||||
}
|
||||
p.drawRectangle( Rectf(
|
||||
{ mScreenPos.x + mTextBox->getPixelsPosition().x +
|
||||
{ screenPos.x + mTextBox->getPixelsPosition().x +
|
||||
getXOffsetCol( hspace, mTextBox->getTextCache()->getTabWidth(),
|
||||
mTextBox->getText(), mSearchStrPos.first ),
|
||||
mScreenPos.y + mTextBox->getPixelsPosition().y },
|
||||
screenPos.y + mTextBox->getPixelsPosition().y },
|
||||
Sizef( getTextWidth( hspace, mTextBox->getTextCache()->getTabWidth(), mResultStr ),
|
||||
mTextBox->getPixelsSize().getHeight() ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UITreeViewCellGlobalSearch::updateCell( Model* ) {
|
||||
if ( mTextBox->isType( UI_TYPE_CHECKBOX ) ) {
|
||||
UICheckBox* chk = mTextBox->asType<UICheckBox>();
|
||||
auto* result = getResultPtr();
|
||||
if ( result ) {
|
||||
chk->setChecked( result->selected );
|
||||
} else if ( auto* dataResult = getResultDataPtr() ) {
|
||||
chk->setChecked( dataResult->selected );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,11 @@ using namespace EE::UI::Doc;
|
||||
|
||||
class UITreeViewCellGlobalSearch : public UITreeViewCell {
|
||||
public:
|
||||
static UITreeViewCellGlobalSearch* New() { return eeNew( UITreeViewCellGlobalSearch, () ); }
|
||||
static UITreeViewCellGlobalSearch* New( bool selectionEnabled ) {
|
||||
return eeNew( UITreeViewCellGlobalSearch, ( selectionEnabled ) );
|
||||
}
|
||||
|
||||
UITreeViewCellGlobalSearch() : UITreeViewCell() {}
|
||||
UITreeViewCellGlobalSearch( bool selectionEnabled );
|
||||
|
||||
UIPushButton* setText( const String& text );
|
||||
|
||||
@@ -20,18 +22,28 @@ class UITreeViewCellGlobalSearch : public UITreeViewCell {
|
||||
|
||||
virtual void draw();
|
||||
|
||||
virtual void updateCell( Model* model );
|
||||
|
||||
protected:
|
||||
std::pair<size_t, size_t> mSearchStrPos;
|
||||
String mResultStr;
|
||||
|
||||
std::function<UITextView*()> getCheckBoxFn();
|
||||
|
||||
void* getDataPtr( const ModelIndex& modelIndex );
|
||||
|
||||
ProjectSearch::ResultData::Result* getResultPtr();
|
||||
|
||||
ProjectSearch::ResultData* getResultDataPtr();
|
||||
};
|
||||
|
||||
class UITreeViewGlobalSearch : public UITreeView {
|
||||
public:
|
||||
static UITreeViewGlobalSearch* New( const SyntaxColorScheme& colorScheme ) {
|
||||
return eeNew( UITreeViewGlobalSearch, ( colorScheme ) );
|
||||
static UITreeViewGlobalSearch* New( const SyntaxColorScheme& colorScheme, bool searchReplace ) {
|
||||
return eeNew( UITreeViewGlobalSearch, ( colorScheme, searchReplace ) );
|
||||
}
|
||||
|
||||
UITreeViewGlobalSearch( const SyntaxColorScheme& colorScheme );
|
||||
UITreeViewGlobalSearch( const SyntaxColorScheme& colorScheme, bool searchReplace );
|
||||
|
||||
UIWidget* createCell( UIWidget* rowWidget, const ModelIndex& index );
|
||||
|
||||
@@ -49,6 +61,7 @@ class UITreeViewGlobalSearch : public UITreeView {
|
||||
Color mLineNumColor;
|
||||
SyntaxColorScheme mColorScheme;
|
||||
String mSearchStr;
|
||||
bool mSearchReplace{ false };
|
||||
};
|
||||
|
||||
#endif // UITREEVIEWGLOBALSEARCH_HPP
|
||||
|
||||
Reference in New Issue
Block a user