Terminal panel updates

- Add TerminalSettings resource.
- Init/load terminal settings from terminal panel.
- Add terminal context menu (i.e. right-click PopupMenu).
- Add shortcut to open a new terminal Ctrl+Shift+T and make terminal panel
  visible.
This commit is contained in:
Leroy Hopson 2021-07-12 23:11:28 +07:00
parent 04e077694f
commit ebb527cb8b
No known key found for this signature in database
GPG key ID: D2747312A6DB51AA
9 changed files with 169 additions and 0 deletions

3
.gitignore vendored
View file

@ -24,3 +24,6 @@ mono_crash.*
addons/WAT
test/results.xml
test/test_metadata.json
# GodotXterm-specific ignores
.gdxterm

View file

@ -68,6 +68,10 @@ func _input(event):
if not has_focus():
return
if event is InputEventKey:
if event.shift:
return
# We need to handle many input events otherwise keys such as TAB, ctrl, etc.
# will trigger editor shortcuts when using them in the terminal.
if event is InputEventKey:

View file

@ -0,0 +1,3 @@
[gd_resource type="ShortCut" format=2]
[resource]

View file

@ -0,0 +1,11 @@
[gd_resource type="ShortCut" load_steps=2 format=2]
[sub_resource type="InputEventKey" id=1]
shift = true
control = true
command = true
pressed = true
scancode = 84
[resource]
shortcut = SubResource( 1 )

View file

@ -0,0 +1,3 @@
[gd_resource type="ShortCut" format=2]
[resource]

View file

@ -0,0 +1,59 @@
extends Resource
enum FileType {
USE_SHELL_ENV,
CUSTOM_FILE,
}
enum CWDType {
USE_PROJECT_DIRECTORY,
CUSTOM_CWD,
}
### Shortcuts ###
export (ShortCut) var new_terminal_shortcut = preload("./default_new_terminal_shortcut.tres")
export (ShortCut) var copy_shortcut = preload("./default_copy_shortcut.tres")
export (ShortCut) var paste_shortcut = preload("./default_paste_shortcut.tres")
### Scroll settings ###
# The maximum amount of lines the terminal keeps in its buffer.
export var scrollback_buffer_lines := 1000
# If true, mouse wheel up and down can be used to scroll the terminal.
export var mouse_wheel_scroll := true
# Whether or not to display scroll bar.
export var show_scroll_bar := true
# Copy/paste settings.
export var copy_on_selection := false
# Font settings.
export var font_size: int = 14
export var letter_spacing: int = 0
export var line_height: float = 1.2
export var ctrl_scroll_to_resize_font := true
# Bell settings.
export var visual_bell := true
export var audio_bell := true
export var bell_sound: AudioStream = preload("../../../themes/audio/bell.wav")
# Exec args.
export (FileType) var file_type := FileType.USE_SHELL_ENV
export var custom_file := "/bin/sh"
export (CWDType) var cwd_type := CWDType.USE_PROJECT_DIRECTORY
export var custom_cwd := ""
export var args := PoolStringArray()
export var use_os_env := true
export var extra_env := {
TERM = "xterm-256color",
COLORTERM = "truecolor",
}
func _init(p_copy_on_selection := false):
copy_on_selection = p_copy_on_selection

View file

@ -8,9 +8,22 @@ tool
extends Control
const EditorTerminal := preload("./editor_terminal.tscn")
const TerminalSettings := preload("./settings/terminal_settings.gd")
const SETTINGS_FILE_PATH := "res://.gdxterm/settings.tres"
enum TerminalPopupMenuOptions {
NEW_TERMINAL = 0,
COPY = 2,
PASTE = 3,
SELECT_ALL = 4,
CLEAR = 6,
KILL_TERMINAL = 7,
}
# Has access to the EditorSettings singleton so it can dynamically generate the
# terminal color scheme based on editor theme settings.
var editor_plugin: EditorPlugin
var editor_interface: EditorInterface
onready var editor_settings: EditorSettings = editor_interface.get_editor_settings()
@ -18,9 +31,11 @@ onready var tabs: Tabs = $VBoxContainer/TabbarContainer/Tabs
onready var tabbar_container: HBoxContainer = $VBoxContainer/TabbarContainer
onready var add_button: ToolButton = $VBoxContainer/TabbarContainer/Tabs/AddButton
onready var tab_container: TabContainer = $VBoxContainer/TabContainer
onready var terminal_popup_menu: PopupMenu = $VBoxContainer/TerminalPopupMenu
onready var ready := true
var _theme := Theme.new()
var _settings: TerminalSettings
var _tab_container_min_size
@ -29,7 +44,22 @@ func _ready():
_update_settings()
func _load_or_create_settings() -> void:
var dir := Directory.new()
if not dir.dir_exists(SETTINGS_FILE_PATH.get_base_dir()):
dir.make_dir(SETTINGS_FILE_PATH.get_base_dir())
if not dir.file_exists(SETTINGS_FILE_PATH):
var settings := TerminalSettings.new()
ResourceSaver.save(SETTINGS_FILE_PATH, settings)
_settings = load(SETTINGS_FILE_PATH)
func _update_settings() -> void:
_load_or_create_settings()
var editor_scale: float = editor_interface.get_editor_scale()
rect_min_size = Vector2(0, tabbar_container.rect_size.y + 182) * editor_scale
@ -77,6 +107,7 @@ func _on_AddButton_pressed():
tabs.add_tab(shell.get_file())
terminal.editor_settings = editor_settings
terminal.set_anchors_preset(PRESET_WIDE)
terminal.connect("gui_input", self, "_on_TabContainer_gui_input")
tab_container.add_child(terminal)
terminal.pty.fork(shell)
terminal.grab_focus()
@ -108,3 +139,36 @@ func _notification(what):
_update_terminal_tabs()
NOTIFICATION_WM_FOCUS_IN:
_update_terminal_tabs()
func _input(event: InputEvent) -> void:
if not _settings or not event.is_pressed():
return
if _settings.new_terminal_shortcut and _settings.new_terminal_shortcut.shortcut:
if event.shortcut_match(_settings.new_terminal_shortcut.shortcut):
editor_plugin.make_bottom_panel_item_visible(self)
_on_AddButton_pressed()
func _on_TabContainer_gui_input(event):
if event is InputEventMouseButton and event.button_index == BUTTON_RIGHT:
terminal_popup_menu.rect_position = event.global_position
terminal_popup_menu.popup()
func _on_TerminalPopupMenu_id_pressed(id):
match id:
TerminalPopupMenuOptions.NEW_TERMINAL:
_on_AddButton_pressed()
TerminalPopupMenuOptions.PASTE:
if tabs.get_tab_count() > 0:
var terminal = tab_container.get_child(tab_container.current_tab)
for i in OS.clipboard.length():
var event = InputEventKey.new()
event.unicode = ord(OS.clipboard[i])
event.pressed = true
terminal._gui_input(event)
TerminalPopupMenuOptions.KILL_TERMINAL:
if tabs.get_tab_count() > 0:
_on_Tabs_tab_close(tabs.current_tab)

