Added some functions to the StyleSheet to enable updating the cached element definition and finding selectors.
ecode:
Added "UI Panel Font Size" option.
LSP Client minor fixes. Added "--css" command line option.
"Show Line Endings" is now disabled by default.
Fixed "switch-to-previous-colorscheme" when running with emscripten.
This commit is contained in:
Martín Lucas Golini
2023-01-29 14:01:35 -03:00
parent e46fb2922d
commit 3aab736563
18 changed files with 158 additions and 47 deletions

View File

@@ -28,6 +28,8 @@ class EE_API ElementDefinition : NonCopyable {
const StyleSheetStyleVector& getStyles() const;
void refresh();
protected:
StyleSheetStyleVector mStyles;
StyleSheetProperties mProperties;

View File

@@ -55,6 +55,11 @@ class EE_API StyleSheet {
bool markerExists( const Uint32& marker ) const;
std::vector<std::shared_ptr<StyleSheetStyle>>
findStyleFromSelectorName( const std::string& selector );
bool refreshCacheFromStyles( const std::vector<std::shared_ptr<StyleSheetStyle>>& styles );
protected:
Uint32 mMarker{ 0 };
std::vector<std::shared_ptr<StyleSheetStyle>> mNodes;

View File

@@ -64,7 +64,7 @@ class EE_API StyleSheetProperty {
void setName( const std::string& name );
void setValue( const std::string& value );
void setValue( const std::string& value, bool updateHash = false );
const bool& isVolatile() const;

View File

@@ -59,6 +59,8 @@ class EE_API StyleSheetStyle {
void setMarker( const Uint32& marker );
bool updatePropertyValue( const std::string& name, const std::string& value );
protected:
Uint32 mMarker{ 0 };
StyleSheetSelector mSelector;

View File

@@ -142,6 +142,8 @@ class EE_API UITreeView : public UIAbstractTableView {
bool tryOpenModelIndex( const ModelIndex& index, bool forceUpdate = true );
void updateContentSize();
protected:
enum class IterationDecision {
Continue,
@@ -191,8 +193,6 @@ class EE_API UITreeView : public UIAbstractTableView {
virtual void onSortColumn( const size_t& colIndex );
void updateContentSize();
void setAllExpanded( const ModelIndex& index = {}, bool expanded = true );
virtual UIWidget* setupCell( UITableCell* widget, UIWidget* rowWidget,

View File

@@ -4,32 +4,7 @@ namespace EE { namespace UI { namespace CSS {
ElementDefinition::ElementDefinition( const StyleSheetStyleVector& styleSheetStyles ) :
mStyles( styleSheetStyles ), mStructurallyVolatile( false ) {
for ( auto& styleSheetStyle : styleSheetStyles ) {
const StyleSheetProperties& properties = styleSheetStyle->getProperties();
if ( styleSheetStyle->getSelector().isStructurallyVolatile() )
mStructurallyVolatile = true;
for ( auto iterator = properties.begin(); iterator != properties.end(); ++iterator ) {
const StyleSheetProperty& property = iterator->second;
const auto& it = mProperties.find( property.getId() );
if ( it == mProperties.end() ||
property.getSpecificity() >= it->second.getSpecificity() ) {
mProperties[property.getId()] = property;
}
if ( String::startsWith( property.getName(), "transition" ) )
mTransitionProperties.push_back( &property );
else if ( String::startsWith( property.getName(), "animation" ) )
mAnimationProperties.push_back( &property );
}
findVariables( styleSheetStyle );
}
for ( auto& property : mProperties )
mPropertyIds.insert( property.first );
refresh();
}
StyleSheetProperty* ElementDefinition::getProperty( const Uint32& id ) {
@@ -65,6 +40,40 @@ const StyleSheetStyleVector& ElementDefinition::getStyles() const {
return mStyles;
}
void ElementDefinition::refresh() {
mProperties.clear();
mTransitionProperties.clear();
mAnimationProperties.clear();
mPropertyIds.clear();
mStructurallyVolatile = false;
for ( auto& styleSheetStyle : mStyles ) {
const StyleSheetProperties& properties = styleSheetStyle->getProperties();
if ( styleSheetStyle->getSelector().isStructurallyVolatile() )
mStructurallyVolatile = true;
for ( auto iterator = properties.begin(); iterator != properties.end(); ++iterator ) {
const StyleSheetProperty& property = iterator->second;
const auto& it = mProperties.find( property.getId() );
if ( it == mProperties.end() ||
property.getSpecificity() >= it->second.getSpecificity() ) {
mProperties[property.getId()] = property;
}
if ( String::startsWith( property.getName(), "transition" ) )
mTransitionProperties.push_back( &property );
else if ( String::startsWith( property.getName(), "animation" ) )
mAnimationProperties.push_back( &property );
}
findVariables( styleSheetStyle );
}
for ( auto& property : mProperties )
mPropertyIds.insert( property.first );
}
void ElementDefinition::findVariables( const StyleSheetStyle* style ) {
for ( const auto& vars : style->getVariables() ) {
const StyleSheetVariable& variable = vars.second;

View File

@@ -106,6 +106,32 @@ bool StyleSheet::markerExists( const Uint32& marker ) const {
return false;
}
std::vector<std::shared_ptr<StyleSheetStyle>>
StyleSheet::findStyleFromSelectorName( const std::string& selector ) {
std::vector<std::shared_ptr<StyleSheetStyle>> found;
for ( const auto& node : mNodes ) {
if ( selector == node->getSelector().getName() )
found.push_back( node );
}
return found;
}
bool StyleSheet::refreshCacheFromStyles(
const std::vector<std::shared_ptr<StyleSheetStyle>>& styles ) {
bool refreshed = false;
for ( const auto& style : styles ) {
for ( auto& node : mNodeCache ) {
for ( auto& nodeStyle : node.second->getStyles() ) {
if ( nodeStyle == style.get() ) {
node.second->refresh();
refreshed = true;
}
}
}
}
return refreshed;
}
bool StyleSheet::addStyleToNodeIndex( StyleSheetStyle* style ) {
const std::string& id = style->getSelector().getSelectorId();
const std::string& tag = style->getSelector().getSelectorTagName();

View File

@@ -154,9 +154,10 @@ void StyleSheetProperty::setName( const std::string& name ) {
mNameHash = String::hash( mName );
}
void StyleSheetProperty::setValue( const std::string& value ) {
void StyleSheetProperty::setValue( const std::string& value, bool updateHash ) {
mValue = value;
// mValueHash = String::hash( value );
if ( updateHash )
mValueHash = String::hash( value );
mIsVarValue = String::startsWith( mValue, "var(" );
createIndexed();
}

View File

@@ -59,6 +59,17 @@ StyleSheetProperties& StyleSheetStyle::getPropertiesRef() {
return mProperties;
}
bool StyleSheetStyle::updatePropertyValue( const std::string& name, const std::string& value ) {
bool updated = false;
for ( auto& prop : mProperties ) {
if ( prop.second.getName() == name ) {
prop.second.setValue( value, true );
updated = true;
}
}
return updated;
}
const StyleSheetVariables& StyleSheetStyle::getVariables() const {
return mVariables;
}

View File

@@ -203,12 +203,8 @@ UICodeEditor* UICodeEditorSplitter::createCodeEditor() {
/* editor commands */
doc.setCommand( "switch-to-previous-colorscheme", [&] {
auto it = mColorSchemes.find( mCurrentColorScheme );
auto prev = std::prev( it, 1 );
if ( prev != mColorSchemes.end() ) {
setColorScheme( prev->first );
} else {
setColorScheme( mColorSchemes.rbegin()->first );
}
setColorScheme( it == mColorSchemes.begin() ? mColorSchemes.rbegin()->first
: ( --it )->first );
} );
doc.setCommand( "switch-to-next-colorscheme", [&] {

View File

@@ -291,7 +291,6 @@ std::vector<UIWidget*> UISceneNode::loadNode( pugi::xml_node node, Node* parent,
uiwidget->onWidgetCreated();
} else if ( String::toLower( std::string( widget.name() ) ) == "style" ) {
// combineStyleSheet( widget.text().as_string(), false );
CSS::StyleSheetParser parser;
if ( parser.loadFromString( widget.text().as_string() ) ) {

View File

@@ -78,13 +78,14 @@ void AppConfig::load( const std::string& confPath, std::string& keybindingsPath,
windowState.position.y = iniState.getValueI( "window", "y", -1 );
editor.showLineNumbers = ini.getValueB( "editor", "show_line_numbers", true );
editor.showWhiteSpaces = ini.getValueB( "editor", "show_white_spaces", true );
editor.showLineEndings = ini.getValueB( "editor", "show_line_endings", true );
editor.showLineEndings = ini.getValueB( "editor", "show_line_endings", false );
editor.highlightMatchingBracket =
ini.getValueB( "editor", "highlight_matching_brackets", true );
editor.highlightCurrentLine = ini.getValueB( "editor", "highlight_current_line", true );
editor.verticalScrollbar = ini.getValueB( "editor", "vertical_scrollbar", true );
editor.horizontalScrollbar = ini.getValueB( "editor", "horizontal_scrollbar", true );
ui.fontSize = ini.getValue( "ui", "font_size", "11dp" );
ui.panelFontSize = ini.getValue( "ui", "panel_font_size", "11dp" );
ui.showSidePanel = ini.getValueB( "ui", "show_side_panel", true );
ui.panelPosition = panelPositionFromString( ini.getValue( "ui", "panel_position", "left" ) );
ui.serifFont = ini.getValue( "ui", "serif_font", "fonts/NotoSans-Regular.ttf" );
@@ -195,6 +196,7 @@ void AppConfig::save( const std::vector<std::string>& recentFiles,
ini.setValueB( "editor", "horizontal_scrollbar", editor.horizontalScrollbar );
ini.setValue( "editor", "font_size", editor.fontSize.toString() );
ini.setValue( "ui", "font_size", ui.fontSize.toString() );
ini.setValue( "ui", "panel_font_size", ui.panelFontSize.toString() );
ini.setValueB( "ui", "show_side_panel", ui.showSidePanel );
ini.setValue( "ui", "panel_position", panelPositionToString( ui.panelPosition ) );
ini.setValue( "ui", "serif_font", ui.serifFont );

View File

@@ -24,6 +24,7 @@ enum class PanelPosition { Left, Right };
struct UIConfig {
StyleSheetLength fontSize{ 11, StyleSheetLength::Dp };
StyleSheetLength panelFontSize{ 11, StyleSheetLength::Dp };
bool showSidePanel{ true };
PanelPosition panelPosition{ PanelPosition::Left };
std::string serifFont;

View File

@@ -897,6 +897,37 @@ void App::setUIFontSize() {
setFocusEditorOnClose( msgBox );
}
void App::setUIPanelFontSize() {
UIMessageBox* msgBox = UIMessageBox::New(
UIMessageBox::INPUT, i18n( "set_side_panel_font_size", "Set side panel font size:" ) );
msgBox->setTitle( mWindowTitle );
msgBox->getTextInput()->setText( mConfig.ui.panelFontSize.toString() );
msgBox->setCloseShortcut( { KEY_ESCAPE, 0 } );
msgBox->showWhenReady();
msgBox->addEventListener( Event::OnConfirm, [&, msgBox]( const Event* ) {
mConfig.ui.panelFontSize = StyleSheetLength( msgBox->getTextInput()->getText() );
// Update the CSS
auto selsFound = mUISceneNode->getStyleSheet().findStyleFromSelectorName(
"#project_view > treeview::row > treeview::cell > treeview::cell::text" );
if ( !selsFound.empty() ) {
for ( auto sel : selsFound )
sel->updatePropertyValue( "font-size", mConfig.ui.panelFontSize.toString() );
mUISceneNode->getStyleSheet().refreshCacheFromStyles( selsFound );
}
UITreeView* treeView = mUISceneNode->find<UITreeView>( "project_view" );
if ( !treeView ) {
msgBox->closeWindow();
return;
}
treeView->reloadStyle( true, true, true, true );
treeView->updateContentSize();
msgBox->closeWindow();
} );
setFocusEditorOnClose( msgBox );
}
void App::setFocusEditorOnClose( UIMessageBox* msgBox ) {
msgBox->addEventListener( Event::OnClose, [&]( const Event* ) {
if ( mSplitter && mSplitter->getCurWidget() )
@@ -1362,6 +1393,7 @@ std::vector<std::string> App::getUnlockedCommands() {
"editor-font-size",
"terminal-font-size",
"ui-font-size",
"ui-panel-font-size",
"serif-font",
"monospace-font",
"terminal-font",
@@ -2125,8 +2157,8 @@ FontTrueType* App::loadFont( const std::string& name, std::string fontPath,
}
void App::init( const LogLevel& logLevel, std::string file, const Float& pidelDensity,
const std::string& colorScheme, bool terminal, bool frameBuffer,
bool benchmarkMode ) {
const std::string& colorScheme, bool terminal, bool frameBuffer, bool benchmarkMode,
const std::string& css ) {
DisplayManager* displayManager = Engine::instance()->getDisplayManager();
Display* currentDisplay = displayManager->getDisplayIndex( 0 );
mDisplayDPI = currentDisplay->getDPI();
@@ -2280,6 +2312,20 @@ void App::init( const LogLevel& logLevel, std::string file, const Float& pidelDe
mUISceneNode->getRoot()->addClass( "appbackground" );
if ( !css.empty() && FileSystem::fileExists( css ) ) {
CSS::StyleSheetParser parser;
if ( parser.loadFromFile( css ) )
mUISceneNode->combineStyleSheet( parser.getStyleSheet(), false );
}
std::string panelUI( String::format( R"css(
#project_view > treeview::row > treeview::cell > treeview::cell::text {
font-size: %s;
}
)css",
mConfig.ui.panelFontSize.toString().c_str() ) );
mUISceneNode->combineStyleSheet( panelUI, false );
const std::string baseUI = R"html(
<style>
TextInput#search_find,
@@ -2792,6 +2838,10 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) {
args::ValueFlag<std::string> prefersColorScheme(
parser, "prefers-color-scheme", "Set the preferred color scheme (\"light\" or \"dark\")",
{ 'c', "prefers-color-scheme" } );
args::ValueFlag<std::string> css(
parser, "css",
"Sets the path for a custom stylesheet to load at the start of the application",
{ "css" } );
args::Flag terminal( parser, "terminal", "Open a new terminal", { 't', "terminal" } );
args::MapFlag<std::string, LogLevel> logLevel(
parser, "log-level", "The level of details that the application will emmit logs.",
@@ -2831,7 +2881,7 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) {
appInstance->init( logLevel.Get(), filePos ? filePos.Get() : file.Get(),
pixelDenstiyConf ? pixelDenstiyConf.Get() : 0.f,
prefersColorScheme ? prefersColorScheme.Get() : "", terminal.Get(), fb.Get(),
benchmarkMode.Get() );
benchmarkMode.Get(), css.Get() );
eeSAFE_DELETE( appInstance );
Engine::destroySingleton();

View File

@@ -31,8 +31,8 @@ class App : public UICodeEditorSplitter::Client {
~App();
void init( const LogLevel& logLevel, std::string file, const Float& pidelDensity,
const std::string& colorScheme, bool terminal, bool frameBuffer,
bool benchmarkMode );
const std::string& colorScheme, bool terminal, bool frameBuffer, bool benchmarkMode,
const std::string& css );
void createWidgetInspector();
@@ -222,6 +222,7 @@ class App : public UICodeEditorSplitter::Client {
t.setCommand( "editor-font-size", [&] { setEditorFontSize(); } );
t.setCommand( "terminal-font-size", [&] { setTerminalFontSize(); } );
t.setCommand( "ui-font-size", [&] { setUIFontSize(); } );
t.setCommand( "ui-panel-font-size", [&] { setUIPanelFontSize(); } );
t.setCommand( "serif-font", [&] { openFontDialog( mConfig.ui.serifFont, false ); } );
t.setCommand( "monospace-font", [&] { openFontDialog( mConfig.ui.monospaceFont, true ); } );
t.setCommand( "terminal-font", [&] { openFontDialog( mConfig.ui.terminalFont, false ); } );
@@ -292,6 +293,8 @@ class App : public UICodeEditorSplitter::Client {
void ecodeSource();
void setUIPanelFontSize();
protected:
EE::Window::Window* mWindow{ nullptr };
UISceneNode* mUISceneNode{ nullptr };

View File

@@ -120,7 +120,7 @@ class LinterPlugin : public UICodeEditorPlugin {
bool mShuttingDown{ false };
bool mHoveringMatch{ false };
bool mEnableLSPDiagnostics{ true };
bool mErrorLens{ false };
bool mErrorLens{ true };
std::set<std::string> mLanguagesDisabled;
std::set<std::string> mLSPLanguagesDisabled;

View File

@@ -289,8 +289,10 @@ static void fromJson( LSPServerCapabilities& caps, const json& json ) {
}
caps.hoverProvider = toBoolOrObject( json, "hoverProvider" );
fromJson( caps.completionProvider, json["completionProvider"] );
fromJson( caps.signatureHelpProvider, json["signatureHelpProvider"] );
if ( json.contains( "completionProvider" ) )
fromJson( caps.completionProvider, json["completionProvider"] );
if ( json.contains( "signatureHelpProvider" ) )
fromJson( caps.signatureHelpProvider, json["signatureHelpProvider"] );
caps.definitionProvider = toBoolOrObject( json, "definitionProvider" );
caps.declarationProvider = toBoolOrObject( json, "declarationProvider" );
caps.typeDefinitionProvider = toBoolOrObject( json, "typeDefinitionProvider" );

View File

@@ -805,6 +805,8 @@ UIMenu* SettingsMenu::createWindowMenu() {
->setId( "ui-scale-factor" );
mWindowMenu->add( i18n( "ui_font_size", "UI Font Size" ), findIcon( "font-size" ) )
->setId( "ui-font-size" );
mWindowMenu->add( i18n( "ui_panel_font_size", "UI Panel Font Size" ), findIcon( "font-size" ) )
->setId( "ui-panel-font-size" );
mWindowMenu->add( i18n( "editor_font_size", "Editor Font Size" ), findIcon( "font-size" ) )
->setId( "editor-font-size" );
mWindowMenu->add( i18n( "terminal_font_size", "Terminal Font Size" ), findIcon( "font-size" ) )