mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-07-15 15:32:51 +03:00
Added eterm::UITerminal.
Many changes over ecode. Working on adding terminal support in ecode. Basic support is working, may contain some bugs.
This commit is contained in:
@@ -12,12 +12,14 @@ namespace EE {
|
||||
|
||||
class EE_API AllocatedPointer {
|
||||
public:
|
||||
AllocatedPointer( void* Data, const std::string& File, int Line, size_t Memory );
|
||||
AllocatedPointer( void* data, const std::string& File, int Line, size_t memory,
|
||||
bool track = false );
|
||||
|
||||
std::string mFile;
|
||||
int mLine;
|
||||
size_t mMemory;
|
||||
void* mData;
|
||||
bool mTrack;
|
||||
};
|
||||
|
||||
typedef std::map<void*, AllocatedPointer> AllocatedPointerMap;
|
||||
@@ -27,31 +29,31 @@ class EE_API MemoryManager {
|
||||
public:
|
||||
static void* addPointer( const AllocatedPointer& aAllocatedPointer );
|
||||
|
||||
static void* addPointerInPlace( void* Place, const AllocatedPointer& aAllocatedPointer );
|
||||
static void* addPointerInPlace( void* place, const AllocatedPointer& aAllocatedPointer );
|
||||
|
||||
static bool removePointer( void* Data );
|
||||
static bool removePointer( void* data, const char* file, const size_t& line );
|
||||
|
||||
static void showResults();
|
||||
|
||||
template <class T> static T* deletePtr( T* Data ) {
|
||||
delete Data;
|
||||
return Data;
|
||||
template <class T> static T* deletePtr( T* data ) {
|
||||
delete data;
|
||||
return data;
|
||||
}
|
||||
|
||||
template <class T> static T* deleteArrayPtr( T* Data ) {
|
||||
delete[] Data;
|
||||
return Data;
|
||||
template <class T> static T* deleteArrayPtr( T* data ) {
|
||||
delete[] data;
|
||||
return data;
|
||||
}
|
||||
|
||||
template <class T> static T* free( T* Data ) {
|
||||
::free( Data );
|
||||
template <class T> static T* free( T* data ) {
|
||||
::free( data );
|
||||
#if defined( __GNUC__ ) && __GNUC__ >= 12
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wuse-after-free"
|
||||
return Data;
|
||||
return data;
|
||||
#pragma GCC diagnostic pop
|
||||
#else
|
||||
return Data;
|
||||
return data;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -67,6 +69,10 @@ class EE_API MemoryManager {
|
||||
};
|
||||
|
||||
#ifdef EE_MEMORY_MANAGER
|
||||
#define eeNewTracked( classType, constructor ) \
|
||||
(classType*)EE::MemoryManager::addPointer( EE::AllocatedPointer( \
|
||||
new classType constructor, __FILE__, __LINE__, sizeof( classType ), true ) )
|
||||
|
||||
#define eeNew( classType, constructor ) \
|
||||
(classType*)EE::MemoryManager::addPointer( EE::AllocatedPointer( \
|
||||
new classType constructor, __FILE__, __LINE__, sizeof( classType ) ) )
|
||||
@@ -84,25 +90,30 @@ class EE_API MemoryManager {
|
||||
EE::MemoryManager::addPointer( EE::AllocatedPointer( EE::MemoryManager::allocate( amount ), \
|
||||
__FILE__, __LINE__, amount ) )
|
||||
|
||||
#define eeDelete( data ) \
|
||||
{ \
|
||||
if ( EE::MemoryManager::removePointer( EE::MemoryManager::deletePtr( data ) ) == false ) \
|
||||
printf( "Deleting at '%s' %d\n", __FILE__, __LINE__ ); \
|
||||
#define eeDelete( data ) \
|
||||
{ \
|
||||
if ( EE::MemoryManager::removePointer( EE::MemoryManager::deletePtr( data ), __FILE__, \
|
||||
__LINE__ ) == false ) \
|
||||
printf( "Deleting at '%s' %d\n", __FILE__, __LINE__ ); \
|
||||
}
|
||||
|
||||
#define eeDeleteArray( data ) \
|
||||
{ \
|
||||
if ( EE::MemoryManager::removePointer( EE::MemoryManager::deleteArrayPtr( data ) ) == \
|
||||
false ) \
|
||||
printf( "Deleting at '%s' %d\n", __FILE__, __LINE__ ); \
|
||||
#define eeDeleteArray( data ) \
|
||||
{ \
|
||||
if ( EE::MemoryManager::removePointer( EE::MemoryManager::deleteArrayPtr( data ), \
|
||||
__FILE__, __LINE__ ) == false ) \
|
||||
printf( "Deleting at '%s' %d\n", __FILE__, __LINE__ ); \
|
||||
}
|
||||
|
||||
#define eeFree( data ) \
|
||||
{ \
|
||||
if ( EE::MemoryManager::removePointer( EE::MemoryManager::free( data ) ) == false ) \
|
||||
printf( "Deleting at '%s' %d\n", __FILE__, __LINE__ ); \
|
||||
#define eeFree( data ) \
|
||||
{ \
|
||||
if ( EE::MemoryManager::removePointer( EE::MemoryManager::free( data ), __FILE__, \
|
||||
__LINE__ ) == false ) \
|
||||
printf( "Deleting at '%s' %d\n", __FILE__, __LINE__ ); \
|
||||
}
|
||||
#else
|
||||
|
||||
#define eeNewTracked( classType, constructor ) new classType constructor
|
||||
|
||||
#define eeNew( classType, constructor ) new classType constructor
|
||||
|
||||
#define eeNewInPlace( place, classType, constructor ) new place classType constructor
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define EE_UICUIEVENT_HPP
|
||||
|
||||
#include <eepp/config.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace EE { namespace Scene {
|
||||
|
||||
@@ -85,6 +86,7 @@ class EE_API Event {
|
||||
OnMenuShow,
|
||||
OnMenuHide,
|
||||
OnEditorTabReady,
|
||||
OnTitleChange,
|
||||
NoEvent = eeINDEX_NOT_FOUND
|
||||
};
|
||||
|
||||
@@ -115,6 +117,17 @@ class EE_API DropEvent : public Event {
|
||||
Node* droppedNode;
|
||||
};
|
||||
|
||||
class EE_API TextEvent : public Event {
|
||||
public:
|
||||
TextEvent( Node* node, const Uint32& eventType, const std::string& txt ) :
|
||||
Event( node, eventType ), text( txt ) {}
|
||||
|
||||
const std::string& getText() const { return text; }
|
||||
|
||||
protected:
|
||||
std::string text;
|
||||
};
|
||||
|
||||
}} // namespace EE::Scene
|
||||
|
||||
#endif
|
||||
|
||||
@@ -217,6 +217,8 @@ class EE_API Node : public Transformable {
|
||||
|
||||
void sendCommonEvent( const Uint32& Event );
|
||||
|
||||
void sendTextEvent( const Uint32& event, const std::string& text );
|
||||
|
||||
void childsCloseAll();
|
||||
|
||||
const std::string& getId() const;
|
||||
|
||||
@@ -123,6 +123,10 @@ class EE_API IniFile {
|
||||
int getValueI( std::string const keyname, std::string const valuename,
|
||||
int const defValue = 0 ) const;
|
||||
|
||||
/** Gets the value as an unsigned long */
|
||||
unsigned long getValueU( std::string const keyname, std::string const valuename,
|
||||
unsigned long const defValue = 0 ) const;
|
||||
|
||||
/** Gets the value as boolean */
|
||||
bool getValueB( std::string const keyname, std::string const valuename,
|
||||
bool const defValue = false ) const;
|
||||
@@ -164,6 +168,15 @@ class EE_API IniFile {
|
||||
bool setValueI( std::string const keyname, std::string const valuename, int const value,
|
||||
bool create = true );
|
||||
|
||||
/** Sets a unsigned long value from a keyname and a valuename
|
||||
* @param keyname The key name
|
||||
* @param valuename The value name
|
||||
* @param value The value to assign
|
||||
* @param create If true it will create the keyname if doesn't exists
|
||||
*/
|
||||
bool setValueU( std::string const keyname, std::string const valuename,
|
||||
unsigned long const value, bool create = true );
|
||||
|
||||
/** Sets a boolean value from a keyname and a valuename
|
||||
* @param keyname The key name
|
||||
* @param valuename The value name
|
||||
|
||||
@@ -284,6 +284,8 @@ class EE_API TextDocument {
|
||||
|
||||
void execute( const std::string& command );
|
||||
|
||||
void setCommands( const std::map<std::string, DocumentCommand>& cmds );
|
||||
|
||||
void setCommand( const std::string& command, DocumentCommand func );
|
||||
|
||||
bool hasCommand( const std::string& command );
|
||||
|
||||
@@ -26,6 +26,8 @@ class EE_API UICodeEditorSplitter {
|
||||
|
||||
virtual void onCodeEditorFocusChange( UICodeEditor* editor ) = 0;
|
||||
|
||||
virtual void onWidgetFocusChange( UIWidget* widget ) = 0;
|
||||
|
||||
virtual void onDocumentStateChanged( UICodeEditor* editor, TextDocument& doc ) = 0;
|
||||
|
||||
virtual void onDocumentModified( UICodeEditor* editor, TextDocument& doc ) = 0;
|
||||
@@ -39,18 +41,20 @@ class EE_API UICodeEditorSplitter {
|
||||
virtual void onDocumentLoaded( UICodeEditor* codeEditor, const std::string& path ) = 0;
|
||||
};
|
||||
|
||||
static std::vector<std::string> getUnlockedCommands();
|
||||
|
||||
static UICodeEditorSplitter* New( UICodeEditorSplitter::Client* client, UISceneNode* sceneNode,
|
||||
const std::vector<SyntaxColorScheme>& colorSchemes = {},
|
||||
const std::string& initColorScheme = "" );
|
||||
|
||||
virtual ~UICodeEditorSplitter();
|
||||
|
||||
virtual bool tryTabClose( UICodeEditor* editor );
|
||||
virtual bool tryTabClose(UIWidget* widget );
|
||||
|
||||
void closeEditorTab( UICodeEditor* editor );
|
||||
void closeTab( UIWidget* widget );
|
||||
|
||||
UISplitter* splitEditor( const SplitDirection& direction, UICodeEditor* editor,
|
||||
bool openCurEditor = true );
|
||||
UISplitter* split( const SplitDirection& direction, UIWidget* editor,
|
||||
bool openCurEditor = true );
|
||||
|
||||
void switchToTab( Int32 index );
|
||||
|
||||
@@ -66,10 +70,18 @@ class EE_API UICodeEditorSplitter {
|
||||
|
||||
UITabWidget* tabWidgetFromEditor( UICodeEditor* editor ) const;
|
||||
|
||||
UITabWidget* tabWidgetFromWidget( UIWidget* widget ) const;
|
||||
|
||||
UISplitter* splitterFromEditor( UICodeEditor* editor ) const;
|
||||
|
||||
UISplitter* splitterFromWidget( UIWidget* widget ) const;
|
||||
|
||||
std::pair<UITab*, UICodeEditor*> createCodeEditorInTabWidget( UITabWidget* tabWidget );
|
||||
|
||||
std::pair<UITab*, UIWidget*> createWidgetInTabWidget( UITabWidget* tabWidget, UIWidget* widget,
|
||||
const std::string& tabName,
|
||||
bool focus = true );
|
||||
|
||||
UICodeEditor* createCodeEditor();
|
||||
|
||||
void focusSomeEditor( Node* searchFrom = nullptr );
|
||||
@@ -101,6 +113,8 @@ class EE_API UICodeEditorSplitter {
|
||||
|
||||
void applyColorScheme( const SyntaxColorScheme& colorScheme );
|
||||
|
||||
void forEachWidgetStoppable( std::function<bool( UIWidget* )> run ) const;
|
||||
|
||||
void forEachEditor( std::function<void( UICodeEditor* )> run ) const;
|
||||
|
||||
void forEachDoc( std::function<void( TextDocument& doc )> run ) const;
|
||||
@@ -149,9 +163,16 @@ class EE_API UICodeEditorSplitter {
|
||||
|
||||
Node* getBaseLayout() const;
|
||||
|
||||
UIWidget* getCurWidget() const;
|
||||
|
||||
void setCurentWidget( UIWidget* curWidget );
|
||||
|
||||
bool curWidgetExists() const;
|
||||
|
||||
protected:
|
||||
UISceneNode* mUISceneNode{ nullptr };
|
||||
UICodeEditor* mCurEditor{ nullptr };
|
||||
UIWidget* mCurWidget{ nullptr };
|
||||
std::map<std::string, SyntaxColorScheme> mColorSchemes;
|
||||
std::string mCurrentColorScheme;
|
||||
std::vector<UITabWidget*> mTabWidgets;
|
||||
|
||||
@@ -99,7 +99,9 @@ enum UINodeType {
|
||||
UI_TYPE_TABLEVIEW,
|
||||
UI_TYPE_TABLECELL,
|
||||
UI_TYPE_LISTVIEW,
|
||||
UI_TYPE_USER = 10000
|
||||
UI_TYPE_MODULES = 10000,
|
||||
UI_TYPE_TERMINAL = 10001,
|
||||
UI_TYPE_USER = 100000
|
||||
};
|
||||
|
||||
enum class ScrollBarMode : Uint32 { Auto, AlwaysOn, AlwaysOff };
|
||||
|
||||
@@ -54,6 +54,8 @@ class EE_API UITabWidget : public UIWidget {
|
||||
|
||||
UITabWidget* add( UITab* tab );
|
||||
|
||||
UITab* getTabFromOwnedWidget( const UIWidget* widget );
|
||||
|
||||
UITab* getTab( const Uint32& index );
|
||||
|
||||
UITab* getTab( const String& text );
|
||||
|
||||
14
premake4.lua
14
premake4.lua
@@ -348,7 +348,7 @@ function build_base_cpp_configuration( package_name )
|
||||
set_xcode_config()
|
||||
|
||||
configuration "debug"
|
||||
defines { "DEBUG" }
|
||||
defines { "DEBUG", "EE_DEBUG", "EE_MEMORY_MANAGER" }
|
||||
flags { "Symbols" }
|
||||
if not is_vs() then
|
||||
buildoptions{ "-Wall" }
|
||||
@@ -1179,16 +1179,20 @@ solution "eepp"
|
||||
set_kind()
|
||||
language "C++"
|
||||
files { "src/tools/ecode/**.cpp" }
|
||||
includedirs { "src/thirdparty/efsw/include", "src/thirdparty" }
|
||||
links { "efsw-static" }
|
||||
|
||||
includedirs { "src/thirdparty/efsw/include", "src/thirdparty", "src/modules/eterm/include/" }
|
||||
links { "efsw-static", "eterm-static" }
|
||||
if not os.is("windows") and not os.is("haiku") then
|
||||
links { "pthread" }
|
||||
end
|
||||
if os.is("macosx") then
|
||||
links { "CoreFoundation.framework", "CoreServices.framework" }
|
||||
end
|
||||
|
||||
if os.is_real("linux") then
|
||||
links { "util" }
|
||||
end
|
||||
if os.is("haiku") then
|
||||
links { "bsd" }
|
||||
end
|
||||
build_link_configuration( "ecode", true )
|
||||
|
||||
project "eterm"
|
||||
|
||||
10
premake5.lua
10
premake5.lua
@@ -195,7 +195,7 @@ function build_base_cpp_configuration( package_name )
|
||||
buildoptions { "-Wall" }
|
||||
|
||||
filter "configurations:debug*"
|
||||
defines { "DEBUG" }
|
||||
defines { "DEBUG", "EE_DEBUG", "EE_MEMORY_MANAGER" }
|
||||
symbols "On"
|
||||
targetname ( package_name .. "-debug" )
|
||||
|
||||
@@ -926,13 +926,17 @@ workspace "eepp"
|
||||
set_kind()
|
||||
language "C++"
|
||||
files { "src/tools/ecode/**.cpp" }
|
||||
incdirs { "src/thirdparty/efsw/include", "src/thirdparty" }
|
||||
links { "efsw-static" }
|
||||
incdirs { "src/thirdparty/efsw/include", "src/thirdparty", "src/modules/eterm/include/" }
|
||||
links { "efsw-static", "eterm-static" }
|
||||
build_link_configuration( "ecode", true )
|
||||
filter "system:macosx"
|
||||
links { "CoreFoundation.framework", "CoreServices.framework" }
|
||||
filter { "system:not windows", "system:not haiku" }
|
||||
links { "pthread" }
|
||||
filter "system:linux"
|
||||
links { "util" }
|
||||
filter "system:haiku"
|
||||
links { "bsd" }
|
||||
|
||||
project "eterm"
|
||||
set_kind()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 7.0.2, 2022-07-03T19:41:27. -->
|
||||
<!-- Written by QtCreator 7.0.2, 2022-07-04T12:05:43. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
@@ -107,7 +107,7 @@
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{388e5431-b31b-42b3-b9ad-9002d279d75d}</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">12</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">10</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">19</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||
|
||||
@@ -1013,6 +1013,7 @@
|
||||
../../src/modules/eterm/include/eterm/terminal/terminaldisplay.hpp
|
||||
../../src/modules/eterm/include/eterm/terminal/terminalemulator.hpp
|
||||
../../src/modules/eterm/include/eterm/terminal/terminaltypes.hpp
|
||||
../../src/modules/eterm/include/eterm/ui/uiterminal.hpp
|
||||
../../src/modules/eterm/src/eterm/system/autohandle.cpp
|
||||
../../src/modules/eterm/src/eterm/system/pipe.cpp
|
||||
../../src/modules/eterm/src/eterm/system/process.cpp
|
||||
@@ -1026,6 +1027,7 @@
|
||||
../../src/modules/eterm/src/eterm/terminal/types.hpp
|
||||
../../src/modules/eterm/src/eterm/terminal/wide.hpp
|
||||
../../src/modules/eterm/src/eterm/terminal/windowserrors.hpp
|
||||
../../src/modules/eterm/src/eterm/ui/uiterminal.cpp
|
||||
../../src/test/eetest.cpp
|
||||
../../src/tests/test_all/test.cpp
|
||||
../../src/tests/test_all/test.hpp
|
||||
|
||||
@@ -10,3 +10,5 @@
|
||||
/usr/lib64/gcc/x86_64-suse-linux/10/include
|
||||
../../src/modules/eterm/src/
|
||||
../../src/modules/eterm/include/
|
||||
../../src/modules/eterm/include/eterm/ui
|
||||
../../src/modules/eterm/src/eterm/ui
|
||||
|
||||
@@ -19,18 +19,20 @@ static size_t sPeakMemoryUsage = 0;
|
||||
static AllocatedPointer sBiggestAllocation = AllocatedPointer( NULL, "", 0, 0 );
|
||||
static Mutex sAlloMutex;
|
||||
|
||||
AllocatedPointer::AllocatedPointer( void* Data, const std::string& File, int Line, size_t Memory ) {
|
||||
mData = Data;
|
||||
mFile = File;
|
||||
mLine = Line;
|
||||
mMemory = Memory;
|
||||
AllocatedPointer::AllocatedPointer( void* data, const std::string& file, int line, size_t memory,
|
||||
bool track ) {
|
||||
mData = data;
|
||||
mFile = file;
|
||||
mLine = line;
|
||||
mMemory = memory;
|
||||
mTrack = track;
|
||||
}
|
||||
|
||||
void* MemoryManager::addPointerInPlace( void* Place, const AllocatedPointer& aAllocatedPointer ) {
|
||||
AllocatedPointerMapIt it = sMapPointers.find( Place );
|
||||
void* MemoryManager::addPointerInPlace( void* place, const AllocatedPointer& aAllocatedPointer ) {
|
||||
AllocatedPointerMapIt it = sMapPointers.find( place );
|
||||
|
||||
if ( it != sMapPointers.end() ) {
|
||||
removePointer( Place );
|
||||
removePointer( place, aAllocatedPointer.mFile.c_str(), aAllocatedPointer.mLine );
|
||||
}
|
||||
|
||||
return addPointer( aAllocatedPointer );
|
||||
@@ -52,16 +54,23 @@ void* MemoryManager::addPointer( const AllocatedPointer& aAllocatedPointer ) {
|
||||
sBiggestAllocation = aAllocatedPointer;
|
||||
}
|
||||
|
||||
if ( aAllocatedPointer.mTrack )
|
||||
eePRINTL( "Allocating pointer %p at '%s' %d", aAllocatedPointer.mData,
|
||||
aAllocatedPointer.mFile.c_str(), aAllocatedPointer.mLine );
|
||||
|
||||
return aAllocatedPointer.mData;
|
||||
}
|
||||
|
||||
bool MemoryManager::removePointer( void* Data ) {
|
||||
bool MemoryManager::removePointer( void* data, const char* file, const size_t& line ) {
|
||||
Lock l( sAlloMutex );
|
||||
|
||||
AllocatedPointerMapIt it = sMapPointers.find( Data );
|
||||
AllocatedPointerMapIt it = sMapPointers.find( data );
|
||||
|
||||
if ( it->second.mTrack )
|
||||
eePRINTL( "Deleting pointer %p at '%s' %d", data, file, line );
|
||||
|
||||
if ( it == sMapPointers.end() ) {
|
||||
eePRINTL( "Trying to delete pointer %p created that does not exist!", Data );
|
||||
eePRINTL( "Trying to delete pointer %p created that does not exist!", data );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -303,6 +303,11 @@ void Node::sendCommonEvent( const Uint32& event ) {
|
||||
sendEvent( &CommonEvent );
|
||||
}
|
||||
|
||||
void Node::sendTextEvent( const Uint32& event, const std::string& text ) {
|
||||
TextEvent tevent( this, event, text );
|
||||
sendEvent( &tevent );
|
||||
}
|
||||
|
||||
Uint32 Node::onTextInput( const TextInputEvent& event ) {
|
||||
sendEvent( &event );
|
||||
return 0;
|
||||
|
||||
@@ -305,6 +305,14 @@ bool IniFile::setValueI( std::string const keyname, std::string const valuename,
|
||||
return setValue( keyname, valuename, svalue, create );
|
||||
}
|
||||
|
||||
bool IniFile::setValueU( const std::string keyname, const std::string valuename,
|
||||
const unsigned long value, bool create ) {
|
||||
char svalue[MAX_VALUEDATA];
|
||||
|
||||
String::formatBuffer( svalue, MAX_VALUEDATA, "%u", value );
|
||||
return setValue( keyname, valuename, svalue, create );
|
||||
}
|
||||
|
||||
bool IniFile::setValueF( std::string const keyname, std::string const valuename, double const value,
|
||||
bool create ) {
|
||||
char svalue[MAX_VALUEDATA];
|
||||
@@ -356,6 +364,14 @@ int IniFile::getValueI( std::string const keyname, std::string const valuename,
|
||||
return atoi( getValue( keyname, valuename, svalue ).c_str() );
|
||||
}
|
||||
|
||||
unsigned long IniFile::getValueU( const std::string keyname, const std::string valuename,
|
||||
const unsigned long defValue ) const {
|
||||
char svalue[MAX_VALUEDATA];
|
||||
|
||||
String::formatBuffer( svalue, MAX_VALUEDATA, "%u", defValue );
|
||||
return atoi( getValue( keyname, valuename, svalue ).c_str() );
|
||||
}
|
||||
|
||||
bool IniFile::getValueB( const std::string keyname, const std::string valuename,
|
||||
const bool defValue ) const {
|
||||
std::string val = getValue( keyname, valuename, defValue ? "1" : "0" );
|
||||
|
||||
@@ -1445,6 +1445,10 @@ void TextDocument::execute( const std::string& command ) {
|
||||
}
|
||||
}
|
||||
|
||||
void TextDocument::setCommands( const std::map<std::string, DocumentCommand>& cmds ) {
|
||||
mCommands.insert( cmds.begin(), cmds.end() );
|
||||
}
|
||||
|
||||
void TextDocument::setCommand( const std::string& command, TextDocument::DocumentCommand func ) {
|
||||
mCommands[command] = func;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ UICodeEditorSplitter::getLocalDefaultKeybindings() {
|
||||
{ { KEY_S, KeyMod::getDefaultModifier() }, "save-doc" },
|
||||
{ { KEY_L, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "lock-toggle" },
|
||||
{ { KEY_T, KeyMod::getDefaultModifier() }, "create-new" },
|
||||
{ { KEY_W, KeyMod::getDefaultModifier() }, "close-doc" },
|
||||
{ { KEY_W, KeyMod::getDefaultModifier() }, "close-tab" },
|
||||
{ { KEY_TAB, KeyMod::getDefaultModifier() }, "next-doc" },
|
||||
{ { KEY_TAB, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "previous-doc" },
|
||||
{ { KEY_J, KEYMOD_LALT | KEYMOD_SHIFT }, "split-left" },
|
||||
@@ -57,6 +57,24 @@ UICodeEditorSplitter::getLocalDefaultKeybindings() {
|
||||
};
|
||||
}
|
||||
|
||||
std::vector<std::string> UICodeEditorSplitter::getUnlockedCommands() {
|
||||
const std::vector<std::string> unlockedCmds{ "lock-toggle",
|
||||
"create-new",
|
||||
"close-tab",
|
||||
"next-doc",
|
||||
"previous-doc",
|
||||
"split-left",
|
||||
"split-right",
|
||||
"split-top",
|
||||
"split-bottom",
|
||||
"split-swap",
|
||||
"switch-to-previous-split",
|
||||
"switch-to-next-split",
|
||||
"switch-to-previous-colorscheme",
|
||||
"switch-to-next-colorscheme" };
|
||||
return unlockedCmds;
|
||||
}
|
||||
|
||||
UICodeEditorSplitter* UICodeEditorSplitter::New( UICodeEditorSplitter::Client* client,
|
||||
UISceneNode* sceneNode,
|
||||
const std::vector<SyntaxColorScheme>& colorSchemes,
|
||||
@@ -89,12 +107,26 @@ UITabWidget* UICodeEditorSplitter::tabWidgetFromEditor( UICodeEditor* editor ) c
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UITabWidget* UICodeEditorSplitter::tabWidgetFromWidget( UIWidget* widget ) const {
|
||||
if ( widget )
|
||||
return ( (UITab*)widget->getData() )->getTabWidget();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UISplitter* UICodeEditorSplitter::splitterFromEditor( UICodeEditor* editor ) const {
|
||||
if ( editor && editor->getParent()->getParent()->getParent()->isType( UI_TYPE_SPLITTER ) )
|
||||
return editor->getParent()->getParent()->getParent()->asType<UISplitter>();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UISplitter* UICodeEditorSplitter::splitterFromWidget( UIWidget* widget ) const {
|
||||
if ( widget && widget->getParent() && widget->getParent()->getParent() &&
|
||||
widget->getParent()->getParent()->getParent() &&
|
||||
widget->getParent()->getParent()->getParent()->isType( UI_TYPE_SPLITTER ) )
|
||||
return widget->getParent()->getParent()->getParent()->asType<UISplitter>();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UICodeEditor* UICodeEditorSplitter::createCodeEditor() {
|
||||
UICodeEditor* editor = UICodeEditor::NewOpt( false, true );
|
||||
TextDocument& doc = editor->getDocument();
|
||||
@@ -187,7 +219,7 @@ UICodeEditor* UICodeEditorSplitter::createCodeEditor() {
|
||||
} );
|
||||
doc.setCommand( "switch-to-previous-split", [&] { switchPreviousSplit( mCurEditor ); } );
|
||||
doc.setCommand( "switch-to-next-split", [&] { switchNextSplit( mCurEditor ); } );
|
||||
doc.setCommand( "close-doc", [&] { tryTabClose( mCurEditor ); } );
|
||||
doc.setCommand( "close-tab", [&] { tryTabClose( mCurEditor ); } );
|
||||
doc.setCommand( "create-new", [&] {
|
||||
auto d = createCodeEditorInTabWidget( tabWidgetFromEditor( mCurEditor ) );
|
||||
d.first->getTabWidget()->setTabSelected( d.first );
|
||||
@@ -223,12 +255,12 @@ UICodeEditor* UICodeEditorSplitter::createCodeEditor() {
|
||||
switchToTab( tabWidget->getTabCount() - 1 );
|
||||
}
|
||||
} );
|
||||
doc.setCommand( "split-right", [&] { splitEditor( SplitDirection::Right, mCurEditor ); } );
|
||||
doc.setCommand( "split-bottom", [&] { splitEditor( SplitDirection::Bottom, mCurEditor ); } );
|
||||
doc.setCommand( "split-left", [&] { splitEditor( SplitDirection::Left, mCurEditor ); } );
|
||||
doc.setCommand( "split-top", [&] { splitEditor( SplitDirection::Top, mCurEditor ); } );
|
||||
doc.setCommand( "split-right", [&] { split( SplitDirection::Right, mCurWidget ); } );
|
||||
doc.setCommand( "split-bottom", [&] { split( SplitDirection::Bottom, mCurWidget ); } );
|
||||
doc.setCommand( "split-left", [&] { split( SplitDirection::Left, mCurWidget ); } );
|
||||
doc.setCommand( "split-top", [&] { split( SplitDirection::Top, mCurWidget ); } );
|
||||
doc.setCommand( "split-swap", [&] {
|
||||
if ( UISplitter* splitter = splitterFromEditor( mCurEditor ) )
|
||||
if ( UISplitter* splitter = splitterFromWidget( mCurWidget ) )
|
||||
splitter->swap();
|
||||
} );
|
||||
doc.setCommand( "open-containing-folder", [&] {
|
||||
@@ -257,11 +289,7 @@ UICodeEditor* UICodeEditorSplitter::createCodeEditor() {
|
||||
event->getNode()->asType<UICodeEditor>()->getDocument() );
|
||||
} );
|
||||
editor->addKeyBinds( getLocalDefaultKeybindings() );
|
||||
editor->addUnlockedCommands( { "lock-toggle", "create-new", "close-doc", "next-doc",
|
||||
"previous-doc", "split-left", "split-right", "split-top",
|
||||
"split-bottom", "split-swap", "switch-to-previous-split",
|
||||
"switch-to-next-split", "switch-to-previous-colorscheme",
|
||||
"switch-to-next-colorscheme" } );
|
||||
editor->addUnlockedCommands( getUnlockedCommands() );
|
||||
|
||||
if ( nullptr == mCurEditor ) {
|
||||
mAboutToAddEditor = editor;
|
||||
@@ -386,16 +414,31 @@ void UICodeEditorSplitter::loadAsyncFileFromPathInNewTab(
|
||||
void UICodeEditorSplitter::setCurrentEditor( UICodeEditor* editor ) {
|
||||
eeASSERT( checkEditorExists( editor ) );
|
||||
bool isNew = mCurEditor != editor;
|
||||
bool isNewW = mCurWidget != editor;
|
||||
mCurEditor = editor;
|
||||
mCurWidget = editor;
|
||||
if ( isNewW )
|
||||
mClient->onWidgetFocusChange( editor );
|
||||
if ( isNew )
|
||||
mClient->onCodeEditorFocusChange( editor );
|
||||
if ( editor )
|
||||
mClient->onDocumentStateChanged( editor, editor->getDocument() );
|
||||
}
|
||||
|
||||
void UICodeEditorSplitter::setCurentWidget( UIWidget* curWidget ) {
|
||||
if ( curWidget->isType( UI_TYPE_CODEEDITOR ) ) {
|
||||
setCurrentEditor( curWidget->asType<UICodeEditor>() );
|
||||
return;
|
||||
}
|
||||
bool isNewW = mCurWidget != curWidget;
|
||||
mCurWidget = curWidget;
|
||||
if ( isNewW )
|
||||
mClient->onWidgetFocusChange( curWidget );
|
||||
}
|
||||
|
||||
std::pair<UITab*, UICodeEditor*>
|
||||
UICodeEditorSplitter::createCodeEditorInTabWidget( UITabWidget* tabWidget ) {
|
||||
eeASSERT( curEditorExists() );
|
||||
eeASSERT( curWidgetExists() );
|
||||
if ( nullptr == tabWidget )
|
||||
return std::make_pair( (UITab*)nullptr, (UICodeEditor*)nullptr );
|
||||
UICodeEditor* editor = createCodeEditor();
|
||||
@@ -413,8 +456,34 @@ UICodeEditorSplitter::createCodeEditorInTabWidget( UITabWidget* tabWidget ) {
|
||||
return std::make_pair( tab, editor );
|
||||
}
|
||||
|
||||
std::pair<UITab*, UIWidget*>
|
||||
UICodeEditorSplitter::createWidgetInTabWidget( UITabWidget* tabWidget, UIWidget* widget,
|
||||
const std::string& tabName, bool focus ) {
|
||||
eeASSERT( curWidgetExists() );
|
||||
if ( nullptr == tabWidget )
|
||||
return std::make_pair( (UITab*)nullptr, (UIWidget*)nullptr );
|
||||
UITab* tab = tabWidget->add( tabName, widget );
|
||||
widget->setData( (UintPtr)tab );
|
||||
widget->addEventListener( Event::OnFocus, [&]( const Event* event ) {
|
||||
setCurentWidget( event->getNode()->asType<UIWidget>() );
|
||||
} );
|
||||
widget->addEventListener( Event::OnTitleChange, [&]( const Event* event ) {
|
||||
const TextEvent* tevent = static_cast<const TextEvent*>( event );
|
||||
UIWidget* widget = event->getNode()->asType<UIWidget>();
|
||||
UITabWidget* tabWidget = tabWidgetFromWidget( widget );
|
||||
UITab* tab = tabWidget->getTabFromOwnedWidget( widget );
|
||||
if ( !tab )
|
||||
return;
|
||||
tab->setText( tevent->getText() );
|
||||
} );
|
||||
if ( focus )
|
||||
tabWidget->setTabSelected( tab );
|
||||
return std::make_pair( tab, widget );
|
||||
}
|
||||
|
||||
void UICodeEditorSplitter::removeUnusedTab( UITabWidget* tabWidget ) {
|
||||
if ( tabWidget && tabWidget->getTabCount() >= 2 &&
|
||||
tabWidget->getTab( 0 )->getOwnedWidget()->isType( UI_TYPE_CODEEDITOR ) &&
|
||||
tabWidget->getTab( 0 )
|
||||
->getOwnedWidget()
|
||||
->asType<UICodeEditor>()
|
||||
@@ -425,7 +494,7 @@ void UICodeEditorSplitter::removeUnusedTab( UITabWidget* tabWidget ) {
|
||||
}
|
||||
|
||||
UITabWidget* UICodeEditorSplitter::createEditorWithTabWidget( Node* parent, bool openCurEditor ) {
|
||||
eeASSERT( curEditorExists() );
|
||||
eeASSERT( curWidgetExists() );
|
||||
if ( nullptr == mBaseLayout )
|
||||
mBaseLayout = parent;
|
||||
UICodeEditor* prevCurEditor = mCurEditor;
|
||||
@@ -439,11 +508,19 @@ UITabWidget* UICodeEditorSplitter::createEditorWithTabWidget( Node* parent, bool
|
||||
tabWidget->setAllowSwitchTabsInEmptySpaces( true );
|
||||
tabWidget->addEventListener( Event::OnTabSelected, [&]( const Event* event ) {
|
||||
UITabWidget* tabWidget = event->getNode()->asType<UITabWidget>();
|
||||
setCurrentEditor( tabWidget->getTabSelected()->getOwnedWidget()->asType<UICodeEditor>() );
|
||||
if ( tabWidget->getTabSelected()->getOwnedWidget()->isType( UI_TYPE_CODEEDITOR ) ) {
|
||||
setCurrentEditor(
|
||||
tabWidget->getTabSelected()->getOwnedWidget()->asType<UICodeEditor>() );
|
||||
} else {
|
||||
setCurentWidget( tabWidget->getTabSelected()->getOwnedWidget()->asType<UIWidget>() );
|
||||
}
|
||||
} );
|
||||
tabWidget->setTabTryCloseCallback( [&]( UITab* tab ) -> bool {
|
||||
tryTabClose( tab->getOwnedWidget()->asType<UICodeEditor>() );
|
||||
return false;
|
||||
if ( tab->getOwnedWidget()->isType( UI_TYPE_CODEEDITOR ) ) {
|
||||
tryTabClose( tab->getOwnedWidget()->asType<UICodeEditor>() );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} );
|
||||
tabWidget->addEventListener( Event::OnTabClosed, [&]( const Event* event ) {
|
||||
onTabClosed( static_cast<const TabEvent*>( event ) );
|
||||
@@ -467,6 +544,8 @@ UITab* UICodeEditorSplitter::isDocumentOpen( const std::string& path,
|
||||
return nullptr;
|
||||
for ( size_t i = 0; i < tabWidget->getTabCount(); i++ ) {
|
||||
UITab* tab = tabWidget->getTab( i );
|
||||
if ( !tab->getOwnedWidget()->isType( UI_TYPE_CODEEDITOR ) )
|
||||
continue;
|
||||
UICodeEditor* editor = tab->getOwnedWidget()->asType<UICodeEditor>();
|
||||
|
||||
if ( editor->getDocument().getFilePath() == path ) {
|
||||
@@ -477,6 +556,8 @@ UITab* UICodeEditorSplitter::isDocumentOpen( const std::string& path,
|
||||
for ( auto tabWidget : mTabWidgets ) {
|
||||
for ( size_t i = 0; i < tabWidget->getTabCount(); i++ ) {
|
||||
UITab* tab = tabWidget->getTab( i );
|
||||
if ( !tab->getOwnedWidget()->isType( UI_TYPE_CODEEDITOR ) )
|
||||
continue;
|
||||
UICodeEditor* editor = tab->getOwnedWidget()->asType<UICodeEditor>();
|
||||
|
||||
if ( editor->getDocument().getFilePath() == path ) {
|
||||
@@ -496,8 +577,10 @@ void UICodeEditorSplitter::applyColorScheme( const SyntaxColorScheme& colorSchem
|
||||
|
||||
void UICodeEditorSplitter::forEachEditor( std::function<void( UICodeEditor* )> run ) const {
|
||||
for ( auto tabWidget : mTabWidgets )
|
||||
for ( size_t i = 0; i < tabWidget->getTabCount(); i++ )
|
||||
run( tabWidget->getTab( i )->getOwnedWidget()->asType<UICodeEditor>() );
|
||||
for ( size_t i = 0; i < tabWidget->getTabCount(); i++ ) {
|
||||
if ( tabWidget->getTab( i )->getOwnedWidget()->isType( UI_TYPE_CODEEDITOR ) )
|
||||
run( tabWidget->getTab( i )->getOwnedWidget()->asType<UICodeEditor>() );
|
||||
}
|
||||
}
|
||||
|
||||
void UICodeEditorSplitter::forEachDoc( std::function<void( TextDocument& )> run ) const {
|
||||
@@ -516,7 +599,19 @@ void UICodeEditorSplitter::forEachEditorStoppable(
|
||||
std::function<bool( UICodeEditor* )> run ) const {
|
||||
for ( auto tabWidget : mTabWidgets ) {
|
||||
for ( size_t i = 0; i < tabWidget->getTabCount(); i++ ) {
|
||||
if ( run( tabWidget->getTab( i )->getOwnedWidget()->asType<UICodeEditor>() ) ) {
|
||||
if ( tabWidget->getTab( i )->getOwnedWidget()->isType( UI_TYPE_CODEEDITOR ) &&
|
||||
run( tabWidget->getTab( i )->getOwnedWidget()->asType<UICodeEditor>() ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UICodeEditorSplitter::forEachWidgetStoppable( std::function<bool( UIWidget* )> run ) const {
|
||||
for ( auto tabWidget : mTabWidgets ) {
|
||||
for ( size_t i = 0; i < tabWidget->getTabCount(); i++ ) {
|
||||
if ( tabWidget->getTab( i )->getOwnedWidget()->isWidget() &&
|
||||
run( tabWidget->getTab( i )->getOwnedWidget()->asType<UIWidget>() ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -526,7 +621,8 @@ void UICodeEditorSplitter::forEachEditorStoppable(
|
||||
void UICodeEditorSplitter::forEachDocStoppable( std::function<bool( TextDocument& )> run ) const {
|
||||
for ( auto tabWidget : mTabWidgets ) {
|
||||
for ( size_t i = 0; i < tabWidget->getTabCount(); i++ ) {
|
||||
if ( run( *tabWidget->getTab( i )
|
||||
if ( tabWidget->getTab( i )->getOwnedWidget()->isType( UI_TYPE_CODEEDITOR ) &&
|
||||
run( *tabWidget->getTab( i )
|
||||
->getOwnedWidget()
|
||||
->asType<UICodeEditor>()
|
||||
->getDocumentRef()
|
||||
@@ -568,6 +664,10 @@ Node* UICodeEditorSplitter::getBaseLayout() const {
|
||||
return mBaseLayout;
|
||||
}
|
||||
|
||||
UIWidget* UICodeEditorSplitter::getCurWidget() const {
|
||||
return mCurWidget;
|
||||
}
|
||||
|
||||
std::vector<UICodeEditor*> UICodeEditorSplitter::getAllEditors() {
|
||||
std::vector<UICodeEditor*> editors;
|
||||
forEachEditor( [&]( UICodeEditor* editor ) { editors.push_back( editor ); } );
|
||||
@@ -598,50 +698,65 @@ void UICodeEditorSplitter::zoomReset() {
|
||||
forEachEditor( []( UICodeEditor* editor ) { editor->fontSizeReset(); } );
|
||||
}
|
||||
|
||||
bool UICodeEditorSplitter::tryTabClose( UICodeEditor* editor ) {
|
||||
if ( nullptr != editor && editor->isDirty() ) {
|
||||
UIMessageBox* msgBox =
|
||||
UIMessageBox::New( UIMessageBox::OK_CANCEL,
|
||||
"Do you really want to close this tab?\nAll changes will be lost." );
|
||||
msgBox->addEventListener( Event::MsgBoxConfirmClick,
|
||||
[&, editor]( const Event* ) { closeEditorTab( editor ); } );
|
||||
msgBox->addEventListener( Event::OnClose, [&]( const Event* ) {
|
||||
msgBox = nullptr;
|
||||
if ( mCurEditor )
|
||||
mCurEditor->setFocus();
|
||||
} );
|
||||
msgBox->setTitle( "Close Tab?" );
|
||||
msgBox->center();
|
||||
msgBox->show();
|
||||
bool UICodeEditorSplitter::tryTabClose( UIWidget* widget ) {
|
||||
if ( !widget )
|
||||
return false;
|
||||
|
||||
if ( widget->isType( UI_TYPE_CODEEDITOR ) ) {
|
||||
UICodeEditor* editor = widget->asType<UICodeEditor>();
|
||||
if ( nullptr != editor && editor->isDirty() ) {
|
||||
UIMessageBox* msgBox = UIMessageBox::New(
|
||||
UIMessageBox::OK_CANCEL,
|
||||
"Do you really want to close this tab?\nAll changes will be lost." );
|
||||
msgBox->addEventListener( Event::MsgBoxConfirmClick,
|
||||
[&, editor]( const Event* ) { closeTab( editor ); } );
|
||||
msgBox->addEventListener( Event::OnClose, [&]( const Event* ) {
|
||||
msgBox = nullptr;
|
||||
if ( mCurEditor )
|
||||
mCurEditor->setFocus();
|
||||
} );
|
||||
msgBox->setTitle( "Close Tab?" );
|
||||
msgBox->center();
|
||||
msgBox->show();
|
||||
return false;
|
||||
} else {
|
||||
closeTab( editor );
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
closeEditorTab( editor );
|
||||
closeTab( widget );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void UICodeEditorSplitter::closeEditorTab( UICodeEditor* editor ) {
|
||||
if ( editor ) {
|
||||
UITabWidget* tabWidget = tabWidgetFromEditor( editor );
|
||||
if ( tabWidget ) {
|
||||
if ( !( editor->getDocument().isEmpty() &&
|
||||
!tabWidget->getParent()->isType( UI_TYPE_SPLITTER ) &&
|
||||
tabWidget->getTabCount() == 1 ) ) {
|
||||
tabWidget->removeTab( (UITab*)editor->getData() );
|
||||
void UICodeEditorSplitter::closeTab( UIWidget* widget ) {
|
||||
if ( widget ) {
|
||||
if ( widget->isType( UI_TYPE_CODEEDITOR ) ) {
|
||||
UICodeEditor* editor = widget->asType<UICodeEditor>();
|
||||
UITabWidget* tabWidget = tabWidgetFromEditor( editor );
|
||||
if ( tabWidget ) {
|
||||
if ( !( editor->getDocument().isEmpty() &&
|
||||
!tabWidget->getParent()->isType( UI_TYPE_SPLITTER ) &&
|
||||
tabWidget->getTabCount() == 1 ) ) {
|
||||
tabWidget->removeTab( (UITab*)editor->getData() );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
UITabWidget* tabWidget = tabWidgetFromWidget( widget );
|
||||
tabWidget->removeTab( (UITab*)widget->getData() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UISplitter* UICodeEditorSplitter::splitEditor( const SplitDirection& direction,
|
||||
UICodeEditor* editor, bool openCurEditor ) {
|
||||
if ( !editor )
|
||||
UISplitter* UICodeEditorSplitter::split( const SplitDirection& direction, UIWidget* widget,
|
||||
bool openCurEditor ) {
|
||||
if ( !widget )
|
||||
return nullptr;
|
||||
UIOrientation orientation =
|
||||
direction == SplitDirection::Left || direction == SplitDirection::Right
|
||||
? UIOrientation::Horizontal
|
||||
: UIOrientation::Vertical;
|
||||
UITabWidget* tabWidget = tabWidgetFromEditor( editor );
|
||||
UITabWidget* tabWidget = tabWidgetFromWidget( widget );
|
||||
if ( !tabWidget )
|
||||
return nullptr;
|
||||
Node* parent = tabWidget->getParent();
|
||||
@@ -750,15 +865,14 @@ void UICodeEditorSplitter::switchNextSplit( UICodeEditor* editor ) {
|
||||
|
||||
void UICodeEditorSplitter::focusSomeEditor( Node* searchFrom ) {
|
||||
UICodeEditor* editor =
|
||||
searchFrom ? searchFrom->findByType<UICodeEditor>( UI_TYPE_CODEEDITOR )
|
||||
: mUISceneNode->getRoot()->findByType<UICodeEditor>( UI_TYPE_CODEEDITOR );
|
||||
searchFrom && searchFrom->isType( UI_TYPE_CODEEDITOR )
|
||||
? searchFrom->findByType<UICodeEditor>( UI_TYPE_CODEEDITOR )
|
||||
: ( mBaseLayout ? mBaseLayout->findByType<UICodeEditor>( UI_TYPE_CODEEDITOR )
|
||||
: nullptr );
|
||||
|
||||
if ( searchFrom && !editor )
|
||||
editor = mUISceneNode->getRoot()->findByType<UICodeEditor>( UI_TYPE_CODEEDITOR );
|
||||
|
||||
if ( editor && tabWidgetFromEditor( editor ) && !tabWidgetFromEditor( editor )->isClosing() &&
|
||||
tabWidgetFromEditor( editor )->getTabCount() > 1 ) {
|
||||
UITabWidget* tabW = tabWidgetFromEditor( editor );
|
||||
UITabWidget* tabW = nullptr;
|
||||
if ( editor && ( tabW = tabWidgetFromEditor( editor ) ) && !tabW->isClosing() &&
|
||||
tabW->getTabCount() > 1 ) {
|
||||
if ( tabW && tabW->getTabSelected()->getOwnedWidget() != editor ) {
|
||||
tabW->setTabSelected( tabW->getTabSelected() );
|
||||
return;
|
||||
@@ -782,10 +896,6 @@ void UICodeEditorSplitter::focusSomeEditor( Node* searchFrom ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
UITabWidget* tabW = mUISceneNode->getRoot()->findByType<UITabWidget>( UI_TYPE_TABWIDGET );
|
||||
if ( tabW && tabW->getTabCount() > 0 )
|
||||
tabW->setTabSelected( tabW->getTabSelected() );
|
||||
}
|
||||
|
||||
void UICodeEditorSplitter::closeTabWidgets( UISplitter* splitter ) {
|
||||
@@ -828,6 +938,18 @@ bool UICodeEditorSplitter::curEditorExists() const {
|
||||
return found || mCurEditor == nullptr || mAboutToAddEditor == mCurEditor || mFirstCodeEditor;
|
||||
}
|
||||
|
||||
bool UICodeEditorSplitter::curWidgetExists() const {
|
||||
bool found = false;
|
||||
forEachWidgetStoppable( [&]( UIWidget* widget ) {
|
||||
if ( widget == mCurWidget ) {
|
||||
found = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} );
|
||||
return found || mCurWidget == nullptr;
|
||||
}
|
||||
|
||||
UICodeEditor* UICodeEditorSplitter::getCurEditor() const {
|
||||
eeASSERT( curEditorExists() );
|
||||
return mCurEditor;
|
||||
@@ -855,10 +977,10 @@ void UICodeEditorSplitter::closeSplitter( UISplitter* splitter ) {
|
||||
}
|
||||
|
||||
void UICodeEditorSplitter::onTabClosed( const TabEvent* tabEvent ) {
|
||||
UICodeEditor* editor = tabEvent->getTab()->getOwnedWidget()->asType<UICodeEditor>();
|
||||
UIWidget* widget = tabEvent->getTab()->getOwnedWidget()->asType<UIWidget>();
|
||||
UITabWidget* tabWidget = tabEvent->getTab()->getTabWidget();
|
||||
if ( tabWidget->getTabCount() == 0 ) {
|
||||
UISplitter* splitter = splitterFromEditor( editor );
|
||||
UISplitter* splitter = splitterFromWidget( widget );
|
||||
if ( splitter ) {
|
||||
if ( splitter->isFull() ) {
|
||||
tabWidget->close();
|
||||
@@ -903,6 +1025,7 @@ void UICodeEditorSplitter::onTabClosed( const TabEvent* tabEvent ) {
|
||||
}
|
||||
}
|
||||
mCurEditor = nullptr;
|
||||
mCurWidget = nullptr;
|
||||
auto d = createCodeEditorInTabWidget( tabWidget );
|
||||
d.first->getTabWidget()->setTabSelected( d.first );
|
||||
} else {
|
||||
@@ -912,7 +1035,7 @@ void UICodeEditorSplitter::onTabClosed( const TabEvent* tabEvent ) {
|
||||
}
|
||||
if ( tabEvent->getTab()->getOwnedWidget() == mCurEditor )
|
||||
focusSomeEditor( nullptr );
|
||||
eeASSERT( curEditorExists() );
|
||||
eeASSERT( curWidgetExists() );
|
||||
}
|
||||
|
||||
}}} // namespace EE::UI::Tools
|
||||
|
||||
@@ -216,6 +216,8 @@ UIPushButton* UITab::setText( const String& text ) {
|
||||
|
||||
tTabW->orderTabs();
|
||||
}
|
||||
|
||||
sendTextEvent( Event::OnTitleChange, mText.toUtf8() );
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -466,6 +466,18 @@ UITabWidget* UITabWidget::add( UITab* tab ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
UITab* UITabWidget::getTabFromOwnedWidget( const UIWidget* widget ) {
|
||||
for ( Uint32 i = 0; i < mTabs.size(); i++ ) {
|
||||
if ( mTabs[i]->isType( UI_TYPE_TAB ) ) {
|
||||
UITab* tTab = mTabs[i]->asType<UITab>();
|
||||
|
||||
if ( tTab->getOwnedWidget() == widget )
|
||||
return tTab;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UITab* UITabWidget::getTab( const Uint32& index ) {
|
||||
eeASSERT( index < mTabs.size() );
|
||||
return mTabs[index];
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <eepp/ui/css/stylesheetspecification.hpp>
|
||||
#include <eepp/ui/css/transitiondefinition.hpp>
|
||||
#include <eepp/ui/uiborderdrawable.hpp>
|
||||
#include <eepp/ui/uieventdispatcher.hpp>
|
||||
#include <eepp/ui/uinodedrawable.hpp>
|
||||
#include <eepp/ui/uiscenenode.hpp>
|
||||
#include <eepp/ui/uistyle.hpp>
|
||||
@@ -56,6 +57,10 @@ UIWidget::UIWidget( const std::string& tag ) :
|
||||
UIWidget::UIWidget() : UIWidget( "widget" ) {}
|
||||
|
||||
UIWidget::~UIWidget() {
|
||||
if ( mUISceneNode && mUISceneNode->getUIEventDispatcher() &&
|
||||
mUISceneNode->getUIEventDispatcher()->getNodeDragging() == this )
|
||||
mUISceneNode->getUIEventDispatcher()->setNodeDragging( nullptr );
|
||||
|
||||
if ( !SceneManager::instance()->isShootingDown() && NULL != mUISceneNode )
|
||||
mUISceneNode->onWidgetDelete( this );
|
||||
eeSAFE_DELETE( mStyle );
|
||||
|
||||
@@ -1162,6 +1162,9 @@ const Uint8& UIWindow::getBaseAlpha() const {
|
||||
}
|
||||
|
||||
void UIWindow::setTitle( const String& text ) {
|
||||
if ( mTitle && text == mTitle->getText() )
|
||||
return;
|
||||
|
||||
if ( NULL == mTitle ) {
|
||||
mTitle = UITextView::NewWithTag( "window::title" );
|
||||
mTitle->setLayoutSizePolicy( SizePolicy::Fixed, SizePolicy::Fixed );
|
||||
@@ -1177,6 +1180,7 @@ void UIWindow::setTitle( const String& text ) {
|
||||
fixTitleSize();
|
||||
|
||||
mTitle->setText( text );
|
||||
sendTextEvent( Event::OnTitleChange, text.toUtf8() );
|
||||
}
|
||||
|
||||
void UIWindow::fixTitleSize() {
|
||||
|
||||
@@ -178,7 +178,7 @@ class TerminalDisplay : public ITerminalDisplay {
|
||||
|
||||
virtual void onMouseDoubleClick( const Vector2i& pos, const Uint32& flags );
|
||||
|
||||
virtual void onMouseMotion( const Vector2i& pos, const Uint32& flags );
|
||||
virtual void onMouseMove( const Vector2i& pos, const Uint32& flags );
|
||||
|
||||
virtual void onMouseDown( const Vector2i& pos, const Uint32& flags );
|
||||
|
||||
|
||||
72
src/modules/eterm/include/eterm/ui/uiterminal.hpp
Normal file
72
src/modules/eterm/include/eterm/ui/uiterminal.hpp
Normal file
@@ -0,0 +1,72 @@
|
||||
#ifndef ETERM_UI_UITERMINAL_HPP
|
||||
#define ETERM_UI_UITERMINAL_HPP
|
||||
|
||||
#include <eepp/ui/uiwidget.hpp>
|
||||
#include <eterm/terminal/terminaldisplay.hpp>
|
||||
|
||||
using namespace EE::UI;
|
||||
using namespace eterm::Terminal;
|
||||
|
||||
namespace eterm { namespace UI {
|
||||
|
||||
class EE_API UITerminal : public UIWidget {
|
||||
public:
|
||||
static UITerminal* New( Font* font, const Float& fontSize, const Sizef& pixelsSize,
|
||||
std::string program = "", const std::vector<std::string>& args = {},
|
||||
const std::string& workingDir = "", const size_t& historySize = 10000,
|
||||
IProcessFactory* processFactory = nullptr,
|
||||
const bool& useFrameBuffer = false );
|
||||
|
||||
static UITerminal* New( const std::shared_ptr<TerminalDisplay>& terminalDisplay );
|
||||
|
||||
virtual ~UITerminal();
|
||||
|
||||
virtual Uint32 getType() const;
|
||||
|
||||
virtual bool isType( const Uint32& type ) const;
|
||||
|
||||
virtual void draw();
|
||||
|
||||
const std::shared_ptr<TerminalDisplay>& getTerm() const;
|
||||
|
||||
virtual void scheduledUpdate( const Time& time );
|
||||
|
||||
const std::string& getTitle() const;
|
||||
|
||||
void setTitle( const std::string& title );
|
||||
|
||||
protected:
|
||||
std::string mTitle;
|
||||
bool mIsCustomTitle{ false };
|
||||
bool mDraggingSel{ false };
|
||||
|
||||
UITerminal( const std::shared_ptr<TerminalDisplay>& terminalDisplay );
|
||||
|
||||
std::shared_ptr<TerminalDisplay> mTerm;
|
||||
|
||||
virtual Uint32 onTextInput( const TextInputEvent& event );
|
||||
|
||||
virtual Uint32 onKeyDown( const KeyEvent& event );
|
||||
|
||||
virtual Uint32 onKeyUp( const KeyEvent& event );
|
||||
|
||||
virtual Uint32 onMouseMove( const Vector2i& position, const Uint32& flags );
|
||||
|
||||
virtual Uint32 onMouseDown( const Vector2i& position, const Uint32& flags );
|
||||
|
||||
virtual Uint32 onMouseDoubleClick( const Vector2i& position, const Uint32& flags );
|
||||
|
||||
virtual Uint32 onMouseUp( const Vector2i& position, const Uint32& flags );
|
||||
|
||||
virtual void onPositionChange();
|
||||
|
||||
virtual void onSizeChange();
|
||||
|
||||
virtual Uint32 onFocus();
|
||||
|
||||
virtual Uint32 onFocusLoss();
|
||||
};
|
||||
|
||||
}} // namespace eterm::UI
|
||||
|
||||
#endif
|
||||
@@ -695,7 +695,7 @@ void TerminalDisplay::onMouseDoubleClick( const Vector2i& pos, const Uint32& fla
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalDisplay::onMouseMotion( const Vector2i& pos, const Uint32& flags ) {
|
||||
void TerminalDisplay::onMouseMove( const Vector2i& pos, const Uint32& flags ) {
|
||||
if ( ( flags & EE_BUTTON_LMASK ) &&
|
||||
( mTerminal->getSelectionMode() == TerminalSelectionMode::SEL_EMPTY ||
|
||||
mTerminal->getSelectionMode() == TerminalSelectionMode::SEL_READY ) ) {
|
||||
@@ -712,6 +712,28 @@ void TerminalDisplay::onMouseMotion( const Vector2i& pos, const Uint32& flags )
|
||||
void TerminalDisplay::onMouseDown( const Vector2i& pos, const Uint32& flags ) {
|
||||
auto gridPos{ positionToGrid( pos ) };
|
||||
|
||||
if ( ( flags & EE_BUTTON_LMASK ) &&
|
||||
mLastDoubleClick.getElapsedTime() < Milliseconds( 300.f ) ) {
|
||||
mTerminal->selstart( gridPos.x, gridPos.y, SNAP_LINE );
|
||||
} else if ( flags & EE_BUTTON_LMASK ) {
|
||||
if ( mTerminal->getSelectionMode() == TerminalSelectionMode::SEL_IDLE ) {
|
||||
mTerminal->selstart( gridPos.x, gridPos.y, 0 );
|
||||
invalidateLines();
|
||||
} else if ( mTerminal->getSelectionMode() == TerminalSelectionMode::SEL_READY ) {
|
||||
mTerminal->selclear();
|
||||
}
|
||||
} else if ( flags & EE_BUTTON_MMASK ) {
|
||||
auto selection = mTerminal->getSelection();
|
||||
if ( !selection.empty() ) {
|
||||
for ( auto& chr : selection )
|
||||
onTextInput( chr );
|
||||
}
|
||||
}
|
||||
mTerminal->mousereport( TerminalMouseEventType::MouseButtonDown, positionToGrid( pos ), flags,
|
||||
mWindow->getInput()->getModState() );
|
||||
}
|
||||
|
||||
void TerminalDisplay::onMouseUp( const Vector2i& pos, const Uint32& flags ) {
|
||||
Uint32 smod = sanitizeMod( mWindow->getInput()->getModState() );
|
||||
|
||||
auto scIt = terminalKeyMap.MouseShortcuts().find( flags );
|
||||
@@ -738,29 +760,6 @@ void TerminalDisplay::onMouseDown( const Vector2i& pos, const Uint32& flags ) {
|
||||
}
|
||||
}
|
||||
|
||||
if ( ( flags & EE_BUTTON_LMASK ) &&
|
||||
mLastDoubleClick.getElapsedTime() < Milliseconds( 300.f ) ) {
|
||||
mTerminal->selstart( gridPos.x, gridPos.y, SNAP_LINE );
|
||||
} else if ( flags & EE_BUTTON_LMASK ) {
|
||||
if ( mTerminal->getSelectionMode() == TerminalSelectionMode::SEL_IDLE ) {
|
||||
auto gridPos{ positionToGrid( pos ) };
|
||||
mTerminal->selstart( gridPos.x, gridPos.y, 0 );
|
||||
invalidateLines();
|
||||
} else if ( mTerminal->getSelectionMode() == TerminalSelectionMode::SEL_READY ) {
|
||||
mTerminal->selclear();
|
||||
}
|
||||
} else if ( flags & EE_BUTTON_MMASK ) {
|
||||
auto selection = mTerminal->getSelection();
|
||||
if ( !selection.empty() ) {
|
||||
for ( auto& chr : selection )
|
||||
onTextInput( chr );
|
||||
}
|
||||
}
|
||||
mTerminal->mousereport( TerminalMouseEventType::MouseButtonDown, positionToGrid( pos ), flags,
|
||||
mWindow->getInput()->getModState() );
|
||||
}
|
||||
|
||||
void TerminalDisplay::onMouseUp( const Vector2i& pos, const Uint32& flags ) {
|
||||
if ( ( flags & EE_BUTTON_LMASK ) ) {
|
||||
auto selection = mTerminal->getSelection();
|
||||
if ( !selection.empty() && selection != "\n" )
|
||||
@@ -1089,7 +1088,8 @@ void TerminalDisplay::drawGrid( const Vector2f& pos ) {
|
||||
y += lineHeight;
|
||||
}
|
||||
|
||||
if ( !mEmulator->isScrolling() && !IS_SET( MODE_HIDE ) && mDirtyCursor ) {
|
||||
if ( !mEmulator->isScrolling() && !IS_SET( MODE_HIDE ) &&
|
||||
( !mUseFrameBuffer || mDirtyCursor ) ) {
|
||||
mDirtyCursor = false;
|
||||
Color drawcol;
|
||||
if ( IS_SET( MODE_REVERSE ) ) {
|
||||
@@ -1172,7 +1172,7 @@ void TerminalDisplay::draw( const Vector2f& pos ) {
|
||||
Primitives p;
|
||||
p.setForceDraw( false );
|
||||
p.setColor( defaultBg );
|
||||
p.drawRectangle( Rectf( mPosition.asFloat(), mSize.asFloat() ) );
|
||||
p.drawRectangle( Rectf( mPosition.floor().asFloat(), mSize.asFloat() ) );
|
||||
|
||||
if ( !mFrameBuffer || mDirty )
|
||||
drawGrid( pos );
|
||||
|
||||
140
src/modules/eterm/src/eterm/ui/uiterminal.cpp
Normal file
140
src/modules/eterm/src/eterm/ui/uiterminal.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
#include <eepp/scene/scenemanager.hpp>
|
||||
#include <eepp/ui/uiscenenode.hpp>
|
||||
#include <eepp/ui/uitabwidget.hpp>
|
||||
#include <eterm/ui/uiterminal.hpp>
|
||||
|
||||
using namespace EE::Scene;
|
||||
|
||||
namespace eterm { namespace UI {
|
||||
|
||||
UITerminal* UITerminal::New( Font* font, const Float& fontSize, const Sizef& pixelsSize,
|
||||
std::string program, const std::vector<std::string>& args,
|
||||
const std::string& workingDir, const size_t& historySize,
|
||||
IProcessFactory* processFactory, const bool& useFrameBuffer ) {
|
||||
auto win = SceneManager::instance()->getUISceneNode()->getWindow();
|
||||
auto terminal =
|
||||
TerminalDisplay::create( win, font, fontSize, pixelsSize, program, args, workingDir,
|
||||
historySize, processFactory, useFrameBuffer );
|
||||
return UITerminal::New( terminal );
|
||||
}
|
||||
|
||||
UITerminal* UITerminal::New( const std::shared_ptr<TerminalDisplay>& terminalDisplay ) {
|
||||
return eeNew( UITerminal, ( terminalDisplay ) );
|
||||
}
|
||||
|
||||
UITerminal::~UITerminal() {}
|
||||
|
||||
Uint32 UITerminal::getType() const {
|
||||
return UI_TYPE_TERMINAL;
|
||||
}
|
||||
|
||||
bool UITerminal::isType( const Uint32& type ) const {
|
||||
return getType() == type || UIWidget::isType( type );
|
||||
}
|
||||
|
||||
void UITerminal::draw() {
|
||||
mTerm->setPosition( mScreenPosi.asFloat() );
|
||||
mTerm->draw();
|
||||
}
|
||||
|
||||
UITerminal::UITerminal( const std::shared_ptr<TerminalDisplay>& terminalDisplay ) :
|
||||
UIWidget( "terminal" ), mTerm( terminalDisplay ) {
|
||||
mFlags |= UI_TAB_STOP;
|
||||
mTerm->pushEventCallback( [&]( const TerminalDisplay::Event& event ) {
|
||||
if ( event.type == TerminalDisplay::EventType::TITLE && getParent() ) {
|
||||
if ( !mIsCustomTitle && mTitle != event.eventData ) {
|
||||
mTitle = event.eventData;
|
||||
sendTextEvent( Event::OnTitleChange, mTitle );
|
||||
}
|
||||
}
|
||||
} );
|
||||
subscribeScheduledUpdate();
|
||||
}
|
||||
|
||||
const std::shared_ptr<TerminalDisplay>& UITerminal::getTerm() const {
|
||||
return mTerm;
|
||||
}
|
||||
|
||||
void UITerminal::scheduledUpdate( const Time& ) {
|
||||
mTerm->update();
|
||||
if ( mTerm->isDirty() )
|
||||
invalidateDraw();
|
||||
}
|
||||
|
||||
const std::string& UITerminal::getTitle() const {
|
||||
return mTitle;
|
||||
}
|
||||
|
||||
void UITerminal::setTitle( const std::string& title ) {
|
||||
if ( title != mTitle ) {
|
||||
mTitle = title;
|
||||
mIsCustomTitle = true;
|
||||
sendTextEvent( Event::OnTitleChange, title );
|
||||
}
|
||||
}
|
||||
|
||||
Uint32 UITerminal::onTextInput( const TextInputEvent& event ) {
|
||||
mTerm->onTextInput( event.getChar() );
|
||||
return 1;
|
||||
}
|
||||
|
||||
Uint32 UITerminal::onKeyDown( const KeyEvent& event ) {
|
||||
mTerm->onKeyDown( event.getKeyCode(), event.getChar(), event.getMod(), event.getScancode() );
|
||||
return 1;
|
||||
}
|
||||
|
||||
Uint32 UITerminal::onKeyUp( const KeyEvent& ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
Uint32 UITerminal::onMouseMove( const Vector2i& position, const Uint32& flags ) {
|
||||
mTerm->onMouseMove( position, flags );
|
||||
return 1;
|
||||
}
|
||||
|
||||
Uint32 UITerminal::onMouseDown( const Vector2i& position, const Uint32& flags ) {
|
||||
if ( ( flags & EE_BUTTON_LMASK ) &&
|
||||
mTerm->getTerminal()->getSelectionMode() == TerminalSelectionMode::SEL_IDLE ) {
|
||||
mDraggingSel = true;
|
||||
} else if ( ( flags & EE_BUTTON_LMASK ) && mDraggingSel ) {
|
||||
return 1;
|
||||
}
|
||||
mTerm->onMouseDown( position, flags );
|
||||
return 1;
|
||||
}
|
||||
|
||||
Uint32 UITerminal::onMouseDoubleClick( const Vector2i& position, const Uint32& flags ) {
|
||||
mTerm->onMouseDoubleClick( position, flags );
|
||||
return 1;
|
||||
}
|
||||
|
||||
Uint32 UITerminal::onMouseUp( const Vector2i& position, const Uint32& flags ) {
|
||||
if ( ( flags & EE_BUTTON_LMASK ) && mDraggingSel )
|
||||
mDraggingSel = false;
|
||||
mTerm->onMouseUp( position, flags );
|
||||
return 1;
|
||||
}
|
||||
|
||||
void UITerminal::onPositionChange() {
|
||||
mTerm->setPosition( mScreenPosi.asFloat() );
|
||||
UIWidget::onPositionChange();
|
||||
}
|
||||
|
||||
void UITerminal::onSizeChange() {
|
||||
mTerm->setSize( getPixelsSize() );
|
||||
UIWidget::onSizeChange();
|
||||
}
|
||||
|
||||
Uint32 UITerminal::onFocus() {
|
||||
mTerm->setFocus( true );
|
||||
invalidateDraw();
|
||||
return UIWidget::onFocus();
|
||||
}
|
||||
|
||||
Uint32 UITerminal::onFocusLoss() {
|
||||
mTerm->setFocus( false );
|
||||
invalidateDraw();
|
||||
return UIWidget::onFocusLoss();
|
||||
}
|
||||
|
||||
}} // namespace eterm::UI
|
||||
@@ -229,7 +229,7 @@ json saveNode( Node* node ) {
|
||||
res["type"] = "splitter";
|
||||
res["split"] = splitter->getSplitPartition().toString();
|
||||
res["orientation"] =
|
||||
splitter->getOrientation() == UIOrientation::Horizontal ? "horizontal" : "vertial";
|
||||
splitter->getOrientation() == UIOrientation::Horizontal ? "horizontal" : "vertical";
|
||||
res["first"] = saveNode( splitter->getFirstWidget() );
|
||||
res["last"] = saveNode( splitter->getLastWidget() );
|
||||
} else if ( node->isType( UI_TYPE_TABWIDGET ) ) {
|
||||
@@ -309,7 +309,7 @@ static void loadDocuments( UICodeEditorSplitter* editorSplitter, std::shared_ptr
|
||||
curTabWidget );
|
||||
}
|
||||
} else if ( j["type"] == "splitter" ) {
|
||||
UISplitter* splitter = editorSplitter->splitEditor(
|
||||
UISplitter* splitter = editorSplitter->split(
|
||||
j["orientation"] == "horizontal" ? UICodeEditorSplitter::SplitDirection::Right
|
||||
: UICodeEditorSplitter::SplitDirection::Bottom,
|
||||
curTabWidget->getTabSelected()->getOwnedWidget()->asType<UICodeEditor>(), false );
|
||||
@@ -392,4 +392,4 @@ void AppConfig::loadProject( std::string projectFolder, UICodeEditorSplitter* ed
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace ecode
|
||||
|
||||
@@ -28,7 +28,7 @@ void DocSearchController::initSearchBar(
|
||||
auto& kbind = mSearchBarLayout->getKeyBindings();
|
||||
kbind.addKeybindsString( {
|
||||
{ mApp->getKeybind( "repeat-find" ), "repeat-find" },
|
||||
{ mApp->getKeybind( "find-prev" ), "find-prev" },
|
||||
{ mApp->getKeybind( "find-prev" ), "find-prev" }
|
||||
} );
|
||||
kbind.addKeybindsStringUnordered( keybindings );
|
||||
|
||||
@@ -104,8 +104,8 @@ void DocSearchController::initSearchBar(
|
||||
} );
|
||||
mSearchBarLayout->addCommand( "close-searchbar", [&] {
|
||||
hideSearchBar();
|
||||
if ( mEditorSplitter->getCurEditor() )
|
||||
mEditorSplitter->getCurEditor()->setFocus();
|
||||
if ( mEditorSplitter->getCurWidget() )
|
||||
mEditorSplitter->getCurWidget()->setFocus();
|
||||
if ( mSearchState.editor ) {
|
||||
if ( mEditorSplitter->editorExists( mSearchState.editor ) ) {
|
||||
mSearchState.editor->setHighlightWord( "" );
|
||||
|
||||
@@ -17,8 +17,7 @@ void appLoop() {
|
||||
}
|
||||
|
||||
bool App::onCloseRequestCallback( EE::Window::Window* ) {
|
||||
if ( nullptr != mEditorSplitter->getCurEditor() &&
|
||||
mEditorSplitter->getCurEditor()->isDirty() ) {
|
||||
if ( mEditorSplitter->isAnyEditorDirty() ) {
|
||||
UIMessageBox* msgBox = UIMessageBox::New(
|
||||
UIMessageBox::OK_CANCEL,
|
||||
i18n( "confirm_ecode_exit",
|
||||
@@ -152,9 +151,9 @@ void App::openFileDialog() {
|
||||
loadFileFromPath( file );
|
||||
} );
|
||||
dialog->addEventListener( Event::OnWindowClose, [&]( const Event* ) {
|
||||
if ( mEditorSplitter && mEditorSplitter->getCurEditor() &&
|
||||
if ( mEditorSplitter && mEditorSplitter->getCurWidget() &&
|
||||
!SceneManager::instance()->isShootingDown() )
|
||||
mEditorSplitter->getCurEditor()->setFocus();
|
||||
mEditorSplitter->getCurWidget()->setFocus();
|
||||
} );
|
||||
dialog->center();
|
||||
dialog->show();
|
||||
@@ -174,9 +173,9 @@ void App::openFolderDialog() {
|
||||
loadFolder( path );
|
||||
} );
|
||||
dialog->addEventListener( Event::OnWindowClose, [&]( const Event* ) {
|
||||
if ( mEditorSplitter && mEditorSplitter->getCurEditor() &&
|
||||
if ( mEditorSplitter && mEditorSplitter->getCurWidget() &&
|
||||
!SceneManager::instance()->isShootingDown() )
|
||||
mEditorSplitter->getCurEditor()->setFocus();
|
||||
mEditorSplitter->getCurWidget()->setFocus();
|
||||
} );
|
||||
dialog->center();
|
||||
dialog->show();
|
||||
@@ -198,9 +197,9 @@ void App::openFontDialog( std::string& fontPath, bool loadingMonoFont ) {
|
||||
dialog->setTitle( "Select Font File" );
|
||||
dialog->setCloseShortcut( KEY_ESCAPE );
|
||||
dialog->addEventListener( Event::OnWindowClose, [&]( const Event* ) {
|
||||
if ( mEditorSplitter && mEditorSplitter->getCurEditor() &&
|
||||
if ( mEditorSplitter && mEditorSplitter->getCurWidget() &&
|
||||
!SceneManager::instance()->isShootingDown() )
|
||||
mEditorSplitter->getCurEditor()->setFocus();
|
||||
mEditorSplitter->getCurWidget()->setFocus();
|
||||
} );
|
||||
dialog->addEventListener( Event::OpenFile, [&, loadingMonoFont]( const Event* event ) {
|
||||
auto newPath = event->getNode()->asType<UIFileDialog>()->getFullPath();
|
||||
@@ -658,8 +657,8 @@ UIMenu* App::createWindowMenu() {
|
||||
"New UI scale factor assigned.\nPlease restart the application." );
|
||||
msg->show();
|
||||
setFocusEditorOnClose( msg );
|
||||
} else if ( mEditorSplitter && mEditorSplitter->getCurEditor() ) {
|
||||
mEditorSplitter->getCurEditor()->setFocus();
|
||||
} else if ( mEditorSplitter && mEditorSplitter->getCurWidget() ) {
|
||||
mEditorSplitter->getCurWidget()->setFocus();
|
||||
}
|
||||
} else {
|
||||
UIMessageBox* msg = UIMessageBox::New( UIMessageBox::OK, "Invalid value!" );
|
||||
@@ -865,8 +864,8 @@ UIMenu* App::createViewMenu() {
|
||||
|
||||
void App::setFocusEditorOnClose( UIMessageBox* msgBox ) {
|
||||
msgBox->addEventListener( Event::OnClose, [&]( const Event* ) {
|
||||
if ( mEditorSplitter && mEditorSplitter->getCurEditor() )
|
||||
mEditorSplitter->getCurEditor()->setFocus();
|
||||
if ( mEditorSplitter && mEditorSplitter->getCurWidget() )
|
||||
mEditorSplitter->getCurWidget()->setFocus();
|
||||
} );
|
||||
}
|
||||
|
||||
@@ -1482,8 +1481,13 @@ void App::updateProjectSettingsMenu() {
|
||||
}
|
||||
|
||||
void App::updateDocumentMenu() {
|
||||
if ( !mEditorSplitter->getCurEditor() )
|
||||
if ( !mEditorSplitter->getCurWidget() ||
|
||||
!mEditorSplitter->getCurWidget()->isType( UI_TYPE_CODEEDITOR ) ) {
|
||||
mSettingsMenu->getItemId( "doc-menu" )->setEnabled( false );
|
||||
return;
|
||||
}
|
||||
|
||||
mSettingsMenu->getItemId( "doc-menu" )->setEnabled( true );
|
||||
|
||||
const TextDocument& doc = mEditorSplitter->getCurEditor()->getDocument();
|
||||
|
||||
@@ -1534,10 +1538,10 @@ void App::updateDocumentMenu() {
|
||||
->setActive( mEditorSplitter->getCurEditor()->isLocked() );
|
||||
}
|
||||
|
||||
static void
|
||||
updateKeybindings( IniFile& ini, const std::string& group, Input* input,
|
||||
std::unordered_map<std::string, std::string>& keybindings,
|
||||
const std::unordered_map<std::string, std::string>& defKeybindings ) {
|
||||
static void updateKeybindings( IniFile& ini, const std::string& group, Input* input,
|
||||
std::unordered_map<std::string, std::string>& keybindings,
|
||||
const std::unordered_map<std::string, std::string>& defKeybindings,
|
||||
bool forceRebind = false ) {
|
||||
KeyBindings bindings( input );
|
||||
bool added = false;
|
||||
|
||||
@@ -1552,7 +1556,7 @@ updateKeybindings( IniFile& ini, const std::string& group, Input* input,
|
||||
for ( const auto& key : keybindings )
|
||||
invertedKeybindings[key.second] = key.first;
|
||||
|
||||
if ( defKeybindings.size() != keybindings.size() ) {
|
||||
if ( defKeybindings.size() != keybindings.size() || forceRebind ) {
|
||||
for ( const auto& key : defKeybindings ) {
|
||||
auto foundCmd = invertedKeybindings.find( key.second );
|
||||
auto& shortcutStr = key.first;
|
||||
@@ -1562,6 +1566,22 @@ updateKeybindings( IniFile& ini, const std::string& group, Input* input,
|
||||
invertedKeybindings[key.second] = shortcutStr;
|
||||
ini.setValue( group, shortcutStr, key.second );
|
||||
added = true;
|
||||
} else if ( foundCmd == invertedKeybindings.end() ) {
|
||||
// Override the shortcut if the command that holds that
|
||||
// shortcut does not exists anymore
|
||||
auto kb = keybindings.find( shortcutStr );
|
||||
if ( kb != keybindings.end() ) {
|
||||
bool found = false;
|
||||
for ( const auto& val : defKeybindings )
|
||||
if ( val.second == kb->second )
|
||||
found = true;
|
||||
if ( !found ) {
|
||||
keybindings[shortcutStr] = key.second;
|
||||
invertedKeybindings[key.second] = shortcutStr;
|
||||
ini.setValue( group, shortcutStr, key.second );
|
||||
added = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1569,11 +1589,11 @@ updateKeybindings( IniFile& ini, const std::string& group, Input* input,
|
||||
ini.writeFile();
|
||||
}
|
||||
|
||||
static void
|
||||
updateKeybindings( IniFile& ini, const std::string& group, Input* input,
|
||||
std::unordered_map<std::string, std::string>& keybindings,
|
||||
std::unordered_map<std::string, std::string>& invertedKeybindings,
|
||||
const std::map<KeyBindings::Shortcut, std::string>& defKeybindings ) {
|
||||
static void updateKeybindings( IniFile& ini, const std::string& group, Input* input,
|
||||
std::unordered_map<std::string, std::string>& keybindings,
|
||||
std::unordered_map<std::string, std::string>& invertedKeybindings,
|
||||
const std::map<KeyBindings::Shortcut, std::string>& defKeybindings,
|
||||
bool forceRebind = false ) {
|
||||
KeyBindings bindings( input );
|
||||
bool added = false;
|
||||
|
||||
@@ -1587,7 +1607,7 @@ updateKeybindings( IniFile& ini, const std::string& group, Input* input,
|
||||
for ( const auto& key : keybindings )
|
||||
invertedKeybindings[key.second] = key.first;
|
||||
|
||||
if ( defKeybindings.size() != keybindings.size() ) {
|
||||
if ( defKeybindings.size() != keybindings.size() || forceRebind ) {
|
||||
for ( const auto& key : defKeybindings ) {
|
||||
auto foundCmd = invertedKeybindings.find( key.second );
|
||||
auto shortcutStr = bindings.getShortcutString( key.first );
|
||||
@@ -1597,6 +1617,22 @@ updateKeybindings( IniFile& ini, const std::string& group, Input* input,
|
||||
invertedKeybindings[key.second] = shortcutStr;
|
||||
ini.setValue( group, shortcutStr, key.second );
|
||||
added = true;
|
||||
} else if ( foundCmd == invertedKeybindings.end() ) {
|
||||
// Override the shortcut if the command that holds that
|
||||
// shortcut does not exists anymore
|
||||
auto kb = keybindings.find( shortcutStr );
|
||||
if ( kb != keybindings.end() ) {
|
||||
bool found = false;
|
||||
for ( const auto& val : defKeybindings )
|
||||
if ( val.second == kb->second )
|
||||
found = true;
|
||||
if ( !found ) {
|
||||
keybindings[shortcutStr] = key.second;
|
||||
invertedKeybindings[key.second] = shortcutStr;
|
||||
ini.setValue( group, shortcutStr, key.second );
|
||||
added = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1616,18 +1652,26 @@ void App::loadKeybindings() {
|
||||
ini.writeFile();
|
||||
}
|
||||
|
||||
bool forceRebind = false;
|
||||
auto version = ini.getValueU( "version", "version", 0 );
|
||||
if ( version != ecode::Version::getVersionNum() ) {
|
||||
ini.setValueU( "version", "version", ecode::Version::getVersionNum() );
|
||||
ini.writeFile();
|
||||
forceRebind = true;
|
||||
}
|
||||
|
||||
Uint32 defModKeyCode = KeyMod::getKeyMod( defMod );
|
||||
if ( 0 != defModKeyCode )
|
||||
if ( KEYMOD_NONE != defModKeyCode )
|
||||
KeyMod::setDefaultModifier( defModKeyCode );
|
||||
|
||||
updateKeybindings( ini, "editor", mWindow->getInput(), mKeybindings, mKeybindingsInvert,
|
||||
getDefaultKeybindings() );
|
||||
getDefaultKeybindings(), forceRebind );
|
||||
|
||||
updateKeybindings( ini, "global_search", mWindow->getInput(), mGlobalSearchKeybindings,
|
||||
GlobalSearchController::getDefaultKeybindings() );
|
||||
GlobalSearchController::getDefaultKeybindings(), forceRebind );
|
||||
|
||||
updateKeybindings( ini, "document_search", mWindow->getInput(), mDocumentSearchKeybindings,
|
||||
DocSearchController::getDefaultKeybindings() );
|
||||
DocSearchController::getDefaultKeybindings(), forceRebind );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1644,7 +1688,9 @@ void App::onDocumentCursorPosChange( UICodeEditor*, TextDocument& doc ) {
|
||||
}
|
||||
|
||||
void App::updateDocInfo( TextDocument& doc ) {
|
||||
if ( mConfig.editor.showDocInfo && mDocInfoText && mEditorSplitter->getCurEditor() ) {
|
||||
if ( mConfig.editor.showDocInfo && mDocInfoText && mEditorSplitter->getCurEditor() &&
|
||||
mEditorSplitter->getCurEditor()->isType( UI_TYPE_CODEEDITOR ) ) {
|
||||
mDocInfoText->setVisible( true );
|
||||
mDocInfoText->setText( String::format(
|
||||
"line: %lld / %lu col: %lld %s", doc.getSelection().start().line() + 1,
|
||||
doc.linesCount(), mEditorSplitter->getCurEditor()->getCurrentColumnCount(),
|
||||
@@ -1665,9 +1711,19 @@ void App::syncProjectTreeWithEditor( UICodeEditor* editor ) {
|
||||
}
|
||||
}
|
||||
|
||||
void App::onWidgetFocusChange( UIWidget* widget ) {
|
||||
if ( mConfig.editor.showDocInfo && mDocInfoText ) {
|
||||
mDocInfoText->setVisible( widget && widget->isType( UI_TYPE_CODEEDITOR ) );
|
||||
}
|
||||
updateDocumentMenu();
|
||||
if ( widget && !widget->isType( UI_TYPE_CODEEDITOR ) ) {
|
||||
if ( widget->isType( UI_TYPE_TERMINAL ) )
|
||||
setAppTitle( widget->asType<UITerminal>()->getTitle() );
|
||||
}
|
||||
}
|
||||
|
||||
void App::onCodeEditorFocusChange( UICodeEditor* editor ) {
|
||||
updateDocInfo( editor->getDocument() );
|
||||
updateDocumentMenu();
|
||||
mDocSearchController->onCodeEditorFocusChange( editor );
|
||||
syncProjectTreeWithEditor( editor );
|
||||
}
|
||||
@@ -1907,6 +1963,33 @@ NotificationCenter* App::getNotificationCenter() const {
|
||||
return mNotificationCenter.get();
|
||||
}
|
||||
|
||||
void App::createNewTerminal() {
|
||||
UIWidget* curWidget = mEditorSplitter->getCurWidget();
|
||||
if ( !curWidget )
|
||||
return;
|
||||
UITabWidget* tabWidget = mEditorSplitter->tabWidgetFromWidget( curWidget );
|
||||
if ( !tabWidget ) {
|
||||
if ( !mEditorSplitter->getTabWidgets().empty() ) {
|
||||
tabWidget = mEditorSplitter->getTabWidgets()[0];
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
UITerminal* term = UITerminal::New( mFontMono, PixelDensity::dpToPx( 11 ), Sizef( 16, 16 ) );
|
||||
mEditorSplitter->createWidgetInTabWidget( tabWidget, term, "Shell", true );
|
||||
term->addEventListener( Event::OnTitleChange, [&]( const Event* event ) {
|
||||
if ( event->getNode() != mEditorSplitter->getCurWidget() )
|
||||
return;
|
||||
setAppTitle( event->getNode()->asType<UITerminal>()->getTitle() );
|
||||
} );
|
||||
}
|
||||
|
||||
std::map<std::string, std::function<void()>> App::getGlobalCommands() {
|
||||
std::map<std::string, std::function<void()>> cmds;
|
||||
|
||||
return cmds;
|
||||
}
|
||||
|
||||
void App::onCodeEditorCreated( UICodeEditor* editor, TextDocument& doc ) {
|
||||
const CodeEditorConfig& config = mConfig.editor;
|
||||
const DocumentConfig& docc = !mCurrentProject.empty() && !mProjectDocConfig.useGlobalSettings
|
||||
@@ -1947,10 +2030,7 @@ void App::onCodeEditorCreated( UICodeEditor* editor, TextDocument& doc ) {
|
||||
doc.setCommand( "save-as-doc", [&] { saveFileDialog( mEditorSplitter->getCurEditor() ); } );
|
||||
doc.setCommand( "save-all", [&] { saveAll(); } );
|
||||
doc.setCommand( "find-replace", [&] { mDocSearchController->showFindView(); } );
|
||||
doc.setCommand( "open-global-search", [&] {
|
||||
mGlobalSearchController->showGlobalSearch(
|
||||
mGlobalSearchController->isUsingSearchReplaceTree() );
|
||||
} );
|
||||
doc.setCommand( "open-global-search", [&] { mGlobalSearchController->showGlobalSearch(); } );
|
||||
doc.setCommand( "open-locatebar", [&] { mFileLocator->showLocateBar(); } );
|
||||
doc.setCommand( "repeat-find", [&] {
|
||||
mDocSearchController->findNextText( mDocSearchController->getSearchState() );
|
||||
@@ -2013,18 +2093,20 @@ void App::onCodeEditorCreated( UICodeEditor* editor, TextDocument& doc ) {
|
||||
|
||||
msgBox->setTitle( mWindowTitle );
|
||||
msgBox->getTextInput()->setHint( "Any https or http URL" );
|
||||
msgBox->setCloseShortcut( { KEY_ESCAPE, 0 } );
|
||||
msgBox->setCloseShortcut( { KEY_ESCAPE, KEYMOD_NONE } );
|
||||
msgBox->showWhenReady();
|
||||
msgBox->addEventListener( Event::MsgBoxConfirmClick, [&, msgBox]( const Event* ) {
|
||||
std::string url( msgBox->getTextInput()->getText().toUtf8() );
|
||||
downloadFileWeb( url );
|
||||
if ( mEditorSplitter->getCurEditor() )
|
||||
mEditorSplitter->getCurEditor()->setFocus();
|
||||
if ( mEditorSplitter->getCurWidget() )
|
||||
mEditorSplitter->getCurWidget()->setFocus();
|
||||
msgBox->closeWindow();
|
||||
} );
|
||||
} );
|
||||
doc.setCommand( "move-panel-left", [&] { panelPosition( PanelPosition::Left ); } );
|
||||
doc.setCommand( "move-panel-right", [&] { panelPosition( PanelPosition::Right ); } );
|
||||
doc.setCommand( "create-new-terminal", [&] { createNewTerminal(); } );
|
||||
editor->addUnlockedCommand( "create-new-terminal" );
|
||||
|
||||
editor->addEventListener( Event::OnDocumentSave, [&]( const Event* event ) {
|
||||
UICodeEditor* editor = event->getNode()->asType<UICodeEditor>();
|
||||
@@ -2204,7 +2286,7 @@ UIPopUpMenu* App::createToolsMenu() {
|
||||
if ( txt == "Locate..." ) {
|
||||
mFileLocator->showLocateBar();
|
||||
} else if ( txt == "Project Find..." ) {
|
||||
mGlobalSearchController->showGlobalSearch();
|
||||
mGlobalSearchController->showGlobalSearch( false );
|
||||
} else if ( txt == "Go to line..." ) {
|
||||
mFileLocator->goToLine();
|
||||
} else if ( txt == "Load current document directory as folder" ) {
|
||||
@@ -2231,6 +2313,8 @@ void App::createSettingsMenu() {
|
||||
mSettingsMenu = UIPopUpMenu::New();
|
||||
mSettingsMenu->setId( "settings_menu" );
|
||||
mSettingsMenu->add( "New", findIcon( "document-new" ), getKeybind( "create-new" ) );
|
||||
mSettingsMenu->add( "New Terminal", findIcon( "terminal" ),
|
||||
getKeybind( "create-new-terminal" ) );
|
||||
mSettingsMenu->add( "Open File...", findIcon( "document-open" ), getKeybind( "open-file" ) );
|
||||
mSettingsMenu->add( "Open Folder...", findIcon( "document-open" ),
|
||||
getKeybind( "open-folder" ) );
|
||||
@@ -2268,14 +2352,14 @@ void App::createSettingsMenu() {
|
||||
fileTypeMenu->setSubMenu( newMenu );
|
||||
}
|
||||
} );
|
||||
mSettingsMenu->addSubMenu( "Document", nullptr, createDocumentMenu() );
|
||||
mSettingsMenu->addSubMenu( "Document", nullptr, createDocumentMenu() )->setId( "doc-menu" );
|
||||
mSettingsMenu->addSubMenu( "Edit", nullptr, createEditMenu() );
|
||||
mSettingsMenu->addSubMenu( "View", nullptr, createViewMenu() );
|
||||
mSettingsMenu->addSubMenu( "Tools", nullptr, createToolsMenu() );
|
||||
mSettingsMenu->addSubMenu( "Window", nullptr, createWindowMenu() );
|
||||
mSettingsMenu->addSubMenu( "Help", findIcon( "help" ), createHelpMenu() );
|
||||
mSettingsMenu->addSeparator();
|
||||
mSettingsMenu->add( "Close", findIcon( "document-close" ), getKeybind( "close-doc" ) );
|
||||
mSettingsMenu->add( "Close", findIcon( "document-close" ), getKeybind( "close-tab" ) );
|
||||
mSettingsMenu->add( "Close Folder", findIcon( "document-close" ),
|
||||
getKeybind( "close-folder" ) );
|
||||
mSettingsMenu->addSeparator();
|
||||
@@ -2289,6 +2373,8 @@ void App::createSettingsMenu() {
|
||||
const String& name = event->getNode()->asType<UIMenuItem>()->getText();
|
||||
if ( name == "New" ) {
|
||||
runCommand( "create-new" );
|
||||
} else if ( name == "New Terminal" ) {
|
||||
runCommand( "create-new-terminal" );
|
||||
} else if ( name == "Open File..." ) {
|
||||
runCommand( "open-file" );
|
||||
} else if ( name == "Open Folder..." ) {
|
||||
@@ -2302,7 +2388,7 @@ void App::createSettingsMenu() {
|
||||
} else if ( name == "Save All" ) {
|
||||
runCommand( "save-all" );
|
||||
} else if ( name == "Close" ) {
|
||||
runCommand( "close-doc" );
|
||||
runCommand( "close-tab" );
|
||||
} else if ( name == "Close Folder" ) {
|
||||
runCommand( "close-folder" );
|
||||
} else if ( name == "Quit" ) {
|
||||
@@ -2761,8 +2847,8 @@ void App::loadFolder( const std::string& path ) {
|
||||
updateRecentFolders();
|
||||
updateProjectSettingsMenu();
|
||||
|
||||
if ( mEditorSplitter->getCurEditor() )
|
||||
mEditorSplitter->getCurEditor()->setFocus();
|
||||
if ( mEditorSplitter->getCurWidget() )
|
||||
mEditorSplitter->getCurWidget()->setFocus();
|
||||
}
|
||||
|
||||
FontTrueType* App::loadFont( const std::string& name, std::string fontPath,
|
||||
@@ -3157,6 +3243,7 @@ void App::init( std::string file, const Float& pidelDensity, const std::string&
|
||||
{ "global-settings", 0xedcf },
|
||||
{ "folder-user", 0xed84 },
|
||||
{ "help", 0xf045 },
|
||||
{ "terminal", 0xf1f6 },
|
||||
};
|
||||
for ( const auto& icon : icons )
|
||||
iconTheme->add( UIGlyphIcon::New( icon.first, iconFont, icon.second ) );
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
#include "widgetcommandexecuter.hpp"
|
||||
#include <eepp/ee.hpp>
|
||||
#include <efsw/efsw.hpp>
|
||||
#include <eterm/ui/uiterminal.hpp>
|
||||
|
||||
using namespace eterm::UI;
|
||||
|
||||
namespace ecode {
|
||||
|
||||
@@ -77,6 +80,10 @@ class App : public UICodeEditorSplitter::Client {
|
||||
|
||||
NotificationCenter* getNotificationCenter() const;
|
||||
|
||||
void createNewTerminal();
|
||||
|
||||
std::map<std::string, std::function<void()>> getGlobalCommands();
|
||||
|
||||
protected:
|
||||
EE::Window::Window* mWindow{ nullptr };
|
||||
UISceneNode* mUISceneNode{ nullptr };
|
||||
@@ -230,6 +237,8 @@ class App : public UICodeEditorSplitter::Client {
|
||||
|
||||
void onDocumentCursorPosChange( UICodeEditor* editor, TextDocument& );
|
||||
|
||||
void onWidgetFocusChange( UIWidget* widget );
|
||||
|
||||
void onCodeEditorFocusChange( UICodeEditor* editor );
|
||||
|
||||
bool setAutoComplete( bool enable );
|
||||
|
||||
@@ -61,7 +61,8 @@ void FileLocator::initLocateBar( UILocateBar* locateBar, UITextInput* locateInpu
|
||||
String number( mLocateInput->getText().substr( 2 ) );
|
||||
Int64 val;
|
||||
if ( String::fromString( val, number ) && val - 1 >= 0 ) {
|
||||
mEditorSplitter->getCurEditor()->goToLine( { val - 1, 0 } );
|
||||
if ( mEditorSplitter->getCurEditor() )
|
||||
mEditorSplitter->getCurEditor()->goToLine( { val - 1, 0 } );
|
||||
mLocateTable->setVisible( false );
|
||||
}
|
||||
} else {
|
||||
@@ -84,7 +85,8 @@ void FileLocator::initLocateBar( UILocateBar* locateBar, UITextInput* locateInpu
|
||||
} );
|
||||
mLocateBarLayout->addCommand( "close-locatebar", [&] {
|
||||
hideLocateBar();
|
||||
mEditorSplitter->getCurEditor()->setFocus();
|
||||
if ( mEditorSplitter->getCurWidget() )
|
||||
mEditorSplitter->getCurWidget()->setFocus();
|
||||
} );
|
||||
mLocateBarLayout->getKeyBindings().addKeybindsString( {
|
||||
{ "escape", "close-locatebar" },
|
||||
|
||||
@@ -47,6 +47,10 @@ size_t GlobalSearchController::replaceInFiles( const std::string& replaceText,
|
||||
return count;
|
||||
}
|
||||
|
||||
void GlobalSearchController::showGlobalSearch() {
|
||||
showGlobalSearch( isUsingSearchReplaceTree() );
|
||||
}
|
||||
|
||||
void GlobalSearchController::initGlobalSearchBar(
|
||||
UIGlobalSearchBar* globalSearchBar, const GlobalSearchBarConfig& globalSearchBarConfig,
|
||||
std::unordered_map<std::string, std::string> keybindings ) {
|
||||
@@ -132,8 +136,8 @@ void GlobalSearchController::initGlobalSearchBar(
|
||||
} );
|
||||
mGlobalSearchBarLayout->addCommand( "close-global-searchbar", [&] {
|
||||
hideGlobalSearchBar();
|
||||
if ( mEditorSplitter->getCurEditor() )
|
||||
mEditorSplitter->getCurEditor()->setFocus();
|
||||
if ( mEditorSplitter->getCurWidget() )
|
||||
mEditorSplitter->getCurWidget()->setFocus();
|
||||
} );
|
||||
mGlobalSearchBarLayout->addCommand( "expand-all", [&] {
|
||||
mGlobalSearchTree->expandAll();
|
||||
|
||||
@@ -50,7 +50,9 @@ class GlobalSearchController {
|
||||
size_t replaceInFiles( const std::string& replaceText,
|
||||
std::shared_ptr<ProjectSearch::ResultModel> model );
|
||||
|
||||
void showGlobalSearch( bool searchAndReplace = false );
|
||||
void showGlobalSearch();
|
||||
|
||||
void showGlobalSearch( bool searchAndReplace );
|
||||
|
||||
void updateColorScheme( const SyntaxColorScheme& colorScheme );
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ void inputCallback( InputEvent* event ) {
|
||||
|
||||
switch ( event->Type ) {
|
||||
case InputEvent::MouseMotion: {
|
||||
terminal->onMouseMotion( win->getInput()->getMousePos(),
|
||||
terminal->onMouseMove( win->getInput()->getMousePos(),
|
||||
win->getInput()->getPressTrigger() );
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user