mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-07-14 23:12:49 +03:00
Added Variant "String" support.
Added panel location configuration (left or right). Added default key modifier (CTRL on Linux and windows, META on macOS, ALT on Haiku). Optimized GlobalSearchController. Allow using $FILENAME in linter warning pattern. Optimized ProjectSearch. Added TextDocument delete on close option (default for temporal files downloaded from the Internet).
This commit is contained in:
2
TODO.md
2
TODO.md
@@ -15,8 +15,6 @@ Detect errors and log them.
|
||||
|
||||
## TextDocument
|
||||
|
||||
* Add multi-line search and replace.
|
||||
|
||||
* Add XML tags auto-close.
|
||||
|
||||
## ecode - Code Editor
|
||||
|
||||
@@ -1,48 +1,48 @@
|
||||
[
|
||||
{
|
||||
"file_patterns": ["%.php$"],
|
||||
"warning_pattern": "[%a ]+:%s+(.*)%s+in%s.*on%sline%s+(%d+)",
|
||||
"warning_pattern_order": { "line": 2, "col": 0, "message": 1 },
|
||||
"command": "php -l $FILENAME"
|
||||
"file_patterns": ["%.php$"],
|
||||
"warning_pattern": "[%a ]+:%s+(.*)%s+in%s.*on%sline%s+(%d+)",
|
||||
"warning_pattern_order": { "line": 2, "col": 0, "message": 1 },
|
||||
"command": "php -l $FILENAME"
|
||||
},
|
||||
{
|
||||
"file_patterns": ["%.js$", "%.ts$"],
|
||||
"warning_pattern": "[^:]:(%d+):(%d+): ([^%[]+)%[([^\n]+)",
|
||||
"warning_pattern_order": { "line": 1, "col": 2, "message": 3, "type": 4 },
|
||||
"command": "eslint --no-ignore --format unix $FILENAME"
|
||||
"file_patterns": ["%.js$", "%.ts$"],
|
||||
"warning_pattern": "[^:]:(%d+):(%d+): ([^%[]+)%[([^\n]+)",
|
||||
"warning_pattern_order": { "line": 1, "col": 2, "message": 3, "type": 4 },
|
||||
"command": "eslint --no-ignore --format unix $FILENAME"
|
||||
},
|
||||
{
|
||||
"file_patterns": ["%.lua$"],
|
||||
"warning_pattern": "[^:]:(%d+):(%d+):[%s]?([^\n]+)",
|
||||
"command": "luacheck $FILENAME --formatter=plain -g --no-max-line-length"
|
||||
"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([^\n]+)",
|
||||
"command": "pycodestyle --ignore=E402 $FILENAME"
|
||||
"file_patterns": ["%.py$"],
|
||||
"warning_pattern": "[^:]:(%d+):(%d+):%s([^\n]+)",
|
||||
"command": "pycodestyle --ignore=E402 $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"
|
||||
"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"
|
||||
},
|
||||
{
|
||||
"file_patterns": ["%.sol$"],
|
||||
"warning_pattern": "(%d+):(%d+)%s.(%w*)%s.([^\n]*)",
|
||||
"warning_pattern_order": { "line": 1, "col": 2, "message": 4, "type": 3 },
|
||||
"command": "solhint $FILENAME"
|
||||
"file_patterns": ["%.sol$"],
|
||||
"warning_pattern": "(%d+):(%d+)%s.(%w*)%s.([^\n]*)",
|
||||
"warning_pattern_order": { "line": 1, "col": 2, "message": 4, "type": 3 },
|
||||
"command": "solhint $FILENAME"
|
||||
},
|
||||
{
|
||||
"file_patterns": ["%.cpp$", "%.hpp$", "%.cxx$", "%.hxx$"],
|
||||
"warning_pattern": "[^:]:(%d+):(%d+):%s?([^%s]*)([^\n]*)",
|
||||
"warning_pattern_order": { "line": 1, "col": 2, "message": 4, "type": 3 },
|
||||
"command": "cppcheck --language=c++ --enable=all --template=gcc $FILENAME"
|
||||
"file_patterns": ["%.cpp$", "%.hpp$", "%.cxx$", "%.hxx$"],
|
||||
"warning_pattern": "$FILENAME:(%d+):(%d+):%s?([^%s]*)([^\n]*)",
|
||||
"warning_pattern_order": { "line": 1, "col": 2, "message": 4, "type": 3 },
|
||||
"command": "cppcheck --language=c++ --enable=all --template=gcc $FILENAME"
|
||||
},
|
||||
{
|
||||
"file_patterns": ["%.kt$"],
|
||||
"warning_pattern": "[^:]:(%d+):(%d+):%s([^\n]+)",
|
||||
"warning_pattern_order": { "line": 1, "col": 2, "message": 3, "type": 4 },
|
||||
"command": "ktlint $FILENAME"
|
||||
"file_patterns": ["%.kt$"],
|
||||
"warning_pattern": "[^:]:(%d+):(%d+):%s([^\n]+)",
|
||||
"warning_pattern_order": { "line": 1, "col": 2, "message": 3, "type": 4 },
|
||||
"command": "ktlint $FILENAME"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -398,6 +398,10 @@ class EE_API TextDocument {
|
||||
|
||||
bool isLoading() const;
|
||||
|
||||
bool isDeleteOnClose() const;
|
||||
|
||||
void setDeleteOnClose( bool deleteOnClose );
|
||||
|
||||
protected:
|
||||
friend class UndoStack;
|
||||
UndoStack mUndoStack;
|
||||
@@ -416,6 +420,7 @@ class EE_API TextDocument {
|
||||
bool mAutoCloseBrackets{ false };
|
||||
bool mDirtyOnFileSystem{ false };
|
||||
bool mSaving{ false };
|
||||
bool mDeleteOnClose{ false };
|
||||
std::vector<std::pair<String::StringBaseType, String::StringBaseType>> mAutoCloseBracketsPairs;
|
||||
Uint32 mIndentWidth{ 4 };
|
||||
IndentType mIndentType{ IndentType::IndentTabs };
|
||||
|
||||
@@ -24,9 +24,9 @@ class EE_API KeyBindings {
|
||||
Shortcut() {}
|
||||
Shortcut( Keycode key, Uint32 mod ) : key( key ), mod( mod ) {}
|
||||
Shortcut( const Uint64& code ) :
|
||||
key( ( Keycode )( code & 0xFFFFFFFF ) ), mod( ( code >> 32 ) & 0xFFFFFFFF ) {}
|
||||
Keycode key{KEY_UNKNOWN};
|
||||
Uint32 mod{0};
|
||||
key( (Keycode)( code & 0xFFFFFFFF ) ), mod( ( code >> 32 ) & 0xFFFFFFFF ) {}
|
||||
Keycode key{ KEY_UNKNOWN };
|
||||
Uint32 mod{ 0 };
|
||||
Uint64 toUint64() const { return (Uint64)mod << 32 | (Uint64)key; }
|
||||
operator Uint64() const { return toUint64(); }
|
||||
bool empty() const { return 0 == mod && 0 == key; }
|
||||
@@ -66,6 +66,10 @@ class EE_API KeyBindings {
|
||||
|
||||
std::string getShortcutString( Shortcut shortcut );
|
||||
|
||||
Uint32 getDefaultModifier() const;
|
||||
|
||||
void setDefaultModifier( Uint32 newDefaultModifier );
|
||||
|
||||
protected:
|
||||
const Window::Input* mInput;
|
||||
ShortcutMap mShortcuts;
|
||||
|
||||
@@ -19,6 +19,7 @@ class EE_API Variant {
|
||||
Invalid,
|
||||
DataPtr,
|
||||
String,
|
||||
StdString,
|
||||
Bool,
|
||||
Float,
|
||||
Int,
|
||||
@@ -32,8 +33,11 @@ class EE_API Variant {
|
||||
cstr
|
||||
};
|
||||
Variant() : mType( Type::Invalid ) {}
|
||||
explicit Variant( const std::string& string ) : mType( Type::String ) {
|
||||
mValue.asString = eeNew( std::string, ( string ) );
|
||||
explicit Variant( const std::string& string ) : mType( Type::StdString ) {
|
||||
mValue.asStdString = eeNew( std::string, ( string ) );
|
||||
}
|
||||
explicit Variant( const String& string ) : mType( Type::String ) {
|
||||
mValue.asString = eeNew( String, ( string ) );
|
||||
}
|
||||
Variant( Drawable* drawable, bool ownDrawable = false ) : mType( Type::Drawable ) {
|
||||
mValue.asDrawable = drawable;
|
||||
@@ -53,7 +57,8 @@ class EE_API Variant {
|
||||
Variant( const Uint64& val ) : mType( Type::Uint64 ) { mValue.asUint64 = val; }
|
||||
explicit Variant( const char* data ) : mType( Type::cstr ) { mValue.asCStr = data; }
|
||||
~Variant() { reset(); }
|
||||
const std::string& asString() const { return *mValue.asString; }
|
||||
const std::string& asStdString() const { return *mValue.asStdString; }
|
||||
const String& asString() const { return *mValue.asString; }
|
||||
Drawable* asDrawable() const { return mValue.asDrawable; }
|
||||
const bool& asBool() const { return mValue.asBool; }
|
||||
const Float& asFloat() const { return mValue.asFloat; }
|
||||
@@ -69,8 +74,11 @@ class EE_API Variant {
|
||||
bool is( const Type& type ) const { return type == mType; }
|
||||
void reset() {
|
||||
switch ( mType ) {
|
||||
case Type::StdString:
|
||||
eeSAFE_DELETE( mValue.asStdString );
|
||||
break;
|
||||
case Type::String:
|
||||
eeSAFE_DELETE( mValue.asString );
|
||||
eeSAFE_DELETE( mValue.asStdString );
|
||||
break;
|
||||
case Type::Drawable:
|
||||
if ( mOwnsObject )
|
||||
@@ -103,6 +111,8 @@ class EE_API Variant {
|
||||
return String::toString( asUint64() );
|
||||
case Type::Float:
|
||||
return String::toString( asFloat() );
|
||||
case Type::StdString:
|
||||
return asStdString();
|
||||
case Type::String:
|
||||
return asString();
|
||||
case Type::Drawable:
|
||||
@@ -142,6 +152,8 @@ class EE_API Variant {
|
||||
return asUint64() < other.asUint64();
|
||||
case Type::Float:
|
||||
return asFloat() < other.asFloat();
|
||||
case Type::StdString:
|
||||
return asStdString() < other.asStdString();
|
||||
case Type::String:
|
||||
return asString() < other.asString();
|
||||
case Type::Drawable:
|
||||
@@ -178,6 +190,8 @@ class EE_API Variant {
|
||||
return asUint64() == other.asUint64();
|
||||
case Type::Float:
|
||||
return asFloat() == other.asFloat();
|
||||
case Type::StdString:
|
||||
return asStdString() == other.asStdString();
|
||||
case Type::String:
|
||||
return asString() == other.asString();
|
||||
case Type::Drawable:
|
||||
@@ -203,7 +217,8 @@ class EE_API Variant {
|
||||
void* asDataPtr;
|
||||
Drawable* asDrawable;
|
||||
UIIcon* asIcon;
|
||||
std::string* asString;
|
||||
std::string* asStdString;
|
||||
String* asString;
|
||||
bool asBool;
|
||||
Float asFloat;
|
||||
int asInt;
|
||||
@@ -215,7 +230,7 @@ class EE_API Variant {
|
||||
const char* asCStr;
|
||||
} mValue;
|
||||
Type mType;
|
||||
bool mOwnsObject{false};
|
||||
bool mOwnsObject{ false };
|
||||
};
|
||||
|
||||
}}} // namespace EE::UI::Models
|
||||
|
||||
@@ -135,7 +135,7 @@ class EE_API UIFileDialog : public UIWindow {
|
||||
UIDropDownList* mFiletype;
|
||||
Uint32 mDialogFlags;
|
||||
KeyBindings::Shortcut mCloseShortcut;
|
||||
KeyBindings::Shortcut mOpenShortut{ KEY_RETURN, KEYMOD_CTRL };
|
||||
KeyBindings::Shortcut mOpenShortut{ KEY_RETURN, KEYMOD_DEFAULT_MODIFIER };
|
||||
std::shared_ptr<FileSystemModel> mModel;
|
||||
|
||||
virtual void onWindowReady();
|
||||
|
||||
@@ -27,7 +27,7 @@ class EE_API UISplitter : public UILayout {
|
||||
|
||||
void setSplitPartition( const StyleSheetLength& divisionSplit );
|
||||
|
||||
void swap();
|
||||
void swap( bool swapSplitPartition = false );
|
||||
|
||||
bool isEmpty();
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef EE_INPUT_KEYKODES_HPP
|
||||
#define EE_INPUT_KEYKODES_HPP
|
||||
|
||||
#include <eepp/config.hpp>
|
||||
|
||||
namespace EE { namespace Window {
|
||||
|
||||
// This is a exact copy from the SDL_keycode and SDL_scancode.
|
||||
@@ -685,6 +687,14 @@ enum KeyModTable {
|
||||
#define KEYMOD_META ( KEYMOD_LMETA | KEYMOD_RMETA )
|
||||
#define KEYMOD_CTRL_SHIFT_ALT_META ( KEYMOD_CTRL | KEYMOD_SHIFT | KEYMOD_ALT | KEYMOD_META )
|
||||
|
||||
#if EE_PLATFORM == EE_PLATFORM_MACOSX
|
||||
#define KEYMOD_DEFAULT_MODIFIER KEYMOD_META
|
||||
#elif EE_PLATFORM == EE_PLATFORM_HAIKU
|
||||
#define KEYMOD_DEFAULT_MODIFIER KEYMOD_ALT
|
||||
#else
|
||||
#define KEYMOD_DEFAULT_MODIFIER KEYMOD_CTRL
|
||||
#endif
|
||||
|
||||
/** @enum MouseButton Mouse buttons */
|
||||
enum MouseButton {
|
||||
EE_BUTTON_LEFT = 1,
|
||||
|
||||
@@ -158,9 +158,10 @@ void MapEditor::createMenuBar() {
|
||||
PU3->getUISceneNode()->findIconDrawable( "zoom-out", PixelDensity::dpToPxI( 16 ) ) );
|
||||
PU3->add( "Normal Size", PU3->getUISceneNode()->findIconDrawable(
|
||||
"zoom-original", PixelDensity::dpToPxI( 16 ) ) );
|
||||
addShortcut( {KEY_KP_PLUS, KEYMOD_CTRL}, "zoom-in", [&] { zoomIn(); } );
|
||||
addShortcut( {KEY_KP_MINUS, KEYMOD_CTRL}, "zoom-out", [&] { zoomOut(); } );
|
||||
addShortcut( {KEY_0, KEYMOD_CTRL}, "zoom-reset", [&] { mUIMap->Map()->setScale( 1 ); } );
|
||||
addShortcut( { KEY_KP_PLUS, KEYMOD_DEFAULT_MODIFIER }, "zoom-in", [&] { zoomIn(); } );
|
||||
addShortcut( { KEY_KP_MINUS, KEYMOD_DEFAULT_MODIFIER }, "zoom-out", [&] { zoomOut(); } );
|
||||
addShortcut( { KEY_0, KEYMOD_DEFAULT_MODIFIER }, "zoom-reset",
|
||||
[&] { mUIMap->Map()->setScale( 1 ); } );
|
||||
|
||||
PU3->addSeparator();
|
||||
|
||||
|
||||
@@ -434,7 +434,9 @@ UIWidget* UIAbstractTableView::updateCell( const int& rowIndex, const ModelIndex
|
||||
|
||||
Variant txt( getModel()->data( index, ModelRole::Display ) );
|
||||
if ( txt.isValid() ) {
|
||||
if ( txt.is( Variant::Type::String ) )
|
||||
if ( txt.is( Variant::Type::StdString ) )
|
||||
cell->setText( txt.asStdString() );
|
||||
else if ( txt.is( Variant::Type::String ) )
|
||||
cell->setText( txt.asString() );
|
||||
else if ( txt.is( Variant::Type::cstr ) )
|
||||
cell->setText( txt.asCStr() );
|
||||
|
||||
@@ -352,10 +352,13 @@ SyntaxDefinitionManager::SyntaxDefinitionManager() {
|
||||
{ "%.cpp$", "%.cc$", "%.C$", "%.cxx$", "%.c++$", "%.hh$", "%.H$", "%.h$", "%.inl$",
|
||||
"%.hxx$", "%.hpp$", "%.h++$" },
|
||||
{
|
||||
{ { "R%\"xml%(", "%)xml%\"" }, "function", "XML" },
|
||||
{ { "R%\"css%(", "%)css%\"" }, "function", "CSS" },
|
||||
{ { "R%\"html%(", "%)html%\"" }, "function", "HTML" },
|
||||
{ { "R\"[%a-\"]+%(", "%)[%a-\"]+%\"" }, "string" },
|
||||
{ { "//.-\n" }, "comment" },
|
||||
{ { "/%*", "%*/" }, "comment" },
|
||||
{ { "#", "[^\\]\n" }, "keyword2" },
|
||||
{ { "R\"[%a-\"]+%(", "%)[%a-\"]+%\"" }, "string" },
|
||||
{ { "\"", "\"", "\\" }, "string" },
|
||||
{ { "'", "'", "\\" }, "string" },
|
||||
{ { "-?0x%x+" }, "number" },
|
||||
|
||||
@@ -40,6 +40,8 @@ TextDocument::TextDocument( bool verbose ) :
|
||||
|
||||
TextDocument::~TextDocument() {
|
||||
notifyDocumentClosed();
|
||||
if ( mDeleteOnClose )
|
||||
FileSystem::fileRemove( mFilePath );
|
||||
}
|
||||
|
||||
bool TextDocument::hasFilepath() {
|
||||
@@ -322,6 +324,7 @@ bool TextDocument::loadFromURL( const std::string& url, const Http::Request::Fie
|
||||
FileSystem::fileWrite( path, (const Uint8*)response.getBody().c_str(),
|
||||
response.getBody().size() );
|
||||
loadFromFile( path );
|
||||
setDeleteOnClose( true );
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -346,8 +349,11 @@ bool TextDocument::loadAsyncFromURL( const std::string& url,
|
||||
std::string path( getTempPathFromURI( uri ) );
|
||||
FileSystem::fileWrite( path, (const Uint8*)response.getBody().c_str(),
|
||||
response.getBody().size() );
|
||||
if ( loadFromFile( path ) && onLoaded )
|
||||
onLoaded( this, true );
|
||||
if ( loadFromFile( path ) ) {
|
||||
setDeleteOnClose( true );
|
||||
if ( onLoaded )
|
||||
onLoaded( this, true );
|
||||
}
|
||||
} else {
|
||||
onLoaded( this, false );
|
||||
}
|
||||
@@ -472,6 +478,14 @@ bool TextDocument::isLoading() const {
|
||||
return mLoading;
|
||||
}
|
||||
|
||||
bool TextDocument::isDeleteOnClose() const {
|
||||
return mDeleteOnClose;
|
||||
}
|
||||
|
||||
void TextDocument::setDeleteOnClose( bool deleteOnClose ) {
|
||||
mDeleteOnClose = deleteOnClose;
|
||||
}
|
||||
|
||||
std::string TextDocument::getFilename() const {
|
||||
return FileSystem::fileNameFromPath( mFilePath );
|
||||
}
|
||||
|
||||
@@ -5,15 +5,29 @@ using namespace EE::Window;
|
||||
|
||||
namespace EE { namespace UI {
|
||||
|
||||
std::map<std::string, Uint32> MOD_MAP = {
|
||||
{"lshift", KEYMOD_SHIFT}, {"rshift", KEYMOD_SHIFT}, {"left shift", KEYMOD_SHIFT},
|
||||
{"right shift", KEYMOD_SHIFT}, {"shift", KEYMOD_SHIFT}, {"lctrl", KEYMOD_CTRL},
|
||||
{"rctrl", KEYMOD_CTRL}, {"left ctrl", KEYMOD_CTRL}, {"right ctrl", KEYMOD_CTRL},
|
||||
{"ctrl", KEYMOD_CTRL}, {"lalt", KEYMOD_ALT}, {"ralt", KEYMOD_RALT},
|
||||
{"left alt", KEYMOD_LALT}, {"right alt", KEYMOD_RALT}, {"altgr", KEYMOD_RALT},
|
||||
{"alt", KEYMOD_LALT}, {"lmeta", KEYMOD_META}, {"lmeta", KEYMOD_META},
|
||||
{"left meta", KEYMOD_META}, {"right meta", KEYMOD_META}, {"meta", KEYMOD_META},
|
||||
};
|
||||
std::map<std::string, Uint32> MOD_MAP = { { "lshift", KEYMOD_SHIFT },
|
||||
{ "rshift", KEYMOD_SHIFT },
|
||||
{ "left shift", KEYMOD_SHIFT },
|
||||
{ "right shift", KEYMOD_SHIFT },
|
||||
{ "shift", KEYMOD_SHIFT },
|
||||
{ "lctrl", KEYMOD_CTRL },
|
||||
{ "rctrl", KEYMOD_CTRL },
|
||||
{ "left ctrl", KEYMOD_CTRL },
|
||||
{ "right ctrl", KEYMOD_CTRL },
|
||||
{ "ctrl", KEYMOD_CTRL },
|
||||
{ "lalt", KEYMOD_ALT },
|
||||
{ "ralt", KEYMOD_RALT },
|
||||
{ "left alt", KEYMOD_LALT },
|
||||
{ "right alt", KEYMOD_RALT },
|
||||
{ "altgr", KEYMOD_RALT },
|
||||
{ "alt", KEYMOD_LALT },
|
||||
{ "lmeta", KEYMOD_META },
|
||||
{ "lmeta", KEYMOD_META },
|
||||
{ "left meta", KEYMOD_META },
|
||||
{ "right meta", KEYMOD_META },
|
||||
{ "meta", KEYMOD_META },
|
||||
{ "mod", KEYMOD_DEFAULT_MODIFIER },
|
||||
{ "modifier", KEYMOD_DEFAULT_MODIFIER } };
|
||||
|
||||
Uint32 KeyBindings::getKeyMod( std::string key ) {
|
||||
String::toLowerInPlace( key );
|
||||
@@ -142,4 +156,13 @@ std::string KeyBindings::getShortcutString( KeyBindings::Shortcut shortcut ) {
|
||||
return String::join( mods, '+' ) + "+" + keyname;
|
||||
}
|
||||
|
||||
Uint32 KeyBindings::getDefaultModifier() const {
|
||||
return MOD_MAP["mod"];
|
||||
}
|
||||
|
||||
void KeyBindings::setDefaultModifier( Uint32 newDefaultModifier ) {
|
||||
MOD_MAP["mod"] = newDefaultModifier;
|
||||
MOD_MAP["modifier"] = newDefaultModifier;
|
||||
}
|
||||
|
||||
}} // namespace EE::UI
|
||||
|
||||
@@ -213,7 +213,7 @@ bool SortingProxyModel::isColumnSortable( const size_t& columnIndex ) const {
|
||||
bool SortingProxyModel::lessThan( const ModelIndex& index1, const ModelIndex& index2 ) const {
|
||||
auto data1 = mSource->data( index1, mSortRole );
|
||||
auto data2 = mSource->data( index2, mSortRole );
|
||||
if ( data1.is( Variant::Type::String ) && data2.is( Variant::Type::String ) )
|
||||
if ( data1.is( Variant::Type::StdString ) && data2.is( Variant::Type::StdString ) )
|
||||
return String::toLower( data1.asString() ) < String::toLower( data2.asString() );
|
||||
if ( data1.is( Variant::Type::cstr ) && data2.is( Variant::Type::cstr ) )
|
||||
return String::toLower( std::string( data1.asCStr() ) ) <
|
||||
|
||||
@@ -19,31 +19,31 @@ const std::map<KeyBindings::Shortcut, std::string> UICodeEditorSplitter::getDefa
|
||||
const std::map<KeyBindings::Shortcut, std::string>
|
||||
UICodeEditorSplitter::getLocalDefaultKeybindings() {
|
||||
return {
|
||||
{ { KEY_S, KEYMOD_CTRL }, "save-doc" },
|
||||
{ { KEY_L, KEYMOD_CTRL | KEYMOD_SHIFT }, "lock-toggle" },
|
||||
{ { KEY_T, KEYMOD_CTRL }, "create-new" },
|
||||
{ { KEY_W, KEYMOD_CTRL }, "close-doc" },
|
||||
{ { KEY_TAB, KEYMOD_CTRL }, "next-doc" },
|
||||
{ { KEY_TAB, KEYMOD_CTRL | KEYMOD_SHIFT }, "previous-doc" },
|
||||
{ { KEY_S, KEYMOD_DEFAULT_MODIFIER }, "save-doc" },
|
||||
{ { KEY_L, KEYMOD_DEFAULT_MODIFIER | KEYMOD_SHIFT }, "lock-toggle" },
|
||||
{ { KEY_T, KEYMOD_DEFAULT_MODIFIER }, "create-new" },
|
||||
{ { KEY_W, KEYMOD_DEFAULT_MODIFIER }, "close-doc" },
|
||||
{ { KEY_TAB, KEYMOD_DEFAULT_MODIFIER }, "next-doc" },
|
||||
{ { KEY_TAB, KEYMOD_DEFAULT_MODIFIER | KEYMOD_SHIFT }, "previous-doc" },
|
||||
{ { KEY_J, KEYMOD_LALT | KEYMOD_SHIFT }, "split-left" },
|
||||
{ { KEY_L, KEYMOD_LALT | KEYMOD_SHIFT }, "split-right" },
|
||||
{ { KEY_I, KEYMOD_LALT | KEYMOD_SHIFT }, "split-top" },
|
||||
{ { KEY_K, KEYMOD_LALT | KEYMOD_SHIFT }, "split-bottom" },
|
||||
{ { KEY_S, KEYMOD_LALT | KEYMOD_SHIFT }, "split-swap" },
|
||||
{ { KEY_J, KEYMOD_CTRL | KEYMOD_LALT }, "switch-to-previous-split" },
|
||||
{ { KEY_L, KEYMOD_CTRL | KEYMOD_LALT }, "switch-to-next-split" },
|
||||
{ { KEY_N, KEYMOD_CTRL | KEYMOD_LALT }, "switch-to-previous-colorscheme" },
|
||||
{ { KEY_M, KEYMOD_CTRL | KEYMOD_LALT }, "switch-to-next-colorscheme" },
|
||||
{ { KEY_1, KEYMOD_CTRL }, "switch-to-tab-1" },
|
||||
{ { KEY_2, KEYMOD_CTRL }, "switch-to-tab-2" },
|
||||
{ { KEY_3, KEYMOD_CTRL }, "switch-to-tab-3" },
|
||||
{ { KEY_4, KEYMOD_CTRL }, "switch-to-tab-4" },
|
||||
{ { KEY_5, KEYMOD_CTRL }, "switch-to-tab-5" },
|
||||
{ { KEY_6, KEYMOD_CTRL }, "switch-to-tab-6" },
|
||||
{ { KEY_7, KEYMOD_CTRL }, "switch-to-tab-7" },
|
||||
{ { KEY_8, KEYMOD_CTRL }, "switch-to-tab-8" },
|
||||
{ { KEY_9, KEYMOD_CTRL }, "switch-to-tab-9" },
|
||||
{ { KEY_0, KEYMOD_CTRL }, "switch-to-last-tab" },
|
||||
{ { KEY_J, KEYMOD_DEFAULT_MODIFIER | KEYMOD_LALT }, "switch-to-previous-split" },
|
||||
{ { KEY_L, KEYMOD_DEFAULT_MODIFIER | KEYMOD_LALT }, "switch-to-next-split" },
|
||||
{ { KEY_N, KEYMOD_DEFAULT_MODIFIER | KEYMOD_LALT }, "switch-to-previous-colorscheme" },
|
||||
{ { KEY_M, KEYMOD_DEFAULT_MODIFIER | KEYMOD_LALT }, "switch-to-next-colorscheme" },
|
||||
{ { KEY_1, KEYMOD_DEFAULT_MODIFIER }, "switch-to-tab-1" },
|
||||
{ { KEY_2, KEYMOD_DEFAULT_MODIFIER }, "switch-to-tab-2" },
|
||||
{ { KEY_3, KEYMOD_DEFAULT_MODIFIER }, "switch-to-tab-3" },
|
||||
{ { KEY_4, KEYMOD_DEFAULT_MODIFIER }, "switch-to-tab-4" },
|
||||
{ { KEY_5, KEYMOD_DEFAULT_MODIFIER }, "switch-to-tab-5" },
|
||||
{ { KEY_6, KEYMOD_DEFAULT_MODIFIER }, "switch-to-tab-6" },
|
||||
{ { KEY_7, KEYMOD_DEFAULT_MODIFIER }, "switch-to-tab-7" },
|
||||
{ { KEY_8, KEYMOD_DEFAULT_MODIFIER }, "switch-to-tab-8" },
|
||||
{ { KEY_9, KEYMOD_DEFAULT_MODIFIER }, "switch-to-tab-9" },
|
||||
{ { KEY_0, KEYMOD_DEFAULT_MODIFIER }, "switch-to-last-tab" },
|
||||
{ { KEY_1, KEYMOD_LALT }, "switch-to-tab-1" },
|
||||
{ { KEY_2, KEYMOD_LALT }, "switch-to-tab-2" },
|
||||
{ { KEY_3, KEYMOD_LALT }, "switch-to-tab-3" },
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace EE { namespace UI { namespace Tools {
|
||||
static CSS::StyleSheetParser sStyleSheetParser;
|
||||
static UISceneNode* sLastSceneNode = NULL;
|
||||
|
||||
const char* COLOR_PICKER_STYLE = R"xml(
|
||||
const char* COLOR_PICKER_STYLE = R"css(
|
||||
#color_picker {
|
||||
margin: 4dp;
|
||||
window-min-size: 320dp 478dp;
|
||||
@@ -79,7 +79,7 @@ const char* COLOR_PICKER_STYLE = R"xml(
|
||||
padding-right: 8dp;
|
||||
icon: ok;
|
||||
}
|
||||
)xml";
|
||||
)css";
|
||||
|
||||
UIColorPicker* UIColorPicker::NewModal( Node* nodeCreator,
|
||||
const UIColorPicker::ColorPickedCb& colorPickedCb,
|
||||
|
||||
@@ -33,66 +33,66 @@ UICodeEditor* UICodeEditor::NewOpt( const bool& autoRegisterBaseCommands,
|
||||
|
||||
const std::map<KeyBindings::Shortcut, std::string> UICodeEditor::getDefaultKeybindings() {
|
||||
return {
|
||||
{ { KEY_BACKSPACE, KEYMOD_CTRL }, "delete-to-previous-word" },
|
||||
{ { KEY_BACKSPACE, KEYMOD_DEFAULT_MODIFIER }, "delete-to-previous-word" },
|
||||
{ { 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_DEFAULT_MODIFIER }, "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" },
|
||||
{ { KEY_KP_ENTER, KEYMOD_CTRL }, "new-line" },
|
||||
{ { KEY_RETURN, KEYMOD_CTRL }, "new-line" },
|
||||
{ { KEY_KP_ENTER, KEYMOD_DEFAULT_MODIFIER | KEYMOD_SHIFT }, "new-line-above" },
|
||||
{ { KEY_RETURN, KEYMOD_DEFAULT_MODIFIER | KEYMOD_SHIFT }, "new-line-above" },
|
||||
{ { KEY_KP_ENTER, KEYMOD_DEFAULT_MODIFIER }, "new-line" },
|
||||
{ { KEY_RETURN, KEYMOD_DEFAULT_MODIFIER }, "new-line" },
|
||||
{ { KEY_KP_ENTER, KEYMOD_SHIFT }, "new-line" },
|
||||
{ { KEY_RETURN, KEYMOD_SHIFT }, "new-line" },
|
||||
{ { KEY_KP_ENTER, 0 }, "new-line" },
|
||||
{ { KEY_RETURN, 0 }, "new-line" },
|
||||
{ { KEY_UP, KEYMOD_CTRL | KEYMOD_SHIFT }, "move-lines-up" },
|
||||
{ { KEY_UP, KEYMOD_CTRL }, "move-scroll-up" },
|
||||
{ { KEY_UP, KEYMOD_DEFAULT_MODIFIER | KEYMOD_SHIFT }, "move-lines-up" },
|
||||
{ { KEY_UP, KEYMOD_DEFAULT_MODIFIER }, "move-scroll-up" },
|
||||
{ { KEY_UP, KEYMOD_SHIFT }, "select-to-previous-line" },
|
||||
{ { KEY_UP, 0 }, "move-to-previous-line" },
|
||||
{ { KEY_DOWN, KEYMOD_CTRL | KEYMOD_SHIFT }, "move-lines-down" },
|
||||
{ { KEY_DOWN, KEYMOD_CTRL }, "move-scroll-down" },
|
||||
{ { KEY_DOWN, KEYMOD_DEFAULT_MODIFIER | KEYMOD_SHIFT }, "move-lines-down" },
|
||||
{ { KEY_DOWN, KEYMOD_DEFAULT_MODIFIER }, "move-scroll-down" },
|
||||
{ { KEY_DOWN, KEYMOD_SHIFT }, "select-to-next-line" },
|
||||
{ { KEY_DOWN, 0 }, "move-to-next-line" },
|
||||
{ { KEY_LEFT, KEYMOD_CTRL | KEYMOD_SHIFT }, "select-to-previous-word" },
|
||||
{ { KEY_LEFT, KEYMOD_CTRL }, "move-to-previous-word" },
|
||||
{ { KEY_LEFT, KEYMOD_DEFAULT_MODIFIER | KEYMOD_SHIFT }, "select-to-previous-word" },
|
||||
{ { KEY_LEFT, KEYMOD_DEFAULT_MODIFIER }, "move-to-previous-word" },
|
||||
{ { KEY_LEFT, KEYMOD_SHIFT }, "select-to-previous-char" },
|
||||
{ { KEY_LEFT, 0 }, "move-to-previous-char" },
|
||||
{ { KEY_RIGHT, KEYMOD_CTRL | KEYMOD_SHIFT }, "select-to-next-word" },
|
||||
{ { KEY_RIGHT, KEYMOD_CTRL }, "move-to-next-word" },
|
||||
{ { KEY_RIGHT, KEYMOD_DEFAULT_MODIFIER | KEYMOD_SHIFT }, "select-to-next-word" },
|
||||
{ { KEY_RIGHT, KEYMOD_DEFAULT_MODIFIER }, "move-to-next-word" },
|
||||
{ { KEY_RIGHT, KEYMOD_SHIFT }, "select-to-next-char" },
|
||||
{ { KEY_RIGHT, 0 }, "move-to-next-char" },
|
||||
{ { KEY_Z, KEYMOD_CTRL | KEYMOD_SHIFT }, "redo" },
|
||||
{ { KEY_HOME, KEYMOD_CTRL | KEYMOD_SHIFT }, "select-to-start-of-doc" },
|
||||
{ { KEY_Z, KEYMOD_DEFAULT_MODIFIER | KEYMOD_SHIFT }, "redo" },
|
||||
{ { KEY_HOME, KEYMOD_DEFAULT_MODIFIER | KEYMOD_SHIFT }, "select-to-start-of-doc" },
|
||||
{ { KEY_HOME, KEYMOD_SHIFT }, "select-to-start-of-content" },
|
||||
{ { KEY_HOME, KEYMOD_CTRL }, "move-to-start-of-doc" },
|
||||
{ { KEY_HOME, KEYMOD_DEFAULT_MODIFIER }, "move-to-start-of-doc" },
|
||||
{ { KEY_HOME, 0 }, "move-to-start-of-content" },
|
||||
{ { KEY_END, KEYMOD_CTRL | KEYMOD_SHIFT }, "select-to-end-of-doc" },
|
||||
{ { KEY_END, KEYMOD_DEFAULT_MODIFIER | KEYMOD_SHIFT }, "select-to-end-of-doc" },
|
||||
{ { KEY_END, KEYMOD_SHIFT }, "select-to-end-of-line" },
|
||||
{ { KEY_END, KEYMOD_CTRL }, "move-to-end-of-doc" },
|
||||
{ { KEY_END, KEYMOD_DEFAULT_MODIFIER }, "move-to-end-of-doc" },
|
||||
{ { KEY_END, 0 }, "move-to-end-of-line" },
|
||||
{ { KEY_PAGEUP, KEYMOD_CTRL }, "move-to-previous-page" },
|
||||
{ { KEY_PAGEUP, KEYMOD_DEFAULT_MODIFIER }, "move-to-previous-page" },
|
||||
{ { KEY_PAGEUP, KEYMOD_SHIFT }, "select-to-previous-page" },
|
||||
{ { KEY_PAGEUP, 0 }, "move-to-previous-page" },
|
||||
{ { KEY_PAGEDOWN, KEYMOD_CTRL }, "move-to-next-page" },
|
||||
{ { KEY_PAGEDOWN, KEYMOD_DEFAULT_MODIFIER }, "move-to-next-page" },
|
||||
{ { KEY_PAGEDOWN, KEYMOD_SHIFT }, "select-to-next-page" },
|
||||
{ { KEY_PAGEDOWN, 0 }, "move-to-next-page" },
|
||||
{ { KEY_Y, KEYMOD_CTRL }, "redo" },
|
||||
{ { KEY_Z, KEYMOD_CTRL }, "undo" },
|
||||
{ { KEY_Y, KEYMOD_DEFAULT_MODIFIER }, "redo" },
|
||||
{ { KEY_Z, KEYMOD_DEFAULT_MODIFIER }, "undo" },
|
||||
{ { KEY_TAB, KEYMOD_SHIFT }, "unindent" },
|
||||
{ { KEY_TAB, 0 }, "indent" },
|
||||
{ { KEY_C, KEYMOD_CTRL }, "copy" },
|
||||
{ { KEY_X, KEYMOD_CTRL }, "cut" },
|
||||
{ { KEY_V, KEYMOD_CTRL }, "paste" },
|
||||
{ { KEY_C, KEYMOD_DEFAULT_MODIFIER }, "copy" },
|
||||
{ { KEY_X, KEYMOD_DEFAULT_MODIFIER }, "cut" },
|
||||
{ { KEY_V, KEYMOD_DEFAULT_MODIFIER }, "paste" },
|
||||
{ { KEY_INSERT, KEYMOD_SHIFT }, "paste" },
|
||||
{ { KEY_A, KEYMOD_CTRL }, "select-all" },
|
||||
{ { KEY_PLUS, KEYMOD_CTRL }, "font-size-grow" },
|
||||
{ { KEY_KP_PLUS, KEYMOD_CTRL }, "font-size-grow" },
|
||||
{ { KEY_MINUS, KEYMOD_CTRL }, "font-size-shrink" },
|
||||
{ { KEY_KP_MINUS, KEYMOD_CTRL }, "font-size-shrink" },
|
||||
{ { KEY_0, KEYMOD_CTRL }, "font-size-reset" },
|
||||
{ { KEY_KP_DIVIDE, KEYMOD_CTRL }, "toggle-line-comments" },
|
||||
{ { KEY_A, KEYMOD_DEFAULT_MODIFIER }, "select-all" },
|
||||
{ { KEY_PLUS, KEYMOD_DEFAULT_MODIFIER }, "font-size-grow" },
|
||||
{ { KEY_KP_PLUS, KEYMOD_DEFAULT_MODIFIER }, "font-size-grow" },
|
||||
{ { KEY_MINUS, KEYMOD_DEFAULT_MODIFIER }, "font-size-shrink" },
|
||||
{ { KEY_KP_MINUS, KEYMOD_DEFAULT_MODIFIER }, "font-size-shrink" },
|
||||
{ { KEY_0, KEYMOD_DEFAULT_MODIFIER }, "font-size-reset" },
|
||||
{ { KEY_KP_DIVIDE, KEYMOD_DEFAULT_MODIFIER }, "toggle-line-comments" },
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@ UIFileDialog::UIFileDialog( Uint32 dialogFlags, const std::string& defaultFilePa
|
||||
modelEvent->getTriggerEvent()->getType() == Event::EventType::KeyDown ) {
|
||||
const KeyEvent* keyEvent =
|
||||
static_cast<const KeyEvent*>( modelEvent->getTriggerEvent() );
|
||||
if ( keyEvent->getMod() & KEYMOD_CTRL ) {
|
||||
if ( keyEvent->getMod() & KEYMOD_DEFAULT_MODIFIER ) {
|
||||
shouldOpenFolder = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,11 +87,14 @@ void UISplitter::setSplitPartition( const StyleSheetLength& divisionSplit ) {
|
||||
}
|
||||
}
|
||||
|
||||
void UISplitter::swap() {
|
||||
void UISplitter::swap( bool swapSplitPartition ) {
|
||||
if ( isFull() ) {
|
||||
UIWidget* tmp = mFirstWidget;
|
||||
mFirstWidget = mLastWidget;
|
||||
mLastWidget = tmp;
|
||||
if ( swapSplitPartition )
|
||||
mSplitPartition.setValue( 100.f - mSplitPartition.getValue(),
|
||||
StyleSheetLength::Percentage );
|
||||
setLayoutDirty();
|
||||
}
|
||||
}
|
||||
@@ -183,14 +186,6 @@ void UISplitter::updateFromDrag() {
|
||||
mDirtyLayout = true;
|
||||
mSplitter->setVisible( !mAlwaysShowSplitter && !mLastWidget ? false : true );
|
||||
mSplitter->setEnabled( mSplitter->isVisible() );
|
||||
Float totalSpace = mOrientation == UIOrientation::Horizontal
|
||||
? mSize.getWidth() - mPaddingPx.Left - mPaddingPx.Right
|
||||
: mSize.getHeight() - mPaddingPx.Top - mPaddingPx.Bottom;
|
||||
if ( mSplitter->isVisible() ) {
|
||||
totalSpace -= UIOrientation::Horizontal == mOrientation
|
||||
? mSplitter->getPixelsSize().getWidth()
|
||||
: mSplitter->getPixelsSize().getHeight();
|
||||
}
|
||||
|
||||
if ( UIOrientation::Horizontal == mOrientation ) {
|
||||
Float fMinSize = mFirstWidget ? mFirstWidget->getCurrentMinSize().getWidth() : 0.f;
|
||||
|
||||
@@ -126,13 +126,16 @@ Float UITableView::getMaxColumnContentWidth( const size_t& colIndex, bool bestGu
|
||||
};
|
||||
if ( bestGuess ) {
|
||||
Variant dataTest( getModel()->data( getModel()->index( 0, colIndex ) ) );
|
||||
bool isStdString = dataTest.is( Variant::Type::StdString );
|
||||
bool isString = dataTest.is( Variant::Type::String );
|
||||
if ( isString || dataTest.is( Variant::Type::cstr ) ) {
|
||||
if ( isStdString || isString || dataTest.is( Variant::Type::cstr ) ) {
|
||||
std::map<size_t, ModelIndex> lengths;
|
||||
for ( size_t i = 0; i < getItemCount(); i++ ) {
|
||||
ModelIndex index( getModel()->index( i, colIndex ) );
|
||||
Variant data( getModel()->data( index ) );
|
||||
size_t length = isString ? data.asString().length() : strlen( data.asCStr() );
|
||||
size_t length =
|
||||
isStdString ? data.asStdString().length()
|
||||
: ( isString ? data.asString().length() : strlen( data.asCStr() ) );
|
||||
if ( lengths.empty() || length > lengths.rbegin()->first )
|
||||
lengths[length] = index;
|
||||
}
|
||||
@@ -153,8 +156,10 @@ Float UITableView::getMaxColumnContentWidth( const size_t& colIndex, bool bestGu
|
||||
}
|
||||
|
||||
void UITableView::createOrUpdateColumns() {
|
||||
if ( !getModel() )
|
||||
if ( !getModel() ) {
|
||||
updateContentSize();
|
||||
return;
|
||||
}
|
||||
UIAbstractTableView::createOrUpdateColumns();
|
||||
updateContentSize();
|
||||
}
|
||||
|
||||
@@ -684,36 +684,36 @@ void UITextInput::registerCommands() {
|
||||
|
||||
void UITextInput::registerKeybindings() {
|
||||
mKeyBindings.addKeybinds( {
|
||||
{ { KEY_BACKSPACE, KEYMOD_CTRL }, "delete-to-previous-word" },
|
||||
{ { KEY_BACKSPACE, KEYMOD_DEFAULT_MODIFIER }, "delete-to-previous-word" },
|
||||
{ { 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_DEFAULT_MODIFIER }, "delete-to-next-word" },
|
||||
{ { KEY_DELETE, 0 }, "delete-to-next-char" },
|
||||
{ { KEY_KP_ENTER, 0 }, "press-enter" },
|
||||
{ { KEY_RETURN, 0 }, "press-enter" },
|
||||
{ { KEY_LEFT, KEYMOD_CTRL | KEYMOD_SHIFT }, "select-to-previous-word" },
|
||||
{ { KEY_LEFT, KEYMOD_CTRL }, "move-to-previous-word" },
|
||||
{ { KEY_LEFT, KEYMOD_DEFAULT_MODIFIER | KEYMOD_SHIFT }, "select-to-previous-word" },
|
||||
{ { KEY_LEFT, KEYMOD_DEFAULT_MODIFIER }, "move-to-previous-word" },
|
||||
{ { KEY_LEFT, KEYMOD_SHIFT }, "select-to-previous-char" },
|
||||
{ { KEY_LEFT, 0 }, "move-to-previous-char" },
|
||||
{ { KEY_RIGHT, KEYMOD_CTRL | KEYMOD_SHIFT }, "select-to-next-word" },
|
||||
{ { KEY_RIGHT, KEYMOD_CTRL }, "move-to-next-word" },
|
||||
{ { KEY_RIGHT, KEYMOD_DEFAULT_MODIFIER | KEYMOD_SHIFT }, "select-to-next-word" },
|
||||
{ { KEY_RIGHT, KEYMOD_DEFAULT_MODIFIER }, "move-to-next-word" },
|
||||
{ { KEY_RIGHT, KEYMOD_SHIFT }, "select-to-next-char" },
|
||||
{ { KEY_RIGHT, 0 }, "move-to-next-char" },
|
||||
{ { KEY_Z, KEYMOD_CTRL | KEYMOD_SHIFT }, "redo" },
|
||||
{ { KEY_HOME, KEYMOD_CTRL | KEYMOD_SHIFT }, "select-to-start-of-doc" },
|
||||
{ { KEY_Z, KEYMOD_DEFAULT_MODIFIER | KEYMOD_SHIFT }, "redo" },
|
||||
{ { KEY_HOME, KEYMOD_DEFAULT_MODIFIER | KEYMOD_SHIFT }, "select-to-start-of-doc" },
|
||||
{ { KEY_HOME, KEYMOD_SHIFT }, "select-to-start-of-content" },
|
||||
{ { KEY_HOME, KEYMOD_CTRL }, "move-to-start-of-doc" },
|
||||
{ { KEY_HOME, KEYMOD_DEFAULT_MODIFIER }, "move-to-start-of-doc" },
|
||||
{ { KEY_HOME, 0 }, "move-to-start-of-content" },
|
||||
{ { KEY_END, KEYMOD_CTRL | KEYMOD_SHIFT }, "select-to-end-of-doc" },
|
||||
{ { KEY_END, KEYMOD_DEFAULT_MODIFIER | KEYMOD_SHIFT }, "select-to-end-of-doc" },
|
||||
{ { KEY_END, KEYMOD_SHIFT }, "select-to-end-of-line" },
|
||||
{ { KEY_END, KEYMOD_CTRL }, "move-to-end-of-doc" },
|
||||
{ { KEY_END, KEYMOD_DEFAULT_MODIFIER }, "move-to-end-of-doc" },
|
||||
{ { KEY_END, 0 }, "move-to-end-of-line" },
|
||||
{ { KEY_Y, KEYMOD_CTRL }, "redo" },
|
||||
{ { KEY_Z, KEYMOD_CTRL }, "undo" },
|
||||
{ { KEY_C, KEYMOD_CTRL }, "copy" },
|
||||
{ { KEY_X, KEYMOD_CTRL }, "cut" },
|
||||
{ { KEY_V, KEYMOD_CTRL }, "paste" },
|
||||
{ { KEY_A, KEYMOD_CTRL }, "select-all" },
|
||||
{ { KEY_Y, KEYMOD_DEFAULT_MODIFIER }, "redo" },
|
||||
{ { KEY_Z, KEYMOD_DEFAULT_MODIFIER }, "undo" },
|
||||
{ { KEY_C, KEYMOD_DEFAULT_MODIFIER }, "copy" },
|
||||
{ { KEY_X, KEYMOD_DEFAULT_MODIFIER }, "cut" },
|
||||
{ { KEY_V, KEYMOD_DEFAULT_MODIFIER }, "paste" },
|
||||
{ { KEY_A, KEYMOD_DEFAULT_MODIFIER }, "select-all" },
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
@@ -84,9 +84,9 @@ void UITreeView::traverseTree( TreeViewCallback callback ) const {
|
||||
}
|
||||
|
||||
void UITreeView::createOrUpdateColumns() {
|
||||
updateContentSize();
|
||||
if ( !getModel() )
|
||||
return;
|
||||
updateContentSize();
|
||||
UIAbstractTableView::createOrUpdateColumns();
|
||||
}
|
||||
|
||||
@@ -201,7 +201,9 @@ UIWidget* UITreeView::updateCell( const int& rowIndex, const ModelIndex& index,
|
||||
|
||||
Variant txt( getModel()->data( index, ModelRole::Display ) );
|
||||
if ( txt.isValid() ) {
|
||||
if ( txt.is( Variant::Type::String ) )
|
||||
if ( txt.is( Variant::Type::StdString ) )
|
||||
cell->setText( txt.asStdString() );
|
||||
else if ( txt.is( Variant::Type::String ) )
|
||||
cell->setText( txt.asString() );
|
||||
else if ( txt.is( Variant::Type::cstr ) )
|
||||
cell->setText( txt.asCStr() );
|
||||
|
||||
@@ -6,6 +6,18 @@
|
||||
|
||||
using namespace EE::Network;
|
||||
|
||||
static PanelPosition panelPositionFromString( const std::string& str ) {
|
||||
if ( String::toLower( str ) == "right" )
|
||||
return PanelPosition::Right;
|
||||
return PanelPosition::Left;
|
||||
}
|
||||
|
||||
static std::string panelPositionToString( const PanelPosition& pos ) {
|
||||
if ( pos == PanelPosition::Right )
|
||||
return "right";
|
||||
return "left";
|
||||
}
|
||||
|
||||
static std::vector<std::string> urlEncode( const std::vector<std::string>& vec ) {
|
||||
std::vector<std::string> encoded;
|
||||
for ( const auto& item : vec )
|
||||
@@ -55,6 +67,7 @@ void AppConfig::load( std::string& confPath, std::string& keybindingsPath,
|
||||
editor.horizontalScrollbar = ini.getValueB( "editor", "horizontal_scrollbar", false );
|
||||
ui.fontSize = ini.getValue( "ui", "font_size", "11dp" );
|
||||
ui.showSidePanel = ini.getValueB( "ui", "show_side_panel", true );
|
||||
ui.panelPosition = panelPositionFromString( ini.getValue( "ui", "panel_position", "left" ) );
|
||||
ui.serifFont = ini.getValue( "ui", "serif_font", "assets/fonts/NotoSans-Regular.ttf" );
|
||||
ui.monospaceFont = ini.getValue( "ui", "monospace_font", "assets/fonts/DejaVuSansMono.ttf" );
|
||||
editor.trimTrailingWhitespaces = ini.getValueB( "editor", "trim_trailing_whitespaces", false );
|
||||
@@ -119,6 +132,7 @@ void AppConfig::save( const std::vector<std::string>& recentFiles,
|
||||
ini.setValue( "editor", "font_size", editor.fontSize.toString() );
|
||||
ini.setValue( "ui", "font_size", ui.fontSize.toString() );
|
||||
ini.setValueB( "ui", "show_side_panel", ui.showSidePanel );
|
||||
ini.setValue( "ui", "panel_position", panelPositionToString( ui.panelPosition ) );
|
||||
ini.setValue( "ui", "serif_font", ui.serifFont );
|
||||
ini.setValue( "ui", "monospace_font", ui.monospaceFont );
|
||||
ini.setValueB( "editor", "trim_trailing_whitespaces", editor.trimTrailingWhitespaces );
|
||||
@@ -179,7 +193,7 @@ void AppConfig::loadProject( std::string projectFolder, UICodeEditorSplitter* ed
|
||||
do {
|
||||
std::string val( ini.getValue( "files", String::format( "file_name_%lu", i ) ) );
|
||||
found = !val.empty();
|
||||
if ( found )
|
||||
if ( found && FileSystem::fileExists( val ) )
|
||||
editorSplitter->loadFileFromPathInNewTab( val );
|
||||
i++;
|
||||
} while ( found );
|
||||
|
||||
@@ -16,9 +16,12 @@ using namespace EE::UI::Tools;
|
||||
using namespace EE::System;
|
||||
using namespace EE::Window;
|
||||
|
||||
enum class PanelPosition { Left, Right };
|
||||
|
||||
struct UIConfig {
|
||||
StyleSheetLength fontSize{ 12, StyleSheetLength::Dp };
|
||||
bool showSidePanel{ true };
|
||||
PanelPosition panelPosition{ PanelPosition::Left };
|
||||
std::string serifFont;
|
||||
std::string monospaceFont;
|
||||
};
|
||||
|
||||
@@ -161,7 +161,7 @@ bool AutoCompleteModule::onKeyDown( UICodeEditor* editor, const KeyEvent& event
|
||||
pickSuggestion( editor );
|
||||
return true;
|
||||
}
|
||||
} else if ( event.getKeyCode() == KEY_SPACE && ( event.getMod() & KEYMOD_CTRL ) ) {
|
||||
} else if ( event.getKeyCode() == KEY_SPACE && ( event.getMod() & KEYMOD_DEFAULT_MODIFIER ) ) {
|
||||
std::string partialSymbol( getPartialSymbol( &editor->getDocument() ) );
|
||||
if ( partialSymbol.size() >= 3 ) {
|
||||
updateSuggestions( partialSymbol, editor );
|
||||
|
||||
@@ -480,12 +480,26 @@ void App::showSidePanel( bool show ) {
|
||||
|
||||
void App::switchSidePanel() {
|
||||
mConfig.ui.showSidePanel = !mConfig.ui.showSidePanel;
|
||||
mWindowMenu->getItem( "Show Left Sidebar" )
|
||||
mWindowMenu->getItem( "Show Side Panel" )
|
||||
->asType<UIMenuCheckBox>()
|
||||
->setActive( mConfig.ui.showSidePanel );
|
||||
showSidePanel( mConfig.ui.showSidePanel );
|
||||
}
|
||||
|
||||
void App::panelPosition( const PanelPosition& panelPosition ) {
|
||||
mConfig.ui.panelPosition = panelPosition;
|
||||
|
||||
if ( !mSidePanel->isVisible() )
|
||||
return;
|
||||
|
||||
if ( ( panelPosition == PanelPosition::Right &&
|
||||
mProjectSplitter->getFirstWidget() == mSidePanel ) ||
|
||||
( panelPosition == PanelPosition::Left &&
|
||||
mProjectSplitter->getFirstWidget() != mSidePanel ) ) {
|
||||
mProjectSplitter->swap( true );
|
||||
}
|
||||
}
|
||||
|
||||
UIMenu* App::createWindowMenu() {
|
||||
mWindowMenu = UIPopUpMenu::New();
|
||||
mWindowMenu->add( "UI Scale Factor (Pixel Density)", findIcon( "pixel-density" ) );
|
||||
@@ -496,8 +510,12 @@ UIMenu* App::createWindowMenu() {
|
||||
mWindowMenu->addSeparator();
|
||||
mWindowMenu->addCheckBox( "Full Screen Mode", false, getKeybind( "fullscreen-toggle" ) )
|
||||
->setId( "fullscreen-mode" );
|
||||
mWindowMenu->addCheckBox( "Show Left Sidebar", mConfig.ui.showSidePanel,
|
||||
mWindowMenu->addCheckBox( "Show Side Panel", mConfig.ui.showSidePanel,
|
||||
getKeybind( "switch-side-panel" ) );
|
||||
mWindowMenu->add( "Move panel to left...", findIcon( "layout-left" ),
|
||||
getKeybind( "layout-left" ) );
|
||||
mWindowMenu->add( "Move panel to right...", findIcon( "layout-right" ),
|
||||
getKeybind( "layout-rigth" ) );
|
||||
mWindowMenu->addSeparator();
|
||||
mWindowMenu->add( "Split Left", findIcon( "split-horizontal" ), getKeybind( "split-left" ) );
|
||||
mWindowMenu->add( "Split Right", findIcon( "split-horizontal" ), getKeybind( "split-right" ) );
|
||||
@@ -511,7 +529,7 @@ UIMenu* App::createWindowMenu() {
|
||||
if ( !event->getNode()->isType( UI_TYPE_MENUITEM ) )
|
||||
return;
|
||||
UIMenuItem* item = event->getNode()->asType<UIMenuItem>();
|
||||
if ( item->getText() == "Show Left Sidebar" ) {
|
||||
if ( item->getText() == "Show Side Panel" ) {
|
||||
mConfig.ui.showSidePanel = item->asType<UIMenuCheckBox>()->isActive();
|
||||
showSidePanel( mConfig.ui.showSidePanel );
|
||||
} else if ( item->getText() == "UI Scale Factor (Pixel Density)" ) {
|
||||
@@ -596,6 +614,10 @@ UIMenu* App::createWindowMenu() {
|
||||
mEditorSplitter->zoomReset();
|
||||
} else if ( "Full Screen Mode" == item->getText() ) {
|
||||
runCommand( "fullscreen-toggle" );
|
||||
} else if ( "Move panel to left..." == item->getText() ) {
|
||||
runCommand( "move-panel-left" );
|
||||
} else if ( "Move panel to right..." == item->getText() ) {
|
||||
runCommand( "move-panel-right" );
|
||||
} else {
|
||||
String text = String( event->getNode()->asType<UIMenuItem>()->getText() ).toLower();
|
||||
String::replaceAll( text, " ", "-" );
|
||||
@@ -1140,19 +1162,19 @@ std::map<KeyBindings::Shortcut, std::string> App::getLocalKeybindings() {
|
||||
{ { KEY_F3, KEYMOD_NONE }, "repeat-find" },
|
||||
{ { KEY_F3, KEYMOD_SHIFT }, "find-prev" },
|
||||
{ { KEY_F12, KEYMOD_NONE }, "console-toggle" },
|
||||
{ { KEY_F, KEYMOD_CTRL }, "find-replace" },
|
||||
{ { KEY_Q, KEYMOD_CTRL }, "close-app" },
|
||||
{ { KEY_O, KEYMOD_CTRL }, "open-file" },
|
||||
{ { KEY_W, KEYMOD_CTRL | KEYMOD_SHIFT }, "download-file-web" },
|
||||
{ { KEY_O, KEYMOD_CTRL | KEYMOD_SHIFT }, "open-folder" },
|
||||
{ { KEY_F, KEYMOD_DEFAULT_MODIFIER }, "find-replace" },
|
||||
{ { KEY_Q, KEYMOD_DEFAULT_MODIFIER }, "close-app" },
|
||||
{ { KEY_O, KEYMOD_DEFAULT_MODIFIER }, "open-file" },
|
||||
{ { KEY_W, KEYMOD_DEFAULT_MODIFIER | KEYMOD_SHIFT }, "download-file-web" },
|
||||
{ { KEY_O, KEYMOD_DEFAULT_MODIFIER | KEYMOD_SHIFT }, "open-folder" },
|
||||
{ { KEY_F6, KEYMOD_NONE }, "debug-draw-highlight-toggle" },
|
||||
{ { KEY_F7, KEYMOD_NONE }, "debug-draw-boxes-toggle" },
|
||||
{ { KEY_F8, KEYMOD_NONE }, "debug-draw-debug-data" },
|
||||
{ { KEY_K, KEYMOD_CTRL }, "open-locatebar" },
|
||||
{ { KEY_F, KEYMOD_CTRL | KEYMOD_SHIFT }, "open-global-search" },
|
||||
{ { KEY_L, KEYMOD_CTRL }, "go-to-line" },
|
||||
{ { KEY_M, KEYMOD_CTRL }, "menu-toggle" },
|
||||
{ { KEY_S, KEYMOD_CTRL | KEYMOD_SHIFT }, "save-all" },
|
||||
{ { KEY_K, KEYMOD_DEFAULT_MODIFIER }, "open-locatebar" },
|
||||
{ { KEY_F, KEYMOD_DEFAULT_MODIFIER | KEYMOD_SHIFT }, "open-global-search" },
|
||||
{ { KEY_L, KEYMOD_DEFAULT_MODIFIER }, "go-to-line" },
|
||||
{ { KEY_M, KEYMOD_DEFAULT_MODIFIER }, "menu-toggle" },
|
||||
{ { KEY_S, KEYMOD_DEFAULT_MODIFIER | KEYMOD_SHIFT }, "save-all" },
|
||||
{ { KEY_F9, KEYMOD_LALT }, "switch-side-panel" },
|
||||
{ { KEY_F, KEYMOD_LALT }, "format-doc" } };
|
||||
}
|
||||
@@ -1417,6 +1439,8 @@ void App::onCodeEditorCreated( UICodeEditor* editor, TextDocument& doc ) {
|
||||
msgBox->closeWindow();
|
||||
} );
|
||||
} );
|
||||
doc.setCommand( "move-panel-left", [&] { panelPosition( PanelPosition::Left ); } );
|
||||
doc.setCommand( "move-panel-right", [&] { panelPosition( PanelPosition::Right ); } );
|
||||
|
||||
editor->addEventListener( Event::OnDocumentSave, [&]( const Event* event ) {
|
||||
UICodeEditor* editor = event->getNode()->asType<UICodeEditor>();
|
||||
@@ -1807,8 +1831,12 @@ void App::createProjectTreeMenu( const FileInfo& file ) {
|
||||
if ( file.isDirectory() ) {
|
||||
mProjectTreeMenu->add( "New File...", findIcon( "file-add" ) )->setId( "new_file" );
|
||||
mProjectTreeMenu->add( "New Folder...", findIcon( "folder-add" ) )->setId( "new_folder" );
|
||||
mProjectTreeMenu->add( "Open Folder...", findIcon( "folder-open" ) )
|
||||
->setId( "open_folder" );
|
||||
} else {
|
||||
mProjectTreeMenu->add( "Open File", findIcon( "document-open" ) )->setId( "open_file" );
|
||||
mProjectTreeMenu->add( "Open Containing Folder...", findIcon( "folder-open" ) )
|
||||
->setId( "open_containing_folder" );
|
||||
mProjectTreeMenu->add( "New File in directory...", findIcon( "file-add" ) )
|
||||
->setId( "new_file_in_place" );
|
||||
mProjectTreeMenu->add( "Duplicate File...", findIcon( "file-copy" ) )
|
||||
@@ -1882,6 +1910,10 @@ void App::createProjectTreeMenu( const FileInfo& file ) {
|
||||
} );
|
||||
} else if ( "rename" == txt ) {
|
||||
renameFile( file );
|
||||
} else if ( "open_containing_folder" == txt ) {
|
||||
Engine::instance()->openURL( file.getDirectoryPath() );
|
||||
} else if ( "open_folder" == txt ) {
|
||||
Engine::instance()->openURL( file.getFilepath() );
|
||||
}
|
||||
} );
|
||||
|
||||
@@ -2135,7 +2167,7 @@ void App::init( const std::string& file, const Float& pidelDensity ) {
|
||||
|
||||
mUISceneNode->getRoot()->addClass( "appbackground" );
|
||||
|
||||
const std::string baseUI = R"xml(
|
||||
const std::string baseUI = R"html(
|
||||
<style>
|
||||
TextInput#search_find,
|
||||
TextInput#search_replace,
|
||||
@@ -2314,6 +2346,7 @@ void App::init( const std::string& file, const Float& pidelDensity ) {
|
||||
<Widget layout_width="0" layout_weight="1" layout_height="match_parent" />
|
||||
<TextView layout_width="wrap_content" layout_height="wrap_content" text="History:" margin-right="4dp" layout_height="18dp" />
|
||||
<DropDownList id="global_search_history" layout_width="300dp" layout_height="18dp" margin-right="4dp" />
|
||||
<PushButton id="global_search_clear_history" layout_width="wrap_content" layout_height="18dp" text="Clear History" margin-right="4dp" />
|
||||
<PushButton id="global_search" layout_width="wrap_content" layout_height="18dp" text="Search" margin-right="4dp" />
|
||||
<PushButton id="global_search_replace" layout_width="wrap_content" layout_height="18dp" text="Search & Replace" />
|
||||
</hbox>
|
||||
@@ -2325,7 +2358,7 @@ void App::init( const std::string& file, const Float& pidelDensity ) {
|
||||
</Splitter>
|
||||
<TextView id="settings" layout_width="wrap_content" layout_height="wrap_content" text="" layout_gravity="top|right" />
|
||||
</RelativeLayout>
|
||||
)xml";
|
||||
)html";
|
||||
|
||||
UIIconTheme* iconTheme = UIIconTheme::New( "remixicon" );
|
||||
mMenuIconSize = mConfig.ui.fontSize.asPixels( 0, Sizef(), mDisplayDPI );
|
||||
@@ -2374,6 +2407,8 @@ void App::init( const std::string& file, const Float& pidelDensity ) {
|
||||
{ "menu-unfold", 0xef40 },
|
||||
{ "menu-fold", 0xef3d },
|
||||
{ "download-cloud", 0xec58 },
|
||||
{ "layout-left", 0xee94 },
|
||||
{ "layout-right", 0xee9b },
|
||||
};
|
||||
for ( const auto& icon : icons )
|
||||
iconTheme->add( UIGlyphIcon::New( icon.first, iconFont, icon.second ) );
|
||||
@@ -2397,6 +2432,8 @@ void App::init( const std::string& file, const Float& pidelDensity ) {
|
||||
mDocInfo->setVisible( mConfig.editor.showDocInfo );
|
||||
|
||||
mProjectSplitter->setSplitPartition( StyleSheetLength( mConfig.window.panelPartition ) );
|
||||
if ( mConfig.ui.panelPosition == PanelPosition::Right )
|
||||
mProjectSplitter->swap();
|
||||
|
||||
if ( !mConfig.ui.showSidePanel )
|
||||
showSidePanel( mConfig.ui.showSidePanel );
|
||||
|
||||
@@ -238,6 +238,8 @@ class App : public UICodeEditorSplitter::Client {
|
||||
|
||||
void switchSidePanel();
|
||||
|
||||
void panelPosition( const PanelPosition& panelPosition );
|
||||
|
||||
void removeFolderWatches();
|
||||
|
||||
void createDocAlert( UICodeEditor* editor );
|
||||
|
||||
@@ -103,13 +103,13 @@ void DocSearchController::initSearchBar( UISearchBar* searchBar ) {
|
||||
mSearchBarLayout->getKeyBindings().addKeybindsString(
|
||||
{ { mApp->getKeybind( "repeat-find" ), "repeat-find" },
|
||||
{ mApp->getKeybind( "find-prev" ), "find-prev" },
|
||||
{ "ctrl+g", "repeat-find" },
|
||||
{ "mod+g", "repeat-find" },
|
||||
{ "escape", "close-searchbar" },
|
||||
{ "ctrl+r", "replace-all" },
|
||||
{ "ctrl+s", "change-case" },
|
||||
{ "ctrl+w", "change-whole-word" },
|
||||
{ "ctrl+l", "toggle-lua-pattern" },
|
||||
{ "ctrl+e", "change-escape-sequence" } } );
|
||||
{ "mod+r", "replace-all" },
|
||||
{ "mod+s", "change-case" },
|
||||
{ "mod+w", "change-whole-word" },
|
||||
{ "mod+l", "toggle-lua-pattern" },
|
||||
{ "mod+e", "change-escape-sequence" } } );
|
||||
addReturnListener( findInput, "repeat-find" );
|
||||
addReturnListener( replaceInput, "find-and-replace" );
|
||||
addClickListener( mSearchBarLayout->find<UIPushButton>( "find_prev" ), "find-prev" );
|
||||
|
||||
@@ -38,6 +38,11 @@ void FormatterModule::onRegister( UICodeEditor* editor ) {
|
||||
return;
|
||||
|
||||
doc.setCommand( "format-doc", [&, editor]() { formatDoc( editor ); } );
|
||||
|
||||
editor->addEventListener( Event::OnDocumentSave, [&]( const Event* event ) {
|
||||
if ( mAutoFormatOnSave && event->getNode()->isType( UI_TYPE_CODEEDITOR ) )
|
||||
formatDoc( event->getNode()->asType<UICodeEditor>() );
|
||||
} );
|
||||
}
|
||||
|
||||
void FormatterModule::onUnregister( UICodeEditor* editor ) {
|
||||
@@ -46,6 +51,14 @@ void FormatterModule::onUnregister( UICodeEditor* editor ) {
|
||||
mEditors.erase( editor );
|
||||
}
|
||||
|
||||
bool FormatterModule::getAutoFormatOnSave() const {
|
||||
return mAutoFormatOnSave;
|
||||
}
|
||||
|
||||
void FormatterModule::setAutoFormatOnSave( bool autoFormatOnSave ) {
|
||||
mAutoFormatOnSave = autoFormatOnSave;
|
||||
}
|
||||
|
||||
void FormatterModule::load( const std::string& formatterPath ) {
|
||||
if ( !FileSystem::fileExists( formatterPath ) )
|
||||
return;
|
||||
|
||||
@@ -24,6 +24,10 @@ class FormatterModule : public UICodeEditorModule {
|
||||
|
||||
void onUnregister( UICodeEditor* );
|
||||
|
||||
bool getAutoFormatOnSave() const;
|
||||
|
||||
void setAutoFormatOnSave( bool autoFormatOnSave );
|
||||
|
||||
protected:
|
||||
enum class FormatterType { Inplace, Output };
|
||||
|
||||
@@ -36,8 +40,9 @@ class FormatterModule : public UICodeEditorModule {
|
||||
std::shared_ptr<ThreadPool> mPool;
|
||||
std::vector<Formatter> mFormatters;
|
||||
std::set<UICodeEditor*> mEditors;
|
||||
bool mClosing{ false };
|
||||
|
||||
bool mAutoFormatOnSave{ false };
|
||||
bool mClosing{ false };
|
||||
bool mReady{ false };
|
||||
|
||||
void load( const std::string& formatterPath );
|
||||
|
||||
@@ -59,6 +59,8 @@ void GlobalSearchController::initGlobalSearchBar( UIGlobalSearchBar* globalSearc
|
||||
UIPushButton* searchButton = mGlobalSearchBarLayout->find<UIPushButton>( "global_search" );
|
||||
UIPushButton* searchReplaceButton =
|
||||
mGlobalSearchBarLayout->find<UIPushButton>( "global_search_replace" );
|
||||
UIPushButton* searchClearHistory =
|
||||
mGlobalSearchBarLayout->find<UIPushButton>( "global_search_clear_history" );
|
||||
UICheckBox* caseSensitiveChk = mGlobalSearchBarLayout->find<UICheckBox>( "case_sensitive" );
|
||||
UICheckBox* wholeWordChk = mGlobalSearchBarLayout->find<UICheckBox>( "whole_word" );
|
||||
UICheckBox* luaPatternChk = mGlobalSearchBarLayout->find<UICheckBox>( "lua_pattern" );
|
||||
@@ -68,6 +70,7 @@ void GlobalSearchController::initGlobalSearchBar( UIGlobalSearchBar* globalSearc
|
||||
|
||||
mGlobalSearchHistoryList =
|
||||
mGlobalSearchBarLayout->find<UIDropDownList>( "global_search_history" );
|
||||
mGlobalSearchBarLayout->addCommand( "global-search-clear-history", [&] { clearHistory(); } );
|
||||
mGlobalSearchBarLayout->addCommand(
|
||||
"search-in-files", [&, caseSensitiveChk, wholeWordChk, luaPatternChk, escapeSequenceChk] {
|
||||
doGlobalSearch( mGlobalSearchInput->getText(), caseSensitiveChk->isChecked(),
|
||||
@@ -108,14 +111,15 @@ void GlobalSearchController::initGlobalSearchBar( UIGlobalSearchBar* globalSearc
|
||||
} );
|
||||
mGlobalSearchBarLayout->getKeyBindings().addKeybindsString( {
|
||||
{ "escape", "close-global-searchbar" },
|
||||
{ "ctrl+s", "change-case" },
|
||||
{ "ctrl+w", "change-whole-word" },
|
||||
{ "ctrl+l", "toggle-lua-pattern" },
|
||||
{ "ctrl+r", "search-replace-in-files" },
|
||||
{ "ctrl+g", "search-again" },
|
||||
{ "ctrl+a", "expand-all" },
|
||||
{ "ctrl+shift+e", "collapse-all" },
|
||||
{ "ctrl+e", "change-escape-sequence" },
|
||||
{ "mod+s", "change-case" },
|
||||
{ "mod+w", "change-whole-word" },
|
||||
{ "mod+l", "toggle-lua-pattern" },
|
||||
{ "mod+r", "search-replace-in-files" },
|
||||
{ "mod+g", "search-again" },
|
||||
{ "mod+a", "expand-all" },
|
||||
{ "mod+shift+e", "collapse-all" },
|
||||
{ "mod+e", "change-escape-sequence" },
|
||||
{ "mod+h", "global-search-clear-history" },
|
||||
} );
|
||||
mGlobalSearchBarLayout->addCommand( "change-case", [&, caseSensitiveChk] {
|
||||
caseSensitiveChk->setChecked( !caseSensitiveChk->isChecked() );
|
||||
@@ -153,6 +157,7 @@ void GlobalSearchController::initGlobalSearchBar( UIGlobalSearchBar* globalSearc
|
||||
addClickListener( searchButton, "search-in-files" );
|
||||
addClickListener( searchReplaceButton, "search-replace-in-files" );
|
||||
addClickListener( searchBarClose, "close-global-searchbar" );
|
||||
addClickListener( searchClearHistory, "global-search-clear-history" );
|
||||
mGlobalSearchLayout = mUISceneNode
|
||||
->loadLayoutFromString( R"xml(
|
||||
<vbox id="global_search_layout" layout_width="wrap_content" layout_height="wrap_content" visible="false">
|
||||
@@ -267,6 +272,19 @@ bool GlobalSearchController::isUsingSearchReplaceTree() {
|
||||
return mGlobalSearchTreeReplace == mGlobalSearchTree;
|
||||
}
|
||||
|
||||
void GlobalSearchController::clearHistory() {
|
||||
auto listBox = mGlobalSearchHistoryList->getListBox();
|
||||
listBox->clear();
|
||||
mGlobalSearchHistory.clear();
|
||||
mGlobalSearchHistoryOnItemSelectedCb = 0;
|
||||
mGlobalSearchTree->setSearchStr( "" );
|
||||
mGlobalSearchTree->setModel( nullptr );
|
||||
mGlobalSearchInput->setText( "" );
|
||||
mGlobalSearchLayout->findByClass( "status_box" )->setVisible( false );
|
||||
mGlobalSearchLayout->findByClass<UITextView>( "search_str" )->setText( "" );
|
||||
updateGlobalSearchBar();
|
||||
}
|
||||
|
||||
void GlobalSearchController::updateGlobalSearchBar() {
|
||||
mGlobalSearchBarLayout->runOnMainThread( [&] {
|
||||
Float width = eeceil( mGlobalSearchInput->getPixelsSize().getWidth() );
|
||||
|
||||
@@ -36,6 +36,7 @@ class GlobalSearchController {
|
||||
|
||||
bool isUsingSearchReplaceTree();
|
||||
|
||||
void clearHistory();
|
||||
protected:
|
||||
UICodeEditorSplitter* mEditorSplitter{ nullptr };
|
||||
UISceneNode* mUISceneNode{ nullptr };
|
||||
|
||||
@@ -234,7 +234,8 @@ void LinterModule::runLinter( std::shared_ptr<TextDocument> doc, const Linter& l
|
||||
|
||||
std::map<Int64, std::vector<LinterMatch>> matches;
|
||||
|
||||
for ( auto& warningPatterm : linter.warningPattern ) {
|
||||
for ( auto warningPatterm : linter.warningPattern ) {
|
||||
String::replaceAll( warningPatterm, "$FILENAME", path );
|
||||
LuaPattern pattern( warningPatterm );
|
||||
for ( auto& match : pattern.gmatch( data ) ) {
|
||||
LinterMatch linterMatch;
|
||||
|
||||
@@ -34,7 +34,9 @@ static String textLine( const std::string& fileText, const size_t& fromPos, size
|
||||
}
|
||||
end = ptr - stringStartPtr;
|
||||
relCol = String( fileText.substr( start, startPtr - nlStartPtr ) ).size();
|
||||
return fileText.substr( start, end - start );
|
||||
// if the line to substract is massive we only get the fist kilobyte of that line, since the
|
||||
// line is only shared for visual aid.
|
||||
return fileText.substr( start, end - start > EE_1KB ? EE_1KB : end - start );
|
||||
}
|
||||
|
||||
static std::vector<ProjectSearch::ResultData::Result>
|
||||
|
||||
@@ -124,16 +124,13 @@ class ProjectSearch {
|
||||
} else {
|
||||
switch ( index.column() ) {
|
||||
case FileOrPosition:
|
||||
return Variant( String::format( "%6lld %s",
|
||||
mResult[index.internalId()]
|
||||
.results[index.row()]
|
||||
.position.start()
|
||||
.line() +
|
||||
1,
|
||||
mResult[index.internalId()]
|
||||
.results[index.row()]
|
||||
.line.toUtf8()
|
||||
.c_str() ) );
|
||||
return Variant(
|
||||
String( String::format( "%6lld ", mResult[index.internalId()]
|
||||
.results[index.row()]
|
||||
.position.start()
|
||||
.line() +
|
||||
1 ) ) +
|
||||
mResult[index.internalId()].results[index.row()].line );
|
||||
}
|
||||
}
|
||||
} else if ( role == ModelRole::Custom ) {
|
||||
|
||||
@@ -101,18 +101,21 @@ ProjectSearch::ResultData* UITreeViewCellGlobalSearch::getResultDataPtr() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#define CELL_GLOBAL_SEARCH_PADDING ( 12 )
|
||||
|
||||
UITreeViewCellGlobalSearch::UITreeViewCellGlobalSearch( bool selectionEnabled ) :
|
||||
UITreeViewCell( selectionEnabled ? getCheckBoxFn() : nullptr ) {}
|
||||
|
||||
UIPushButton* UITreeViewCellGlobalSearch::setText( const String& text ) {
|
||||
auto* result = getResultPtr();
|
||||
if ( text != mTextBox->getText() ||
|
||||
( result && std::make_pair<size_t, size_t>( result->position.start().column() + 12,
|
||||
result->position.end().column() + 12 ) !=
|
||||
mSearchStrPos ) ) {
|
||||
( result &&
|
||||
std::make_pair<size_t, size_t>(
|
||||
result->position.start().column() + CELL_GLOBAL_SEARCH_PADDING,
|
||||
result->position.end().column() + CELL_GLOBAL_SEARCH_PADDING ) != mSearchStrPos ) ) {
|
||||
mTextBox->setVisible( !text.empty() );
|
||||
mTextBox->setText( text );
|
||||
updateText( text + '\n' );
|
||||
updateText( text + "\n" );
|
||||
updateLayout();
|
||||
}
|
||||
return this;
|
||||
@@ -122,7 +125,8 @@ UIPushButton* UITreeViewCellGlobalSearch::updateText( const std::string& text )
|
||||
if ( getCurIndex().internalId() != -1 ) {
|
||||
UITreeViewGlobalSearch* pp = getParent()->getParent()->asType<UITreeViewGlobalSearch>();
|
||||
|
||||
ProjectSearch::ResultData* res = (ProjectSearch::ResultData*)getCurIndex().parent().internalData();
|
||||
ProjectSearch::ResultData* res =
|
||||
(ProjectSearch::ResultData*)getCurIndex().parent().internalData();
|
||||
|
||||
auto styleDef = SyntaxDefinitionManager::instance()->getStyleByExtension( res->file );
|
||||
|
||||
@@ -134,8 +138,8 @@ UIPushButton* UITreeViewCellGlobalSearch::updateText( const std::string& text )
|
||||
}
|
||||
|
||||
auto* result = getResultPtr();
|
||||
mSearchStrPos = { result->position.start().column() + 12,
|
||||
result->position.end().column() + 12 };
|
||||
mSearchStrPos = { result->position.start().column() + CELL_GLOBAL_SEARCH_PADDING,
|
||||
result->position.end().column() + CELL_GLOBAL_SEARCH_PADDING };
|
||||
|
||||
const String& txt = mTextBox->getText();
|
||||
|
||||
@@ -193,6 +197,8 @@ void UITreeViewCellGlobalSearch::draw() {
|
||||
UICheckBox* chk = mTextBox->asType<UICheckBox>();
|
||||
screenPos.x += chk->getRealAlignOffset().x;
|
||||
}
|
||||
if ( mSearchStrPos.second >= mTextBox->getText().length() )
|
||||
return;
|
||||
p.drawRectangle( Rectf(
|
||||
{ screenPos.x + mTextBox->getPixelsPosition().x +
|
||||
getXOffsetCol( hspace, mTextBox->getTextCache()->getTabWidth(),
|
||||
|
||||
Reference in New Issue
Block a user