View file

@ -84,6 +84,12 @@ __meta__ = {
"_edit_use_anchors_": false
}
[node name="PopupMenu" type="PopupMenu" parent="VBoxContainer/TabbarContainer"]
margin_left = 906.0
margin_right = 1024.0
margin_bottom = 88.0
items = [ "Kill", null, 0, false, false, 0, 0, null, "", false, "Kill Others", null, 0, false, false, 1, 0, null, "", false, "Kill to the Right", null, 0, false, false, 2, 0, null, "", false, "Kill All", null, 0, false, false, 3, 0, null, "", false ]
[node name="TabContainer" type="TabContainer" parent="VBoxContainer"]
margin_top = 24.0
margin_right = 1024.0
@ -95,6 +101,18 @@ custom_constants/top_margin = 0
custom_constants/side_margin = 0
tabs_visible = false
[node name="TerminalPopupMenu" type="PopupMenu" parent="VBoxContainer"]
margin_right = 193.0
margin_bottom = 160.0
size_flags_horizontal = 0
size_flags_vertical = 0
items = [ "New Terminal [Ctrl+Shift+T]", null, 0, false, false, 0, 0, null, "", false, "", null, 0, false, true, 1, 0, null, "", true, "Copy [Ctrl+Shift+C]", null, 0, false, false, 2, 0, null, "", false, "Paste [Ctrl+Shift+V]", null, 0, false, false, 3, 0, null, "", false, "Select All", null, 0, false, true, 4, 0, null, "", false, "", null, 0, false, false, 5, 0, null, "", true, "Clear", null, 0, false, true, 6, 0, null, "", false, "Kill Terminal", null, 0, false, false, 7, 0, null, "", false ]
__meta__ = {
"_edit_use_anchors_": false
}
[connection signal="tab_changed" from="VBoxContainer/TabbarContainer/Tabs" to="." method="_on_Tabs_tab_changed"]
[connection signal="tab_close" from="VBoxContainer/TabbarContainer/Tabs" to="." method="_on_Tabs_tab_close"]
[connection signal="pressed" from="VBoxContainer/TabbarContainer/Tabs/AddButton" to="." method="_on_AddButton_pressed"]
[connection signal="gui_input" from="VBoxContainer/TabContainer" to="." method="_on_TabContainer_gui_input"]
[connection signal="id_pressed" from="VBoxContainer/TerminalPopupMenu" to="." method="_on_TerminalPopupMenu_id_pressed"]

View file

@ -24,7 +24,10 @@ func _enter_tree():
"X11", "Server", "OSX":
pty_script = load("res://addons/godot_xterm/nodes/pty/unix/pty_unix.gd")
add_custom_type("PTY", "Node", pty_script, pty_icon)
var terminal_settings_script = preload("./editor_plugins/terminal/settings/terminal_settings.gd")
add_custom_type("TerminalSettings", "Resource", terminal_settings_script, null)
terminal_panel = preload("./editor_plugins/terminal/terminal_panel.tscn").instance()
terminal_panel.editor_plugin = self
terminal_panel.editor_interface = get_editor_interface()
add_control_to_bottom_panel(terminal_panel, "Terminal")
@ -38,5 +41,6 @@ func _exit_tree():
if pty_supported:
remove_custom_type("PTY")
remove_custom_type("TerminalSettings")
remove_control_from_bottom_panel(terminal_panel)
terminal_panel.free()