Added Settings -> Window -> UI Theme -> Syntax Color Scheme to use the editor color scheme globally for the UI Theme colors, having a single color palette for the whole UI and making much easier to style the UI, this solves SpartanJ/ecode#661, since now we support one UI theme for each existing syntax color scheme. Still a WIP, I'll continue improving it during the development of 0.7.5, but it's ready to use.

This commit is contained in:
Martín Lucas Golini
2026-01-18 01:38:27 -03:00
parent ddb412f42d
commit f180e58e56
22 changed files with 434 additions and 127 deletions

View File

@@ -1,5 +1,6 @@
[eepp]
background = #282a36
widget_background = #1e202c
text = #e1e1e6
caret = #93DDFA
selection = #394484
@@ -42,6 +43,7 @@ link_hover = transparent,shadow,underline
[spartan]
background = #201f1f
widget_background = #252524
text = #cfcfcf
caret = #93DDFA
selection = #4e4e8f
@@ -84,6 +86,7 @@ link_hover = transparent,shadow,underline
[onedark]
background = #282c34
widget_background = #1e222a
text = #e1e1e6
caret = #93DDFA
selection = #394484
@@ -126,6 +129,7 @@ link_hover = transparent,shadow,underline
[lite]
background = #2e2e32
widget_background = #252529
text = #e1e1e6
caret = #93DDFA
selection = #48484f
@@ -157,6 +161,7 @@ link_hover = transparent,underline
[fall]
background = #343233
widget_background = #2a2829
text = #c4b398
caret = #61efce
accent = #ffd152
@@ -179,6 +184,7 @@ function = #61efce
[summer]
background = #fbfbfb
widget_background = #f6f6f5
text = #404040
caret = #fc1785
accent = #fc1785
@@ -210,6 +216,7 @@ notice = #8abdff
[dracula]
background = #282a36
widget_background = #1e202c
text = #7b81a6
caret = #f8f8f0
accent = #8be9fd
@@ -232,6 +239,7 @@ function = #50fa7b
[gruvbox dark]
background = #282828
widget_background = #1e1e1e
text = #928374
caret = #fbf1c7
accent = #ebdbb2
@@ -254,6 +262,7 @@ function = #8ec07c
[gruvbox material dark]
background = #1d2021
widget_background = #181b1c
text = #d4be98
caret = #fbf1c7
accent = #ebdbb2
@@ -277,6 +286,7 @@ minimap_background = #1d2021AA
[liqube]
background = #13171e
widget_background = #181c23
text = #abb2bf
caret = #abb2bf
accent = #ffffff
@@ -301,6 +311,7 @@ preprocessor = #98c875
[monodark]
background = #080808
widget_background = #0d0d0d
text = #707070
caret = #ffffff
accent = #d0d0d0
@@ -323,6 +334,7 @@ function = #a0a0a0
[monokai]
background = #272822
widget_background = #22231d
text = #9ea191
caret = #F8F8F0
accent = #F8F8F2
@@ -345,6 +357,7 @@ function = #A6E22E
[winter]
background = #282a36
widget_background = #1e202c
text = #aab3e6
caret = #f5faff
accent = #ffb86c
@@ -367,6 +380,7 @@ function = #8be9fd
[github]
background = #fbfbfb
widget_background = #f6f6f6
text = #404040
caret = #181818
accent = #0366d6
@@ -399,6 +413,7 @@ suggestion_scrollbar = #3daee9
[solarized light]
background = #fdf6e3
widget_background = #f3ecd9
text = #657b83
caret = #657b83
accent = #002b36
@@ -431,6 +446,7 @@ notice = #8abdff
[cold lime]
background = #073642
widget_background = #11404c
text = #00d1d1
caret = #f053f3
accent = #f053f3
@@ -475,6 +491,7 @@ function = #01A870
[vscode dark]
background = #1F1F1F
widget_background = #2f343e
text = #cccccc
caret = #FFFFFF
accent = #76BCFF
@@ -497,6 +514,7 @@ function = #D1D1A2
[zenburn]
background = #404040
widget_background = #363636
text = #dcdccc
caret = #f8f8f0
accent = #dcdccc
@@ -519,6 +537,7 @@ function = #efef8f
[nord]
background = #2E3440
widget_background = #242a36
text = #D8DEE9
caret = #D8DEE9
accent = #88C0D0
@@ -541,6 +560,7 @@ function = #88C0D0
[only dark]
background = #242424
widget_background = #292929
text = #fffff0
caret = #69FF94
accent = #ff0fff
@@ -565,6 +585,7 @@ function = #bf9eee
[moe]
background = #f7f9f9
widget_background = #f2f4f4
text = #404040
caret = #ff5971
accent = #ff5971
@@ -597,6 +618,7 @@ suggestion_scrollbar = #ff5971
[solarobj]
background = #fdf6e3
widget_background = #f8f1de
text = #b2ada1
caret = #b2ada1
accent = #6c71c4
@@ -630,6 +652,7 @@ suggestion_scrollbar = #6c71c4
[catppuccin macchiato]
background = #24273a
widget_background = #292d40
text = #cad3f5
caret = #f4dbd6
selection = #394484
@@ -672,6 +695,7 @@ link_hover = #91d7e3,transparent,shadow,underline
[geany]
background = #ffffff
widget_background = #fafafa
text = #000000
caret = #000000
selection = #c0c0c0
@@ -714,6 +738,7 @@ link_hover = #007f00,transparent,underline
[jEdit]
background = #ffffff
widget_background = #fafafa
text = #000000
caret = #000000
selection = #ccccff

