diff --git a/.gitignore b/.gitignore index f64754ad5..78c9c4a2f 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ src/thirdparty/SDL2-2.0.12* *.dll bin/ee* bin/eepp-* +bin/ecode* ee.tag log.log external_projects.lua diff --git a/README.md b/README.md index a3ea8bcda..b643e6143 100644 --- a/README.md +++ b/README.md @@ -346,23 +346,23 @@ that emscripten have at the moment (no threads, no access to the file system, no Note: please wait some seconds until the resources are loaded, currently there is no loading indicator. Also please use a modern browser with WebGL and WASM support. -* **[ecode - Text Editor](https://web.ensoft.dev/eepp/demo-fs.html?run=eepp-CodeEditor-debug.js)** +* **[ecode - Text Editor](https://web.ensoft.dev/eepp/demo-fs.html?run=ecode.js)** -* **[Texture Atlas Editor](https://web.ensoft.dev/eepp/demo-fs.html?run=eepp-TextureAtlasEditor-debug.js)** +* **[Texture Atlas Editor](https://web.ensoft.dev/eepp/demo-fs.html?run=eepp-TextureAtlasEditor.js)** -* **[Map Editor](https://web.ensoft.dev/eepp/demo-fs.html?run=eepp-MapEditor-debug.js)** +* **[Map Editor](https://web.ensoft.dev/eepp/demo-fs.html?run=eepp-MapEditor.js)** -* **[UI Hello World](https://web.ensoft.dev/eepp/demo-fs.html?run=eepp-ui-hello-world-debug.js)** +* **[UI Hello World](https://web.ensoft.dev/eepp/demo-fs.html?run=eepp-ui-hello-world.js)** -* **[UI Editor running some tests](https://web.ensoft.dev/eepp/demo-fs.html?run=eepp-UIEditor-debug.js)** +* **[UI Editor running some tests](https://web.ensoft.dev/eepp/demo-fs.html?run=eepp-UIEditor.js)** -* **[Fonts example](http://localhost/eepp/emscripten-fs.html?run=eepp-fonts-debug.js)** +* **[Fonts example](http://localhost/eepp/emscripten-fs.html?run=eepp-fonts.js)** -* **[Physics module demo](https://web.ensoft.dev/eepp/demo-fs.html?run=eepp-physics-debug.js)** +* **[Physics module demo](https://web.ensoft.dev/eepp/demo-fs.html?run=eepp-physics.js)** -* **[Sprites example](https://web.ensoft.dev/eepp/demo-fs.html?run=eepp-sprites-debug.js)** +* **[Sprites example](https://web.ensoft.dev/eepp/demo-fs.html?run=eepp-sprites.js)** -* **[Full Test](https://web.ensoft.dev/eepp/demo-fs.html?run=eepp-test-debug.js)** +* **[Full Test](https://web.ensoft.dev/eepp/demo-fs.html?run=eepp-test.js)** ## How to build it diff --git a/TODO.md b/TODO.md index a40f338f0..fb7b8ab22 100644 --- a/TODO.md +++ b/TODO.md @@ -27,6 +27,12 @@ Implement a simple tree view widget, to at least cover the most common use cases * Once `UITreeView` is finished add a directory/project tree view. +* Add support for function listing. + +* Change pixel density from the UI. + +* Display current line-collumn and document line count. + ## UI Editor * Integrate the `UICodeEditor` into the editor in order to be able to edit the layouts and CSS in app. diff --git a/include/eepp/scene/node.hpp b/include/eepp/scene/node.hpp index afa8c21f3..d363f2178 100644 --- a/include/eepp/scene/node.hpp +++ b/include/eepp/scene/node.hpp @@ -388,6 +388,8 @@ class EE_API Node : public Transformable { /** This removes the node from its parent. Never use this unless you know what you are doing. */ void detach(); + void forEachNode( std::function func ); + protected: typedef std::map> EventsMap; friend class EventDispatcher; diff --git a/include/eepp/ui.hpp b/include/eepp/ui.hpp index b50963368..b07e494af 100644 --- a/include/eepp/ui.hpp +++ b/include/eepp/ui.hpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -52,6 +53,9 @@ #include #include +#include +#include +#include #include #include #include diff --git a/include/eepp/ui/doc/textdocument.hpp b/include/eepp/ui/doc/textdocument.hpp index e910689cd..cbf6cd83a 100644 --- a/include/eepp/ui/doc/textdocument.hpp +++ b/include/eepp/ui/doc/textdocument.hpp @@ -323,7 +323,7 @@ class EE_API TextDocument { bool getBOM() const; - TextRange sanitizeRange( const TextRange& range ); + TextRange sanitizeRange( const TextRange& range ) const; protected: friend class UndoStack; diff --git a/include/eepp/ui/uilayout.hpp b/include/eepp/ui/uilayout.hpp index 97af1a395..baa0f9476 100644 --- a/include/eepp/ui/uilayout.hpp +++ b/include/eepp/ui/uilayout.hpp @@ -15,6 +15,8 @@ class EE_API UILayout : public UIWidget { virtual bool isType( const Uint32& type ) const; + virtual const Sizef& getSize() const; + protected: friend class UISceneNode; diff --git a/include/eepp/ui/uimessagebox.hpp b/include/eepp/ui/uimessagebox.hpp index 64839d273..6b4898417 100644 --- a/include/eepp/ui/uimessagebox.hpp +++ b/include/eepp/ui/uimessagebox.hpp @@ -1,6 +1,7 @@ #ifndef EE_UICUIMESSAGEBOX_HPP #define EE_UICUIMESSAGEBOX_HPP +#include #include #include #include @@ -49,7 +50,7 @@ class EE_API UIMessageBox : public UIWindow { UIPushButton* mButtonCancel; UITextInput* mTextInput; KeyBindings::Shortcut mCloseShortcut; - UIWidget* mLayoutCont; + UILayout* mLayoutCont; virtual void onWindowReady(); diff --git a/include/eepp/ui/uistyle.hpp b/include/eepp/ui/uistyle.hpp index f167fa8c6..6834c0d66 100644 --- a/include/eepp/ui/uistyle.hpp +++ b/include/eepp/ui/uistyle.hpp @@ -75,6 +75,8 @@ class EE_API UIStyle : public UIState { std::unordered_set& getStructurallyVolatileChilds(); + bool hasProperty( const CSS::PropertyId& propertyId ) const; + protected: UIWidget* mWidget; std::shared_ptr mElementStyle; diff --git a/include/eepp/ui/uiwidget.hpp b/include/eepp/ui/uiwidget.hpp index 5393d2d8f..659cac510 100644 --- a/include/eepp/ui/uiwidget.hpp +++ b/include/eepp/ui/uiwidget.hpp @@ -53,7 +53,7 @@ class EE_API UIWidget : public UINode { virtual Node* setId( const std::string& id ); - const Sizef& getSize() const; + virtual const Sizef& getSize() const; UITooltip* getTooltip(); diff --git a/premake4.lua b/premake4.lua index cde190d67..595a8ad55 100644 --- a/premake4.lua +++ b/premake4.lua @@ -433,8 +433,12 @@ function build_link_configuration( package_name, use_ee_icon ) end fix_shared_lib_linking_path( package_name, "libeepp-debug" ) - - targetname ( package_name .. "-debug" .. extension ) + + if not os.is_real("emscripten") then + targetname ( package_name .. "-debug" .. extension ) + else + targetname ( package_name .. extension ) + end configuration "release" defines { "NDEBUG" } @@ -1064,12 +1068,12 @@ solution "eepp" files { "src/tools/uieditor/*.cpp" } build_link_configuration( "eepp-UIEditor", true ) - project "eepp-codeeditor" + project "ecode" set_kind() language "C++" files { "src/tools/codeeditor/*.cpp" } includedirs { "src/thirdparty" } - build_link_configuration( "eepp-CodeEditor", true ) + build_link_configuration( "ecode", true ) project "eepp-texturepacker" kind "ConsoleApp" diff --git a/premake5.lua b/premake5.lua index 8061f620d..cebee0a06 100644 --- a/premake5.lua +++ b/premake5.lua @@ -118,7 +118,6 @@ function download_and_extract_dependencies() download_and_extract_sdl(remote_sdl2_devel_vc_url) elseif os.istarget("ios") then download_and_extract_sdl(remote_sdl2_devel_src_url) - os.execute("patch -t --forward -p1 -d src/thirdparty/SDL2-2.0.10/ < projects/ios/SDL2-sensors.patch") end end end @@ -236,6 +235,7 @@ function build_link_configuration( package_name, use_ee_icon ) syslibdirs { "src/thirdparty/" .. remote_sdl2_version .."/lib/x64" } filter "system:emscripten" + targetname ( package_name .. extension ) linkoptions{ "-O2 -s TOTAL_MEMORY=67108864 -s ASM_JS=1 -s VERBOSE=1 -s DISABLE_EXCEPTION_CATCHING=0 -s USE_SDL=2 -s ERROR_ON_UNDEFINED_SYMBOLS=0 -s ERROR_ON_MISSING_LIBRARIES=0 -s FULL_ES3=1 -s \"BINARYEN_TRAP_MODE='clamp'\"" } buildoptions { "-fno-strict-aliasing -O2 -s USE_SDL=2 -s PRECISE_F32=1 -s ENVIRONMENT=web" } @@ -822,12 +822,12 @@ workspace "eepp" filter { "system:not windows", "system:not haiku" } links { "pthread" } - project "eepp-codeeditor" + project "ecode" set_kind() language "C++" files { "src/tools/codeeditor/*.cpp" } incdirs { "src/thirdparty" } - build_link_configuration( "eepp-CodeEditor", true ) + build_link_configuration( "ecode", true ) project "eepp-texturepacker" kind "ConsoleApp" diff --git a/projects/linux/ee.creator.user b/projects/linux/ee.creator.user index 2a5da4a2d..057dfcf17 100644 --- a/projects/linux/ee.creator.user +++ b/projects/linux/ee.creator.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -1843,8 +1843,8 @@ 2 - %{buildDir}../../../bin/eepp-CodeEditor-debug - eepp-CodeEditor-debug + %{buildDir}../../../bin/ecode-debug + ecode-debug ProjectExplorer.CustomExecutableRunConfiguration ../src/eepp/ui/doc/textdocument.cpp diff --git a/src/eepp/scene/node.cpp b/src/eepp/scene/node.cpp index 82c67533e..edd3fbed2 100644 --- a/src/eepp/scene/node.cpp +++ b/src/eepp/scene/node.cpp @@ -903,6 +903,15 @@ void Node::detach() { } } +void Node::forEachNode( std::function func ) { + func( this ); + Node* node = mChild; + while ( node ) { + node->forEachNode( func ); + node = node->getNextNode(); + } +} + void Node::onSceneChange() { mSceneNode = findSceneNode(); diff --git a/src/eepp/ui/doc/textdocument.cpp b/src/eepp/ui/doc/textdocument.cpp index 15ded651f..a96cd9cdc 100644 --- a/src/eepp/ui/doc/textdocument.cpp +++ b/src/eepp/ui/doc/textdocument.cpp @@ -414,7 +414,7 @@ bool TextDocument::hasSelection() const { } String TextDocument::getText( const TextRange& range ) const { - TextRange nrange = range.normalized(); + TextRange nrange = sanitizeRange( range.normalized() ); if ( nrange.start().line() == nrange.end().line() ) { return mLines[nrange.start().line()].substr( nrange.start().column(), nrange.end().column() - nrange.start().column() ); @@ -1043,7 +1043,7 @@ void TextDocument::print() const { printf( "%s", mLines[i].toUtf8().c_str() ); } -TextRange TextDocument::sanitizeRange( const TextRange& range ) { +TextRange TextDocument::sanitizeRange( const TextRange& range ) const { return {sanitizePosition( range.start() ), sanitizePosition( range.end() )}; } diff --git a/src/eepp/ui/uicodeeditor.cpp b/src/eepp/ui/uicodeeditor.cpp index 2fe0ae88e..7a76bd855 100644 --- a/src/eepp/ui/uicodeeditor.cpp +++ b/src/eepp/ui/uicodeeditor.cpp @@ -34,6 +34,7 @@ const std::map UICodeEditor::getDefaultKeybi {{KEY_BACKSPACE, KEYMOD_SHIFT}, "delete-to-previous-char"}, {{KEY_BACKSPACE, 0}, "delete-to-previous-char"}, {{KEY_DELETE, KEYMOD_CTRL}, "delete-to-next-word"}, + {{KEY_DELETE, KEYMOD_SHIFT}, "delete-to-next-word"}, {{KEY_DELETE, 0}, "delete-to-next-char"}, {{KEY_KP_ENTER, KEYMOD_CTRL | KEYMOD_SHIFT}, "new-line-above"}, {{KEY_RETURN, KEYMOD_CTRL | KEYMOD_SHIFT}, "new-line-above"}, @@ -1676,17 +1677,23 @@ void UICodeEditor::drawSelectionMatch( const std::pair& lineRange, return; TextRange selection = mDoc->getSelection( true ); const String& selectionLine = mDoc->line( selection.start().line() ).getText(); - String text( selectionLine.substr( selection.start().column(), - selection.end().column() - selection.start().column() ) ); - drawWordMatch( text, lineRange, startScroll, lineHeight ); + if ( selection.start().column() >= 0 && + selection.start().column() < (Int64)selectionLine.size() && + selection.end().column() >= 0 && selection.end().column() < (Int64)selectionLine.size() ) { + String text( selectionLine.substr( + selection.start().column(), selection.end().column() - selection.start().column() ) ); + if ( !text.empty() ) + drawWordMatch( text, lineRange, startScroll, lineHeight ); + } } void UICodeEditor::drawWordMatch( const String& text, const std::pair& lineRange, const Vector2f& startScroll, const Float& lineHeight ) { + if ( text.empty() ) + return; Primitives primitives; primitives.setForceDraw( false ); primitives.setColor( Color( mSelectionMatchColor ).blendAlpha( mAlpha ) ); - for ( auto ln = lineRange.first; ln <= lineRange.second; ln++ ) { const String& line = mDoc->line( ln ).getText(); size_t pos = 0; diff --git a/src/eepp/ui/uilayout.cpp b/src/eepp/ui/uilayout.cpp index 7371ee488..4f4bd9b65 100644 --- a/src/eepp/ui/uilayout.cpp +++ b/src/eepp/ui/uilayout.cpp @@ -63,6 +63,12 @@ bool UILayout::isType( const Uint32& type ) const { return UILayout::getType() == type ? true : UIWidget::isType( type ); } +const Sizef& UILayout::getSize() const { + if ( mDirtyLayout ) + const_cast( this )->updateLayout(); + return UIWidget::getSize(); +} + void UILayout::updateLayout() {} void UILayout::setLayoutDirty() { diff --git a/src/eepp/ui/uimessagebox.cpp b/src/eepp/ui/uimessagebox.cpp index a8bffb2b9..a01091341 100644 --- a/src/eepp/ui/uimessagebox.cpp +++ b/src/eepp/ui/uimessagebox.cpp @@ -90,6 +90,9 @@ UIMessageBox::UIMessageBox( const Type& type, const String& message, const Uint3 reloadStyle( true, true ); applyDefaultTheme(); + + setMinWindowSize( mLayoutCont->getSize() ); + center(); } UIMessageBox::~UIMessageBox() {} diff --git a/src/eepp/ui/uistyle.cpp b/src/eepp/ui/uistyle.cpp index b5bdae3b5..3cec86366 100644 --- a/src/eepp/ui/uistyle.cpp +++ b/src/eepp/ui/uistyle.cpp @@ -179,6 +179,11 @@ std::unordered_set& UIStyle::getStructurallyVolatileChilds() { return mStructurallyVolatileChilds; } +bool UIStyle::hasProperty( const CSS::PropertyId& propertyId ) const { + return ( mGlobalDefinition && mGlobalDefinition->getProperty( (Uint32)propertyId ) ) || + ( mElementStyle && mElementStyle->getPropertyById( propertyId ) ); +} + void UIStyle::subscribeRelated( UIWidget* widget ) { mRelatedWidgets.insert( widget ); } diff --git a/src/eepp/ui/uiwindow.cpp b/src/eepp/ui/uiwindow.cpp index a78749189..5429a91e1 100644 --- a/src/eepp/ui/uiwindow.cpp +++ b/src/eepp/ui/uiwindow.cpp @@ -1360,10 +1360,11 @@ UIWindow* UIWindow::setMinWindowSize( const Float& width, const Float& height ) } UIWindow* UIWindow::setMinWindowSize( Sizef size ) { - mStyleConfig.MinWindowSize = size; - - applyMinWinSize(); + if ( mStyleConfig.MinWindowSize != size ) { + mStyleConfig.MinWindowSize = size; + applyMinWinSize(); + } return this; } @@ -1655,18 +1656,16 @@ void UIWindow::addKeyBindingString( const std::string& shortcut, const std::stri mKeyBindings.addKeybindString( shortcut, command ); } -void UIWindow::addKeyBinding( const KeyBindings::Shortcut& shortcut, - const std::string& command ) { +void UIWindow::addKeyBinding( const KeyBindings::Shortcut& shortcut, const std::string& command ) { mKeyBindings.addKeybind( shortcut, command ); } -void UIWindow::replaceKeyBindingString( const std::string& shortcut, - const std::string& command ) { +void UIWindow::replaceKeyBindingString( const std::string& shortcut, const std::string& command ) { mKeyBindings.replaceKeybindString( shortcut, command ); } void UIWindow::replaceKeyBinding( const KeyBindings::Shortcut& shortcut, - const std::string& command ) { + const std::string& command ) { mKeyBindings.replaceKeybind( shortcut, command ); } @@ -1679,7 +1678,7 @@ void UIWindow::addKeyBinds( const std::map& } void UIWindow::setKeyBindingCommand( const std::string& command, - UIWindow::KeyBindingCommand func ) { + UIWindow::KeyBindingCommand func ) { mKeyBindingCommands[command] = func; } diff --git a/src/tools/codeeditor/codeeditor.cpp b/src/tools/codeeditor/codeeditor.cpp index e4522c282..96ea9b390 100644 --- a/src/tools/codeeditor/codeeditor.cpp +++ b/src/tools/codeeditor/codeeditor.cpp @@ -380,7 +380,6 @@ void App::initSearchBar() { mSearchState.editor->setHighlightWord( "" ); mSearchState.editor->setHighlightTextRange( TextRange() ); } - mSearchState.reset(); } } ); mSearchBarLayout->addCommand( "repeat-find", [this] { findNextText( mSearchState ); } ); @@ -650,14 +649,28 @@ UIMenu* App::createViewMenu() { mEditorSplitter->getCurEditor()->setFocus(); } ); } else if ( item->getText() == "UI Font Size" ) { - UIMessageBox* msgBox = UIMessageBox::New( UIMessageBox::INPUT, - "Set the UI font size (requires restart):" ); + UIMessageBox* msgBox = UIMessageBox::New( + UIMessageBox::INPUT, "Set the UI font size:" ); msgBox->setTitle( mWindowTitle ); msgBox->getTextInput()->setText( mConfig.ui.fontSize.toString() ); msgBox->setCloseShortcut( {KEY_ESCAPE, 0} ); msgBox->show(); msgBox->addEventListener( Event::MsgBoxConfirmClick, [&, msgBox]( const Event* ) { mConfig.ui.fontSize = StyleSheetLength( msgBox->getTextInput()->getText() ); + Float fontSize = mConfig.ui.fontSize.asDp( 0, Sizef(), mDisplayDPI ); + UIThemeManager* manager = mUISceneNode->getUIThemeManager(); + manager->setDefaultFontSize( fontSize ); + manager->getDefaultTheme()->setDefaultFontSize( fontSize ); + mUISceneNode->forEachNode( [&]( Node* node ) { + if ( node->isType( UI_TYPE_TEXTVIEW ) ) { + UITextView* textView = node->asType(); + if ( !textView->getUIStyle()->hasProperty( PropertyId::FontSize ) ) { + textView->setFontSize( mConfig.ui.fontSize.asDp( + node->getParent()->getPixelsSize().getWidth(), Sizef(), + mUISceneNode->getDPI() ) ); + } + } + } ); msgBox->closeWindow(); } ); msgBox->addEventListener( Event::OnClose, [&]( const Event* ) { @@ -1115,9 +1128,8 @@ bool App::setAutoComplete( bool enable ) { mConfig.editor.autoComplete = enable; if ( enable && !mAutoCompleteModule ) { mAutoCompleteModule = eeNew( AutoCompleteModule, () ); - mEditorSplitter->forEachEditor( [&]( UICodeEditor* editor ) { - editor->registerModule( mAutoCompleteModule ); - } ); + mEditorSplitter->forEachEditor( + [&]( UICodeEditor* editor ) { editor->registerModule( mAutoCompleteModule ); } ); return true; } if ( !enable && mAutoCompleteModule )