diff --git a/addons/godot_xterm/native/src/terminal.cpp b/addons/godot_xterm/native/src/terminal.cpp index a9e9ab6..700ecfc 100644 --- a/addons/godot_xterm/native/src/terminal.cpp +++ b/addons/godot_xterm/native/src/terminal.cpp @@ -398,25 +398,34 @@ void Terminal::_draw() { void Terminal::update_theme() { ResourceLoader *rl = ResourceLoader::get_singleton(); + Ref default_theme; /* Load the default theme if it exists and no theme is set */ - // Having an actual theme resource set allows things like like font resizing. + // Don't actually set the theme to default (to allow inheritence of themes), + // but do load default values from it. const char *default_theme_path = "res://addons/godot_xterm/themes/default.tres"; if (!get_theme().is_valid() && rl->exists(default_theme_path)) { - set_theme(rl->load(default_theme_path)); + default_theme = rl->load(default_theme_path); } /* Generate color palette based on theme */ - auto set_pallete_color = [this](tsm_vte_color color, String theme_color, - Color default_color) -> void { + auto set_pallete_color = [this, default_theme](tsm_vte_color color, + String theme_color, + Color default_color) -> void { Color c; - c = has_color(theme_color, "Terminal") ? get_color(theme_color, "Terminal") - : default_color; + c = has_color(theme_color, "Terminal") + ? get_color(theme_color, "Terminal") + : has_color_override(theme_color) + ? get_color(theme_color, "") + : (default_theme != nullptr && + default_theme->has_color(theme_color, "Terminal")) + ? default_theme->get_color(theme_color, "Terminal") + : default_color; color_palette[color][0] = c.get_r8(); color_palette[color][1] = c.get_g8(); @@ -475,13 +484,18 @@ void Terminal::update_theme() { /* Load fonts into the fontmap from theme */ - auto set_font = [this, rl](String font_style) -> void { + auto load_font = [this, default_theme](String font_style) -> void { Ref fontref; if (has_font(font_style, "Terminal")) { fontref = get_font(font_style, "Terminal"); + } else if (has_font_override(font_style)) { + fontref = get_font(font_style, ""); } else if (has_font("Regular", "Terminal")) { fontref = get_font("Regular", "Terminal"); + } else if (default_theme != nullptr && + default_theme->has_font("Regular", "Terminal")) { + fontref = default_theme->get_font("Regular", "Terminal"); } else { fontref = get_font(""); } @@ -489,12 +503,12 @@ void Terminal::update_theme() { fontmap.insert(std::pair>(font_style, fontref)); }; - set_font("Bold Italic"); - set_font("Bold"); - set_font("Italic"); - set_font("Regular"); + load_font("Bold Italic"); + load_font("Bold"); + load_font("Italic"); + load_font("Regular"); - update_size(); + // update_size(); } void Terminal::draw_background(int row, int col, Color bgcolor, int width = 1) { diff --git a/addons/godot_xterm/nodes/terminal/terminal.gd b/addons/godot_xterm/nodes/terminal/terminal.gd index 48c6d9e..f42d9c1 100644 --- a/addons/godot_xterm/nodes/terminal/terminal.gd +++ b/addons/godot_xterm/nodes/terminal/terminal.gd @@ -7,8 +7,6 @@ tool extends Control -const DefaultTheme = preload("../../themes/default.tres") - signal data_sent(data) signal key_pressed(data, event) signal size_changed(new_size) @@ -46,6 +44,7 @@ export var bell_cooldown: float = 0.1 export var blink_on_time: float = 0.6 export var blink_off_time: float = 0.3 +var _default_theme: Theme = preload("../../themes/default.tres") var _viewport: Viewport = preload("./viewport.tscn").instance() var _native_terminal: Control = _viewport.get_node("Terminal") var _screen := TextureRect.new() @@ -103,8 +102,7 @@ func copy_all() -> String: func _ready(): - if theme: - _native_terminal.theme = theme + _update_theme() _native_terminal.update_mode = update_mode _native_terminal.connect("data_sent", self, "_on_data_sent") @@ -131,6 +129,30 @@ func _ready(): _refresh() +func _update_theme(): + # Themes are not propagated through the Viewport, so in order for theme + # inheritance to work we can pass through the theme variables manually. + for color in _default_theme.get_color_list("Terminal"): + var c: Color + if has_color(color, "Terminal"): + c = get_color(color, "Terminal") + else: + c = _default_theme.get_color(color, "Terminal") + _native_terminal.add_color_override(color, c) + for font in _default_theme.get_font_list("Terminal"): + var f: Font + if has_font(font, "Terminal"): + f = get_font(font, "Terminal") + else: + if _default_theme.has_font(font, "Terminal"): + f = _default_theme.get_font(font, "Terminal") + else: + f = _default_theme.get_font(font, "Regular") + _native_terminal.add_font_override(font, f) + _native_terminal._update_theme() + _native_terminal._update_size() + + func _refresh(): _screen.update() if update_mode == UpdateMode.AUTO: @@ -212,7 +234,7 @@ func _notification(what: int) -> void: _viewport.size = rect_size _refresh() NOTIFICATION_THEME_CHANGED: - _native_terminal.theme = theme + _update_theme() _refresh() diff --git a/examples/menu/menu.gd b/examples/menu/menu.gd index 61b60e4..ee877ec 100644 --- a/examples/menu/menu.gd +++ b/examples/menu/menu.gd @@ -58,7 +58,7 @@ func draw_all(_size = Vector2.ZERO): func draw_title(): - tput.setaf(Color("#FFECA0")) + tput.setaf(tput.ANSIColor.bright_yellow) tput.cup(row, 0) for line in TITLE.split("\r"): @@ -94,8 +94,8 @@ func draw_menu(): tput.cup(row, offset) if selected_index == i: - tput.setab(Color("#FF786B")) - tput.setaf(Color.black) + tput.setab(tput.ANSIColor.red) + tput.setaf(tput.ANSIColor.black) $Terminal.write("%s. %s" % [i + 1, item.name]) @@ -130,12 +130,10 @@ func _on_Terminal_key_pressed(data: String, event: InputEventKey) -> void: var scene = item.scene.instance() var animation_player: AnimationPlayer = scene.get_node("AnimationPlayer") scene.connect("key_pressed", self, "_on_Asciicast_key_pressed", [animation_player]) - get_tree().get_root().add_child(scene) - visible = false + add_child(scene) scene.grab_focus() yield(animation_player, "animation_finished") - visible = true - get_tree().get_root().remove_child(scene) + remove_child(scene) $Terminal.grab_focus() scene.queue_free() "Terminal": @@ -151,11 +149,9 @@ func _on_Terminal_key_pressed(data: String, event: InputEventKey) -> void: ) var scene = item.scene.instance() var pty = scene if OS.has_feature("JavaScript") else scene.get_node("PTY") - get_tree().get_root().add_child(scene) - visible = false + add_child(scene) scene.grab_focus() yield(pty, "exited") - visible = true $Terminal.grab_focus() scene.queue_free() "Exit": diff --git a/examples/menu/menu.tscn b/examples/menu/menu.tscn index afcad5c..690b5f8 100644 --- a/examples/menu/menu.tscn +++ b/examples/menu/menu.tscn @@ -14,10 +14,10 @@ __meta__ = { [node name="Terminal" type="Control" parent="."] anchor_right = 1.0 anchor_bottom = 1.0 -rect_pivot_offset = Vector2( -731.582, 67.4799 ) focus_mode = 1 script = ExtResource( 1 ) __meta__ = { "_edit_use_anchors_": false } + [connection signal="key_pressed" from="Terminal" to="." method="_on_Terminal_key_pressed"] diff --git a/themes/default.tres b/themes/default.tres index a56e524..0b7d303 100644 --- a/themes/default.tres +++ b/themes/default.tres @@ -1,13 +1,11 @@ [gd_resource type="Theme" load_steps=5 format=2] -[ext_resource path="res://addons/godot_xterm/themes/fonts/regular.tres" type="DynamicFont" id=1] [ext_resource path="res://themes/fonts/bold_italic.tres" type="DynamicFont" id=2] [ext_resource path="res://themes/fonts/italic.tres" type="DynamicFont" id=3] [ext_resource path="res://themes/fonts/bold.tres" type="DynamicFont" id=4] - +[ext_resource path="res://themes/fonts/regular.tres" type="DynamicFont" id=5] [resource] -default_font = ExtResource( 1 ) Terminal/colors/Background = Color( 0.12549, 0.145098, 0.192157, 1 ) Terminal/colors/Black = Color( 0, 0, 0, 1 ) Terminal/colors/Blue = Color( 0.341176, 0.698039, 1, 1 ) @@ -29,4 +27,4 @@ Terminal/colors/Yellow = Color( 1, 0.866667, 0.396078, 1 ) Terminal/fonts/Bold = ExtResource( 4 ) "Terminal/fonts/Bold Italic" = ExtResource( 2 ) Terminal/fonts/Italic = ExtResource( 3 ) -Terminal/fonts/Regular = ExtResource( 1 ) +Terminal/fonts/Regular = ExtResource( 5 ) diff --git a/themes/fonts/regular.tres b/themes/fonts/regular.tres index 59ed3fb..86508d6 100644 --- a/themes/fonts/regular.tres +++ b/themes/fonts/regular.tres @@ -1,15 +1,15 @@ [gd_resource type="DynamicFont" load_steps=6 format=2] -[ext_resource path="res://addons/godot_xterm/themes/fonts/nerd_fonts/symbols_2048_em_nerd_font_complete-2.1.0.ttf" type="DynamicFontData" id=1] -[ext_resource path="res://addons/godot_xterm/themes/fonts/noto_color_emoji/noto_color_emoji-20201206-phase3.ttf" type="DynamicFontData" id=2] -[ext_resource path="res://addons/godot_xterm/themes/fonts/unifont/unifont-13.0.06.ttf" type="DynamicFontData" id=3] +[ext_resource path="res://themes/fonts/unifont/unifont_upper-13.0.06.ttf" type="DynamicFontData" id=1] +[ext_resource path="res://themes/fonts/unifont/unifont-13.0.06.ttf" type="DynamicFontData" id=2] +[ext_resource path="res://themes/fonts/noto_color_emoji/noto_color_emoji-20201206-phase3.ttf" type="DynamicFontData" id=3] [ext_resource path="res://addons/godot_xterm/themes/fonts/hack/hack_regular-3.003.ttf" type="DynamicFontData" id=4] -[ext_resource path="res://addons/godot_xterm/themes/fonts/unifont/unifont_upper-13.0.06.ttf" type="DynamicFontData" id=5] +[ext_resource path="res://themes/fonts/nerd_fonts/symbols_2048_em_nerd_font_complete-2.1.0.ttf" type="DynamicFontData" id=5] [resource] size = 14 font_data = ExtResource( 4 ) -fallback/0 = ExtResource( 1 ) -fallback/1 = ExtResource( 2 ) -fallback/2 = ExtResource( 3 ) -fallback/3 = ExtResource( 5 ) +fallback/0 = ExtResource( 5 ) +fallback/1 = ExtResource( 3 ) +fallback/2 = ExtResource( 2 ) +fallback/3 = ExtResource( 1 )