View File

@@ -12,8 +12,9 @@
--base-vertical-padding: 5dp;
--border-width: 1dp;
--list-back: #232629;
--separator: #383a3d;
--separator: #31363b;
--item-hover: #284150;
--list-row-active: #eff0f1;
--slider-back: #676a6e;
--slider-button: #31363b;
--slider-border: #787b80;
@@ -26,6 +27,7 @@
--tab-hover: #334e5e;
--tab-close: #909396;
--tab-close-hover: #863d47;
--tab-font-active: white;
--tab-font-inactive: #c0c5cc;
--icon: #b6bbc2;
--icon-active: white;
@@ -56,21 +58,13 @@ tableview::cell::icon,
treeview::cell::icon,
treeview::cell::expander,
listview::cell::icon,
Menu::Item:selected,
Menu::CheckBox:selected,
Menu::SubMenu:selected,
Menu::RadioButton:selected,
Menu::Item:hover > Menu::Item::text,
Menu::Item:hover > Menu::Item::shortcut,
Menu::CheckBox:hover > Menu::CheckBox::text,
Menu::CheckBox:hover > Menu::CheckBox::shortcut,
Menu::RadioButton:hover > Menu::RadioButton::text,
Menu::RadioButton:hover > Menu::RadioButton::shortcut,
Menu::SubMenu:hover > Menu::SubMenu::text,
Menu::item:hover > Menu::Item::icon,
Menu::SubMenu:hover > Menu::SubMenu::icon,
Menu::item:hover > Menu::CheckBox::icon,
Menu::item:hover > Menu::RadioButton::icon,
tableview::header::column:hover,
treeview::header::column:hover,
listview::header::column:hover {
color: var(--font);
tint: var(--font);
}
PushButton:pressed > PushButton::icon,
SelectButton:pressed > SelectButton::icon,
SelectButton:selected > SelectButton::icon,
@@ -83,21 +77,9 @@ treeview::row:selected treeview::cell::icon,
listview::row:selected listview::cell::icon,
tableview::row:selected tableview::cell::expander,
treeview::row:selected treeview::cell::expander,
listview::row:selected listview::cell::expander,
tableview::row:hover tableview::cell::text,
treeview::row:hover treeview::cell::text,
listview::row:hover listview::cell::text,
tableview::row:hover tableview::cell::icon,
treeview::row:hover treeview::cell::icon,
listview::row:hover listview::cell::icon,
tableview::row:hover tableview::cell::expander,
treeview::row:hover treeview::cell::expander,
listview::row:hover listview::cell::expander,
tableview::header::column:hover,
treeview::header::column:hover,
listview::header::column:hover {
color: var(--font);
tint: var(--font);
listview::row:selected listview::cell::expander {
color: var(--list-row-active);
tint: var(--list-row-active);
}
CheckBox,
@@ -136,6 +118,7 @@ TextInput,
TextInputPassword,
ComboBox::DropDownList,
SpinBox::input, {
selection-color: var(--list-row-active);
selection-back-color: var(--primary);
}
@@ -684,16 +667,16 @@ Window {
}
Window::decoration {
background-color: var(--back);
background-color: var(--separator);
}
Window::border::left,
Window::border::right {
background-color: var(--back);
background-color: var(--separator);
}
Window::border::bottom {
background-color: var(--back);
background-color: var(--separator);
}
DropDownList,
@@ -758,6 +741,7 @@ PopUpMenu {
}
MenuBar::Button {
background-color: transparent;
padding-left: 6dp;
padding-right: 6dp;
min-height: 18dp;
@@ -766,6 +750,8 @@ MenuBar::Button {
MenuBar::Button:selected,
MenuBar::Button:hover {
background-color: var(--primary);
color: var(--menu-font-active);
tint: var(--menu-font-active);
}
Menu::Item,
@@ -818,12 +804,21 @@ Menu::SubMenu:disabled > Menu::SubMenu::icon {
tint: var(--menu-font-disabled);
}
Menu::Item:hover > Menu::Item::text,
Menu::CheckBox:hover > Menu::Item::text,
Menu::RadioButton:hover > Menu::Item::text,
Menu::SubMenu:hover > Menu::Item::text,
Menu::Item:selected > Menu::Item::text,
Menu::CheckBox:selected > Menu::CheckBox::text,
Menu::RadioButton:selected > Menu::RadioButton::text,
Menu::SubMenu:selected > Menu::SubMenu::text,
Menu::Item:selected > Menu::Item::icon,
Menu::CheckBox:selected > Menu::CheckBox::icon,
Menu::RadioButton:selected > Menu::RadioButton::icon,
Menu::SubMenu:selected > Menu::SubMenu::icon,
Menu::Item:selected > Menu::Item::shortcut,
Menu::CheckBox:selected > Menu::CheckBox::shortcut,
Menu::RadioButton:selected > Menu::RadioButton::shortcut,
Menu::SubMenu:selected > Menu::SubMenu::shortcut,
ListBox::item:hover {
color: var(--menu-font-active);
tint: var(--menu-font-active);
}
Menu::Separator {
@@ -841,6 +836,10 @@ Menu::SubMenu::Arrow {
foreground-image: poly(line, var(--icon), "5dp 3dp, 10dp 8dp", 1dp), poly(line, var(--icon), "5dp 13dp, 10dp 8dp", 1dp);
}
Menu::SubMenu:hover > Menu::SubMenu::arrow {
foreground-image: poly(line, var(--menu-font-active), "5dp 3dp, 10dp 8dp", 1dp), poly(line, var(--menu-font-active), "5dp 13dp, 10dp 8dp", 1dp);
}
Menu::Item::icon,
Menu::SubMenu::icon,
Menu::CheckBox::icon,
@@ -890,7 +889,7 @@ Table > ScrollBar {
}
Splitter::separator {
background-color: var(--back);
background-color: var(--separator);
}
Splitter::separator:selected,
@@ -938,7 +937,7 @@ listview::header::column:hover,
tableview::rowheader::row:hover,
treeview::rowheader::row:hover,
listview::rowheader::row:hover {
background-color: var(--tab-hover);
background-color: var(--item-hover);
}
tableview::row,
@@ -948,7 +947,7 @@ treeview::row {
tableview::row:hover,
treeview::row:hover {
background-color: var(--tab-hover);
background-color: var(--item-hover);
}
tableview::row:selected,
@@ -1069,7 +1068,7 @@ tab::icon {
tab:selected > tab::icon,
tab:not(:selected):hover > tab::icon {
tint: var(--menu-font-active);
tint: var(--tab-font-active);
}
console {
@@ -1081,6 +1080,11 @@ console {
border-bottom-width: var(--border-width);
}
ImageViewer > TextView {
text-stroke-width: 1dp;
text-stroke-color: var(--back);
}
/* Reserved classes used by themes */
.appbackground {
background-color: var(--back);
@@ -1091,11 +1095,6 @@ TextInput.table_cell_edit {
padding-bottom: 0!important;
}
ImageViewer > TextView {
text-stroke-width: 1dp;
text-stroke-color: var(--back);
}
@media (prefers-color-scheme: light) {
:root {
@@ -1113,6 +1112,7 @@ ImageViewer > TextView {
--list-back: #ffffff;
--separator: #cbcdcd;
--item-hover: #93cee9;
--list-row-active: #eff0f1;
--slider-back: #e9e9e9;
--slider-button: #cbcdcd;
--slider-border: #e6e6e6;
@@ -1125,6 +1125,7 @@ ImageViewer > TextView {
--tab-hover: #93cee9;
--tab-close: #e6e6e6;
--tab-close-hover: #e49aa2;
--tab-font-active: white;
--tab-font-inactive: #444;
--icon: #232627;
--icon-active: #3daee9;
@@ -1148,55 +1149,6 @@ ImageViewer > TextView {
droppable-hovering-color: #00000020;
}
Menu::Item:selected,
Menu::CheckBox:selected,
Menu::SubMenu:selected,
Menu::RadioButton:selected,
Menu::Item:hover > Menu::Item::text,
Menu::Item:hover > Menu::Item::shortcut,
Menu::CheckBox:hover > Menu::CheckBox::text,
Menu::CheckBox:hover > Menu::CheckBox::shortcut,
Menu::RadioButton:hover > Menu::RadioButton::text,
Menu::RadioButton:hover > Menu::RadioButton::shortcut,
Menu::SubMenu:hover > Menu::SubMenu::text,
Menu::item:hover > Menu::Item::icon,
Menu::SubMenu:hover > Menu::SubMenu::icon,
Menu::item:hover > Menu::CheckBox::icon,
Menu::item:hover > Menu::RadioButton::icon,
PushButton:pressed > PushButton::icon,
SelectButton:pressed > SelectButton::icon,
SelectButton:selected > SelectButton::icon,
SelectButton:selected:pressed > SelectButton::icon,
tableview::row:selected tableview::cell::text,
treeview::row:selected treeview::cell::text,
listview::row:selected listview::cell::text,
tableview::row:selected tableview::cell::icon,
treeview::row:selected treeview::cell::icon,
listview::row:selected listview::cell::icon,
tableview::row:selected tableview::cell::expander,
treeview::row:selected treeview::cell::expander,
listview::row:selected listview::cell::expander,
tableview::row:selected tableview::cell checkbox,
treeview::row:selected treeview::cell checkbox,
listview::row:selected listview::cell checkbox,
tableview::row:hover tableview::cell::text,
treeview::row:hover treeview::cell::text,
listview::row:hover listview::cell::text,
tableview::row:hover tableview::cell::icon,
treeview::row:hover treeview::cell::icon,
listview::row:hover listview::cell::icon,
tableview::row:hover tableview::cell::expander,
treeview::row:hover treeview::cell::expander,
listview::row:hover listview::cell::expander,
tableview::row:hover tableview::cell checkbox,
treeview::row:hover treeview::cell checkbox,
listview::row:hover listview::cell checkbox,
tableview::header::column:hover,
treeview::header::column:hover,
listview::header::column:hover {
tint: var(--menu-font-active);
}
Tab:selected,
Tab:hover,
Tab:pressed {
@@ -1204,7 +1156,7 @@ Tab:pressed {
}
Tab:not(:selected):hover {
color: var(--menu-font-active);
color: var(--tab-font-active);
}
tab::icon,
@@ -1213,7 +1165,7 @@ tab:selected > tab::icon, {
}
tab:not(:selected):hover > tab::icon {
tint: var(--menu-font-active);
tint: var(--tab-font-active);
}
}

View File

@@ -1,6 +1,10 @@
#ifndef EE_CONTAINERS_HPP
#define EE_CONTAINERS_HPP
#ifdef EE_DEBUG
#define EEPP_NO_THIRDPARTY_CONTAINERS
#endif
#ifdef EEPP_NO_THIRDPARTY_CONTAINERS
#include <unordered_map>
#include <unordered_set>

View File

@@ -62,6 +62,8 @@ class EE_API StyleSheet {
StyleSheet getAllWithMarker( const Uint32& marker ) const;
StyleSheet getAllWithMarkers() const;
std::vector<std::shared_ptr<StyleSheetStyle>>
findStyleFromSelectorName( const std::string& selector ) const;

View File

@@ -39,6 +39,7 @@ class SyntaxStyleTypes {
static constexpr auto Link = "link"_sst;
static constexpr auto LinkHover = "link_hover"_sst;
static constexpr auto Background = "background"_sst;
static constexpr auto WidgetBackground = "widget_background"_sst;
static constexpr auto Text = "text"_sst;
static constexpr auto Caret = "caret"_sst;
static constexpr auto Selection = "selection"_sst;
@@ -84,6 +85,7 @@ class SyntaxStyleTypes {
case SyntaxStyleTypes::Link:
case SyntaxStyleTypes::LinkHover:
case SyntaxStyleTypes::Background:
case SyntaxStyleTypes::WidgetBackground:
case SyntaxStyleTypes::Text:
case SyntaxStyleTypes::Caret:
case SyntaxStyleTypes::Selection:
@@ -150,6 +152,8 @@ class SyntaxStyleTypes {
return "link_hover";
case SyntaxStyleTypes::Background:
return "background";
case SyntaxStyleTypes::WidgetBackground:
return "widget_background";
case SyntaxStyleTypes::Text:
return "text";
case SyntaxStyleTypes::Caret:
@@ -246,7 +250,7 @@ constexpr auto SyntaxStyleEmpty() {
* "link"
*
* Editor colors types accepted/used are:
* "background", "text", "caret"
* "background", "widget_background", "text", "caret"
* "selection", "gutter_background",
* "line_number", "line_number2", "line_highlight",
* "gutter_background", "whitespace", "line_break_column",
@@ -268,7 +272,7 @@ class EE_API SyntaxColorScheme {
static std::vector<SyntaxColorScheme> loadFromPack( Pack* pack, std::string filePackPath );
struct Style {
Style(){};
Style() {};
Style( const Color& color ) : color( color ) {}
Style( const Color& color, const Color& background, const Uint32& style ) :
color( color ), background( background ), style( style ) {}

View File

@@ -34,6 +34,11 @@ class EE_API UITheme : protected ResourceManagerMulti<UISkin> {
const std::string& textureAtlasPath, Graphics::Font* defaultFont,
const std::string& styleSheetPath );
static UITheme* loadFromString( const std::string& name, const std::string& abbr,
const std::string& textureAtlasPath,
Graphics::Font* defaultFont,
const std::string& styleSheetString );
static UITheme* loadFromTextureAtlas( UITheme* tTheme,
Graphics::TextureAtlas* getTextureAtlas );

View File

@@ -119,6 +119,16 @@ StyleSheet StyleSheet::getAllWithMarker( const Uint32& marker ) const {
return style;
}
StyleSheet StyleSheet::getAllWithMarkers() const {
StyleSheet style;
std::vector<std::shared_ptr<StyleSheetStyle>> hits;
for ( auto node : mNodes ) {
if ( node->getMarker() != 0 )
style.addStyle( node );
}
return style;
}
bool StyleSheet::markerExists( const Uint32& marker ) const {
for ( auto node : mNodes ) {
if ( node->getMarker() == marker )

View File

@@ -56,6 +56,7 @@ SyntaxColorScheme SyntaxColorScheme::getDefault() {
{ "link_hover"_sst, { Color::Transparent, Color::Transparent, Text::Underlined } },
},
{ { "background"_sst, Color( "#282a36" ) },
{ "widget_background"_sst, Color( "#1e202c" ) },
{ "text"_sst, Color( "#e1e1e6" ) },
{ "caret"_sst, Color( "#93DDFA" ) },
{ "selection"_sst, Color( "#394484" ) },
@@ -259,7 +260,9 @@ SyntaxColorScheme::getEditorSyntaxStyle( const SyntaxStyleType& type ) const {
auto it = mEditorColors.find( type );
if ( it != mEditorColors.end() )
return it->second;
if ( type == "gutter_background"_sst || type == "minimap_background"_sst )
if ( type == "widget_background"_sst )
return getEditorSyntaxStyle( "gutter_background"_sst );
else if ( type == "gutter_background"_sst || type == "minimap_background"_sst )
return getEditorSyntaxStyle( "background"_sst );
else if ( type == "whitespace"_sst || type == "line_break_column"_sst ||
type == "matching_bracket"_sst || type == "matching_selection"_sst ||

View File

@@ -88,7 +88,8 @@ UIAudioPlayer* UIAudioPlayer::New() {
}
UIAudioPlayer::UIAudioPlayer() : UIRelativeLayout( "audioplayer" ) {
getUISceneNode()->loadLayoutFromString( AUDIO_PLAYER_LAYOUT, this );
getUISceneNode()->loadLayoutFromString( AUDIO_PLAYER_LAYOUT, this,
String::hash( "audioplayer" ) );
mProgressBar = findByClass<UIProgressBar>( "progressbar" );
mStatusBtn = findByClass( "status_btn" );
mVolumeBtn = findByClass( "volume_btn" );

View File

@@ -214,7 +214,6 @@ void UIStyle::applyLightDarkValue( std::string& value ) {
std::string::size_type tokenEnd = 0;
while ( true ) {
// TODO: add support to inner-function calls like: light-dark(rgba(0,0,0,1), rgba(1,1,1,1))
tokenStart = value.find( "light-dark(", tokenStart );
if ( tokenStart != std::string::npos ) {
tokenEnd = String::findCloseBracket( value, tokenStart, '(', ')' );

View File

@@ -57,6 +57,25 @@ UITheme* UITheme::load( const std::string& name, const std::string& abbr,
return loadFromTextureAtlas( theme, tgl.getTextureAtlas() );
}
UITheme* UITheme::loadFromString( const std::string& name, const std::string& abbr,
const std::string& textureAtlasPath, Font* defaultFont,
const std::string& styleSheetString ) {
UITheme* theme = UITheme::New( name, abbr, defaultFont );
CSS::StyleSheetParser styleSheetParser;
if ( styleSheetParser.loadFromString( styleSheetString ) ) {
theme->setStyleSheet( styleSheetParser.getStyleSheet() );
}
if ( textureAtlasPath.empty() )
return theme;
TextureAtlasLoader tgl( textureAtlasPath );
return loadFromTextureAtlas( theme, tgl.getTextureAtlas() );
}
UITheme* UITheme::loadFromTextureAtlas( UITheme* tTheme, Graphics::TextureAtlas* textureAtlas ) {
eeASSERT( NULL != tTheme && NULL != textureAtlas );

View File

@@ -84,17 +84,26 @@ StatusBar > #doc_info {
#search_replace.error {
border-color: #ff4040;
}
TableView#locate_bar_table > tableview::row > tableview::cell:nth-child(2),
TableView#locate_bar_table > tableview::row > tableview::cell:nth-child(3) {
TableView#locate_bar_table > tableview::row > tableview::cell:nth-child(2) > tableview::cell::text,
TableView#locate_bar_table > tableview::row > tableview::cell:nth-child(3) > tableview::cell::text {
color: var(--font-hint);
}
TableView#locate_bar_table > tableview::row:selected > tableview::cell:nth-child(2),
TableView#locate_bar_table > tableview::row:selected > tableview::cell:nth-child(3) {
color: var(--font);
TableView#locate_bar_table > tableview::row:selected > tableview::cell:nth-child(2) > tableview::cell::text,
TableView#locate_bar_table > tableview::row:selected > tableview::cell:nth-child(3) > tableview::cell::text {
color: var(--list-row-active)
}
.search_tree treeview::cell {
font-family: monospace;
}
.search_tree treeview::row:selected treeview::cell::text {
color: var(--font);
}
.search_tree treeview::row:selected treeview::cell::expander {
tint: var(--font);
}
.search_tree treeview::row:selected {
background-color: var(--tab-hover);
}
#global_search_history {
padding-top: 0dp;
padding-bottom: 0dp;
@@ -171,6 +180,8 @@ TableView#locate_bar_table > tableview::row:selected > tableview::cell:nth-child
#status_bar > .status_but {
padding: 0dp 5dp 0dp 4dp;
background-color: var(--list-back);
color: var(--font);
tint: var(--font);
border-radius: 0dp;
border-left-color: transparent;
border-top-color: transparent;
@@ -185,6 +196,8 @@ TableView#locate_bar_table > tableview::row:selected > tableview::cell:nth-child
}
#status_bar > .status_but.selected {
background-color: var(--primary);
color: var(--list-row-active);
tint: var(--list-row-active);
}
#status_bar > .status_but:last-child {
border-right-color: transparent;
@@ -427,10 +440,10 @@ Anchor.error:hover {
tint: var(--theme-error);
}
#build_output_issues TableView::row:selected TableView::cell.theme-error > TableView::cell::text {
color: var(--font);
color: var(--list-row-active);
}
#build_output_issues TableView::row:selected TableView::cell.theme-error > TableView::cell::icon {
tint: var(--font);
tint: var(--list-row-active);
}
.texture-preview {
border: 1dp solid var(--list-back);
@@ -564,7 +577,7 @@ TabWidget::container > ImageViewer > TextView {
</style>
)html"
R"html(
R"html(
<vbox id="" lw="mp" lh="mp">
<MenuBar id="main_menubar" visible="false">
<Menu id="menubar_file" text="@string(file, File)" nomenu="true" />

View File

@@ -0,0 +1,181 @@
#include "colorschemetranslator.hpp"
using namespace EE;
namespace ecode {
static const auto BASE_UI_THEME = R"css(
:root {
--inherit-base-theme: true;
/* Main Colors */
--primary: type;
--back: background;
--font: text;
--font-highlight: type;
--font-hint: line_number2;
/* Button styling */
--button-back: line_highlight;
--button-border: line_number;
/* List & Separators */
--list-back: widget_background;
--separator: line_highlight;
--item-hover: selection;
--list-row-active: widget_background;
/* Sliders */
--slider-back: line_number;
--slider-button: line_highlight;
--slider-border: line_number2;
/* Scrollbars */
--scrollbar-border: line_highlight;
--scrollbar-button: suggestion_scrollbar;
--scrollbar-hback-hover: selection_region;
/* Tabs */
--tab-back: line_highlight;
--tab-line: line_number;
--tab-active: background;
--tab-hover: selection;
--tab-close: line_number2;
--tab-close-hover: error;
--tab-font-active: type;
--tab-font-inactive: line_number2;
/* Icons */
--icon: symbol;
--icon-active: type;
--icon-back-hover: selection;
--icon-line: line_number2;
--icon-line-hover: text;
--icon-back-alert: error;
/* Menus */
--menu-back: widget_background;
--menu-font: text;
--menu-border: line_number;
--menu-font-active: widget_background;
--menu-font-disabled: line_number2;
/* Floating & Terminal */
--floating-icon: line_number2;
--term-back-color: background;
--term-font-color: text;
/* Highlights & Status */
--highlight-primary: minimap_selection;
--disabled-color: line_number2;
--disabled-border: line_break_column;
--theme-error: error;
--theme-warning: warning;
--theme-success: function;
droppable-hovering-color: minimap_visible_area;
}
)css";
std::string ColorSchemeTranslator::fromSyntaxColorScheme( const SyntaxColorScheme& colorScheme ) {
std::string output( BASE_UI_THEME );
String::replaceAll( output, "widget_background",
colorScheme.getEditorSyntaxStyle( SyntaxStyleTypes::WidgetBackground )
.color.toHexString( true ) );
String::replaceAll( output, "gutter_background",
colorScheme.getEditorSyntaxStyle( SyntaxStyleTypes::GutterBackground )
.color.toHexString( true ) );
String::replaceAll( output, "background",
colorScheme.getEditorSyntaxStyle( SyntaxStyleTypes::Background )
.color.toHexString( true ) );
String::replaceAll(
output, "text",
colorScheme.getEditorSyntaxStyle( SyntaxStyleTypes::Text ).color.toHexString( true ) );
String::replaceAll(
output, "caret",
colorScheme.getEditorSyntaxStyle( SyntaxStyleTypes::Caret ).color.toHexString( true ) );
String::replaceAll( output, "line_highlight",
colorScheme.getEditorSyntaxStyle( SyntaxStyleTypes::LineHighlight )
.color.toHexString( true ) );
String::replaceAll(
output, "selection_region",
colorScheme.getEditorColor( SyntaxStyleTypes::SelectionRegion ).toHexString( true ) );
String::replaceAll(
output, "minimap_selection",
colorScheme.getEditorColor( SyntaxStyleTypes::MinimapSelection ).toHexString( true ) );
String::replaceAll(
output, "selection",
colorScheme.getEditorColor( SyntaxStyleTypes::Selection ).toHexString( true ) );
String::replaceAll(
output, "line_number2",
colorScheme.getEditorColor( SyntaxStyleTypes::LineNumber2 ).toHexString( true ) );
String::replaceAll(
output, "line_number",
colorScheme.getEditorColor( SyntaxStyleTypes::LineNumber ).toHexString( true ) );
String::replaceAll(
output, "suggestion_scrollbar",
colorScheme.getEditorColor( SyntaxStyleTypes::SuggestionScrollbar ).toHexString( true ) );
String::replaceAll(
output, "line_break_column",
colorScheme.getEditorColor( SyntaxStyleTypes::LineBreakColumn ).toHexString( true ) );
String::replaceAll(
output, "minimap_visible_area",
colorScheme.getEditorColor( SyntaxStyleTypes::MinimapVisibleArea ).toHexString( true ) );
String::replaceAll( output, "error",
colorScheme.getEditorColor( SyntaxStyleTypes::Error ).toHexString( true ) );
String::replaceAll(
output, "warning",
colorScheme.getEditorColor( SyntaxStyleTypes::Warning ).toHexString( true ) );
String::replaceAll(
output, "notice",
colorScheme.getEditorColor( SyntaxStyleTypes::Notice ).toHexString( true ) );
String::replaceAll(
output, "whitespace",
colorScheme.getEditorColor( SyntaxStyleTypes::Whitespace ).toHexString( true ) );
// Syntax Styles (Using getSyntaxStyle)
String::replaceAll(
output, "parameter",
colorScheme.getSyntaxStyle( SyntaxStyleTypes::Parameter ).color.toHexString( true ) );
String::replaceAll(
output, "keyword",
colorScheme.getSyntaxStyle( SyntaxStyleTypes::Keyword ).color.toHexString( true ) );
String::replaceAll(
output, "type",
colorScheme.getSyntaxStyle( SyntaxStyleTypes::Type ).color.toHexString( true ) );
String::replaceAll(
output, "symbol",
colorScheme.getSyntaxStyle( SyntaxStyleTypes::Symbol ).color.toHexString( true ) );
String::replaceAll(
output, "function",
colorScheme.getSyntaxStyle( SyntaxStyleTypes::Function ).color.toHexString( true ) );
return output;
}
} // namespace ecode

View File

@@ -0,0 +1,14 @@
#pragma once
#include <eepp/ui/doc/syntaxcolorscheme.hpp>
using namespace EE::UI::Doc;
namespace ecode {
class ColorSchemeTranslator {
public:
static std::string fromSyntaxColorScheme( const SyntaxColorScheme& colorScheme );
};
} // namespace ecode

View File

@@ -1,4 +1,5 @@
#include "ecode.hpp"
#include "colorschemetranslator.hpp"
#include "customwidgets.hpp"
#include "featureshealth.hpp"
#include "keybindingshelper.hpp"
@@ -1801,6 +1802,9 @@ void App::onColorSchemeChanged( const std::string& ) {
mSplitter->getCurrentColorScheme() );
}
if ( "syntax_color_scheme" == mConfig.ui.theme )
setTheme( "syntax_color_scheme" );
mNotificationCenter->addNotification(
String::format( i18n( "color_scheme_set", "Color scheme: %s" ).toUtf8(),
mSplitter->getCurrentColorScheme().getName() ) );
@@ -1888,6 +1892,9 @@ std::string App::getThemePath() const {
if ( mConfig.ui.theme.empty() || "default_theme" == mConfig.ui.theme )
return getDefaultThemePath();
if ( "syntax_color_scheme" == mConfig.ui.theme )
return mConfig.ui.theme;
auto themePath( mThemesPath + mConfig.ui.theme + ".css" );
if ( !FileSystem::fileExists( themePath ) )
return getDefaultThemePath();
@@ -1899,8 +1906,36 @@ std::string App::getDefaultThemePath() const {
return mResPath + "ui/breeze.css";
}
const SyntaxColorScheme* App::getCurrentColorScheme() const {
const SyntaxColorScheme* colorScheme = nullptr;
if ( mSplitter ) {
colorScheme = &mSplitter->getCurrentColorScheme();
} else {
auto found = std::find_if( mColorSchemes.begin(), mColorSchemes.end(),
[this]( const SyntaxColorScheme& colorScheme ) {
return colorScheme.getName() == mInitColorScheme;
} );
if ( found != mColorSchemes.end() ) {
colorScheme = &*found;
}
}
return colorScheme;
}
void App::setTheme( const std::string& path ) {
UITheme* theme = UITheme::load( "uitheme", "uitheme", "", mFont, path );
UITheme* theme = nullptr;
if ( path == "syntax_color_scheme" ) {
const SyntaxColorScheme* colorScheme = getCurrentColorScheme();
if ( colorScheme ) {
std::string themeString( ColorSchemeTranslator::fromSyntaxColorScheme( *colorScheme ) );
theme = UITheme::loadFromString( "uitheme", "uitheme", "", mFont, themeString );
} else {
theme = UITheme::load( "uitheme", "uitheme", "", mFont, getDefaultThemePath() );
}
} else {
theme = UITheme::load( "uitheme", "uitheme", "", mFont, path );
}
theme->setDefaultFontSize( mConfig.ui.fontSize.asPixels( 0, Sizef(), mDisplayDPI ) );
if ( path != getDefaultThemePath() ) {
@@ -1926,16 +1961,27 @@ void App::setTheme( const std::string& path ) {
}
theme->getStyleSheet().addKeyframes( parser.getStyleSheet().getKeyframes() );
}
/* auto inheritsEditorColors = style->getVariableByName( "--inherit-editor-colors" );
if ( !inheritsEditorColors.isEmpty() ) {
const SyntaxColorScheme* colorScheme = getCurrentColorScheme();
std::string themeString(
ColorSchemeTranslator::fromSyntaxColorScheme( *colorScheme ) );
StyleSheetParser parser;
if ( parser.loadFromString( themeString ) )
theme->getStyleSheet().combineStyleSheet( parser.getStyleSheet() );
} */
}
}
theme->getStyleSheet().invalidateCache();
mAppStyleSheet.invalidateCache();
auto oldMarkers = mUISceneNode->getStyleSheet().getAllWithMarkers();
oldMarkers.invalidateCache();
mUISceneNode->setStyleSheet( theme->getStyleSheet(), false );
if ( !mAppStyleSheet.isEmpty() )
mUISceneNode->getStyleSheet().combineStyleSheet( mAppStyleSheet );
mUISceneNode->getStyleSheet().combineStyleSheet( oldMarkers );
mUISceneNode->getStyleSheet().updateMediaLists( mUISceneNode->getMediaFeatures() );
@@ -4469,7 +4515,6 @@ void App::init( InitParameters& params ) {
UIWidgetCreator::registerWidget( "treeviewfs", UITreeViewFS::New );
mUISceneNode->loadLayoutFromString( baseUI, nullptr, APP_LAYOUT_STYLE_MARKER );
mAppStyleSheet = mUISceneNode->getStyleSheet().getAllWithMarker( APP_LAYOUT_STYLE_MARKER );
mUISceneNode->bind( "main_layout", mMainLayout );
mUISceneNode->bind( "code_container", mBaseLayout );
mUISceneNode->bind( "image_container", mImageLayout );

View File

@@ -628,6 +628,8 @@ class App : public UICodeEditorSplitter::Client, public PluginContextProvider {
return !mCurrentProject.empty() && mCurrentProject != getPlaygroundPath();
}
const SyntaxColorScheme* getCurrentColorScheme() const;
protected:
std::vector<std::string> mArgs;
EE::Window::Window* mWindow{ nullptr };
@@ -726,7 +728,6 @@ class App : public UICodeEditorSplitter::Client, public PluginContextProvider {
UITheme* mTheme{ nullptr };
UIStatusBar* mStatusBar{ nullptr };
UISplitter* mMainSplitter{ nullptr };
StyleSheet mAppStyleSheet;
UIMessageBox* mCloseMsgBox{ nullptr };
UIMenuBar* mMenuBar{ nullptr };
std::unique_ptr<SettingsActions> mSettingsActions;

View File

@@ -212,8 +212,10 @@ LLMChatUI::LLMChatUI( PluginManager* manager ) :
setClass( "llm_chatui" );
setLayoutSizePolicy( SizePolicy::MatchParent, SizePolicy::MatchParent );
mChatSplitter =
getUISceneNode()->loadLayoutFromString( DEFAULT_LAYOUT, this )->asType<UISplitter>();
mChatSplitter = getUISceneNode()
->loadLayoutFromString( DEFAULT_LAYOUT, this,
String::hash( "ai_assistant_plugin_chat_ui" ) )
->asType<UISplitter>();
mChatsList = findByClass( "llm_chats" );
mModelDDL = findByClass<UIDropDownList>( "model_ui" );

View File

@@ -787,7 +787,8 @@ void DebuggerPlugin::buildSidePanelTab() {
</vbox>
)html";
UIIcon* icon = findIcon( "debug" );
mTabContents = getUISceneNode()->loadLayoutFromString( STYLE );
mTabContents =
getUISceneNode()->loadLayoutFromString( STYLE, nullptr, String::hash( "debugger_plugin" ) );
mTab = mSidePanel->add( i18n( "debugger", "Debugger" ), mTabContents,
icon ? icon->getSize( PixelDensity::dpToPx( 12 ) ) : nullptr );
mTab->setId( "debugger_tab" );
@@ -1706,7 +1707,14 @@ bool DebuggerPlugin::breakpointSetEnabled( const std::string& doc, Uint32 lineNu
auto breakpointIt = breakpoints.find( sb );
if ( breakpointIt != breakpoints.end() ) {
if ( enabled != breakpointIt->enabled ) {
#ifdef EEPP_NO_THIRDPARTY_CONTAINERS
SourceBreakpointStateful existingBreakpoint = *breakpointIt;
breakpoints.erase( breakpointIt );
existingBreakpoint.enabled = enabled;
breakpoints.insert( existingBreakpoint );
#else
breakpointIt->enabled = enabled;
#endif
mBreakpointsModel->enable( doc, lineNumber, enabled );
mThreadPool->run( [this, doc] { sendFileBreakpoints( doc ); } );
getUISceneNode()->getRoot()->invalidateDraw();

View File

@@ -241,8 +241,10 @@ void StatusDebuggerController::createContainer() {
}
mContainer = mContext->getUISceneNode()
->loadLayoutFromString( XML, mMainSplitter )
->loadLayoutFromString( XML, mMainSplitter,
String::hash( "status_debugger_controller" ) )
->asType<UIHLinearLayoutCommandExecuter>();
mContext->getStatusBar()->registerStatusBarPanel( mContainer, mContainer );
mContainer->bind( "app_debugger_tab_widget", mUITabWidget );

View File

@@ -1447,10 +1447,10 @@ void GitPlugin::buildSidePanelTab() {
.git_highlight_style > treeview::cell::text {
color: %s;
}
treeview::row treeview::cell.git_highlight_style_clear,
treeview::row:selected .git_highlight_style > treeview::cell::text,
treeview::row:selected .git_highlight_style > treeview::cell::text {
color: var(--font);
color: var(--list-row-active);
tint: var(--list-row-active);
}
.git_highlight_style > treeview::cell::icon {
foreground-image: icon(circle, 8dpru), icon(circle-filled, 8dpru);
@@ -1488,7 +1488,10 @@ void GitPlugin::buildSidePanelTab() {
!mHighlightStyleColor.empty() && Color::isColorString( mHighlightStyleColor )
? mHighlightStyleColor
: std::string{ DEFAULT_HIGHLIGHT_COLOR };
mTabContents = getUISceneNode()->loadLayoutFromString( String::format( STYLE, color, color ) );
mTabContents = getUISceneNode()->loadLayoutFromString(
String::format( STYLE, color, color ), nullptr, String::hash( "git_plugin_style" ) );
mTab = mSidePanel->add( i18n( "source_control", "Source Control" ), mTabContents,
icon ? icon->getSize( PixelDensity::dpToPx( 12 ) ) : nullptr );
mTab->setId( "source_control_tab" );

View File

@@ -2186,8 +2186,18 @@ UIMenu* SettingsMenu::createThemesMenu() {
->setOnShouldCloseCb( shouldCloseCb )
->setId( "default_theme" );
menu->addRadioButton( i18n( "syntax_color_scheme", "Syntax Color Scheme" ),
"syntax_color_scheme" == curTheme )
->setOnShouldCloseCb( shouldCloseCb )
->setTooltipText( i18n( "syntax_color_scheme_tool",
"Uses the editor color scheme colors to create a UI theme." ) )
->setId( "syntax_color_scheme" );
auto files = FileSystem::filesInfoGetInPath( mApp->getThemesPath(), true, true, true );
if ( !files.empty() )
menu->addSeparator();
for ( const auto& file : files ) {
if ( file.getExtension() != "css" )
continue;
@@ -2198,11 +2208,14 @@ UIMenu* SettingsMenu::createThemesMenu() {
}
menu->on( Event::OnItemClicked, [this]( const Event* event ) {
if ( event->getNode()->isType( UI_TYPE_MENU_SEPARATOR ) )
return;
auto id = event->getNode()->getId();
mApp->getConfig().ui.theme = "default_theme" != id ? id : "";
std::string path( mApp->getConfig().ui.theme.empty()
? mApp->getDefaultThemePath()
: mApp->getThemesPath() + id + ".css" );
std::string path(
mApp->getConfig().ui.theme.empty()
? mApp->getDefaultThemePath()
: ( "syntax_color_scheme" == id ? id : mApp->getThemesPath() + id + ".css" ) );
mApp->setTheme( path );
} );

View File

@@ -180,6 +180,7 @@ UIPushButton* UITreeViewCellGlobalSearch::updateText( const std::string& text )
auto tokens = SyntaxTokenizer::tokenize( styleDef, text, SyntaxState{}, to ).first;
size_t start = to;
mTextBox->setUsingCustomStyling( true );
for ( const auto& token : tokens ) {
mTextBox->setFontFillColor( pp->getColorScheme().getSyntaxStyle( token.type ).color,
start, start + token.len );