mirror of
https://github.com/git-learning-game/oh-my-git.git
synced 2024-12-20 20:33:11 +01:00
Quick implementation of the 3-layer files
This commit is contained in:
parent
e6b12b75f7
commit
76c4aab834
5 changed files with 187 additions and 126 deletions
|
@ -39,67 +39,95 @@ func substr2(s):
|
|||
return s.substr(2)
|
||||
|
||||
func update():
|
||||
if grid:
|
||||
if grid and repository:
|
||||
clear()
|
||||
match mode:
|
||||
FileBrowserMode.WORKING_DIRECTORY:
|
||||
if shell:
|
||||
var wd_files = Array(shell.run("find . -type f").split("\n"))
|
||||
# The last entry is an empty string, remove it.
|
||||
wd_files.pop_back()
|
||||
wd_files = helpers.map(wd_files, self, "substr2")
|
||||
|
||||
var deleted_files = []
|
||||
if shell.run("test -d .git && echo yes || echo no") == "yes\n":
|
||||
deleted_files = Array(shell.run("git status -s | grep '^.D' | sed 's/^...//'").split("\n"))
|
||||
deleted_files.pop_back()
|
||||
# Files in the working directory.
|
||||
var wd_files = Array(repository.shell.run("find . -type f -not -path '*/\\.git/*'").split("\n"))
|
||||
# The last entry is an empty string, remove it.
|
||||
wd_files.pop_back()
|
||||
wd_files = helpers.map(wd_files, self, "substr2")
|
||||
|
||||
var files = wd_files + deleted_files
|
||||
var head_files
|
||||
var index_files
|
||||
|
||||
files.sort_custom(self, "very_best_sort")
|
||||
if repository.there_is_a_git():
|
||||
# Files in the HEAD commit.
|
||||
head_files = Array(repository.shell.run("git ls-tree --name-only -r HEAD 2> /dev/null || true").split("\n"))
|
||||
# The last entry is an empty string, remove it.
|
||||
head_files.pop_back()
|
||||
# Files in the index.
|
||||
index_files = Array(repository.shell.run("git ls-files -s | cut -f2 | uniq").split("\n"))
|
||||
# The last entry is an empty string, remove it.
|
||||
index_files.pop_back()
|
||||
|
||||
var files = wd_files
|
||||
for f in head_files:
|
||||
if not f in files:
|
||||
files.push_back(f)
|
||||
for f in index_files:
|
||||
if not f in files:
|
||||
files.push_back(f)
|
||||
|
||||
files.sort_custom(self, "very_best_sort")
|
||||
|
||||
for file_path in files:
|
||||
var item = preload("res://scenes/file_browser_item.tscn").instance()
|
||||
item.label = file_path
|
||||
item.repository = repository
|
||||
item.connect("clicked", self, "item_clicked")
|
||||
grid.add_child(item)
|
||||
|
||||
if false:
|
||||
match mode:
|
||||
FileBrowserMode.WORKING_DIRECTORY:
|
||||
if shell:
|
||||
|
||||
var deleted_files = []
|
||||
if shell.run("test -d .git && echo yes || echo no") == "yes\n":
|
||||
deleted_files = Array(shell.run("git status -s | grep '^.D' | sed 's/^...//'").split("\n"))
|
||||
deleted_files.pop_back()
|
||||
|
||||
#var is_visible = false
|
||||
for file_path in files:
|
||||
if file_path.substr(0, 5) == ".git/":
|
||||
continue
|
||||
#is_visible = true
|
||||
var item = preload("res://scenes/file_browser_item.tscn").instance()
|
||||
item.label = file_path
|
||||
item.connect("clicked", self, "item_clicked")
|
||||
item.connect("deleted", self, "item_deleted")
|
||||
item.status = get_file_status(file_path, shell, 1)
|
||||
|
||||
grid.add_child(item)
|
||||
#visible = is_visible
|
||||
|
||||
FileBrowserMode.COMMIT:
|
||||
if commit:
|
||||
# The last entry is an empty string, remove it.
|
||||
files.pop_back()
|
||||
for file_path in files:
|
||||
var item = preload("res://scenes/file_browser_item.tscn").instance()
|
||||
item.label = file_path
|
||||
item.connect("clicked", self, "item_clicked")
|
||||
grid.add_child(item)
|
||||
FileBrowserMode.INDEX:
|
||||
#var is_visible = false
|
||||
for file_path in files:
|
||||
if file_path.substr(0, 5) == ".git/":
|
||||
continue
|
||||
#is_visible = true
|
||||
var item = preload("res://scenes/file_browser_item.tscn").instance()
|
||||
item.label = file_path
|
||||
item.connect("clicked", self, "item_clicked")
|
||||
item.connect("deleted", self, "item_deleted")
|
||||
item.status = get_file_status(file_path, shell, 1)
|
||||
if repository and repository.there_is_a_git():
|
||||
|
||||
grid.add_child(item)
|
||||
var deleted_files = Array(repository.shell.run("git status -s | grep '^D' | sed 's/^...//'").split("\n"))
|
||||
# The last entries are empty strings, remove them.
|
||||
|
||||
for file_path in files:
|
||||
var item = preload("res://scenes/file_browser_item.tscn").instance()
|
||||
item.label = file_path
|
||||
item.connect("clicked", self, "item_clicked")
|
||||
item.status = get_file_status(file_path, repository.shell, 0)
|
||||
grid.add_child(item)
|
||||
#if item.status != item.IconStatus.NONE:
|
||||
# is_visible = true
|
||||
#visible = is_visible
|
||||
|
||||
FileBrowserMode.COMMIT:
|
||||
if commit:
|
||||
var files = Array(commit.repository.shell.run("git ls-tree --name-only -r %s" % commit.id).split("\n"))
|
||||
# The last entry is an empty string, remove it.
|
||||
files.pop_back()
|
||||
for file_path in files:
|
||||
var item = preload("res://scenes/file_browser_item.tscn").instance()
|
||||
item.label = file_path
|
||||
item.connect("clicked", self, "item_clicked")
|
||||
grid.add_child(item)
|
||||
FileBrowserMode.INDEX:
|
||||
#var is_visible = false
|
||||
if repository and repository.there_is_a_git():
|
||||
var index_files = Array(repository.shell.run("git ls-files -s | cut -f2 | uniq").split("\n"))
|
||||
var deleted_files = Array(repository.shell.run("git status -s | grep '^D' | sed 's/^...//'").split("\n"))
|
||||
# The last entries are empty strings, remove them.
|
||||
index_files.pop_back()
|
||||
deleted_files.pop_back()
|
||||
var files = index_files + deleted_files
|
||||
for file_path in files:
|
||||
var item = preload("res://scenes/file_browser_item.tscn").instance()
|
||||
item.label = file_path
|
||||
item.connect("clicked", self, "item_clicked")
|
||||
item.status = get_file_status(file_path, repository.shell, 0)
|
||||
grid.add_child(item)
|
||||
#if item.status != item.IconStatus.NONE:
|
||||
# is_visible = true
|
||||
#visible = is_visible
|
||||
|
||||
func get_file_status(file_path, the_shell, idx):
|
||||
var file_status = the_shell.run("git status -s '%s'" % file_path)
|
||||
if file_status.length()>0:
|
||||
|
@ -120,12 +148,12 @@ func get_file_status(file_path, the_shell, idx):
|
|||
return FileBrowserItem.IconStatus.NONE
|
||||
|
||||
func item_clicked(item):
|
||||
if item.status == item.IconStatus.REMOVED:
|
||||
if not item.get_node("VBoxContainer/Control/WD").visible:
|
||||
return
|
||||
|
||||
match mode:
|
||||
FileBrowserMode.WORKING_DIRECTORY:
|
||||
text_edit.text = helpers.read_file(shell._cwd + item.label)
|
||||
text_edit.text = helpers.read_file(repository.shell._cwd + item.label)
|
||||
FileBrowserMode.COMMIT:
|
||||
text_edit.text = commit.repository.shell.run("git show %s:\"%s\"" % [commit.id, item.label])
|
||||
FileBrowserMode.INDEX:
|
||||
|
@ -147,7 +175,7 @@ func close():
|
|||
func save():
|
||||
match mode:
|
||||
FileBrowserMode.WORKING_DIRECTORY:
|
||||
var fixme_path = shell._cwd
|
||||
var fixme_path = repository.shell._cwd
|
||||
|
||||
# Add a newline to the end of the file if there is none.
|
||||
if text_edit.text.length() > 0 and text_edit.text.substr(text_edit.text.length()-1, 1) != "\n":
|
||||
|
|
|
@ -4,18 +4,50 @@ extends Control
|
|||
signal clicked(what)
|
||||
signal deleted(what)
|
||||
|
||||
enum IconStatus {NONE, NEW, REMOVED, CONFLICT, EDIT, UNTRACKED}
|
||||
export(IconStatus) var status setget _set_status
|
||||
export var label: String setget _set_label
|
||||
var type = "file"
|
||||
var repository
|
||||
|
||||
onready var label_node = $VBoxContainer/Label
|
||||
onready var status_icon = $VBoxContainer/Control/TextureRect/StatusIcon
|
||||
|
||||
func _ready():
|
||||
_set_label(label)
|
||||
_set_status(status)
|
||||
$PopupMenu.add_item("Delete file", 0)
|
||||
#$PopupMenu.add_item("Delete file", 0)
|
||||
var exists_in_wd = repository.shell.run("test -f '%s' && echo yes || echo no" % label) == "yes\n"
|
||||
var exists_in_index = repository.shell.run("git ls-files --error-unmatch '%s' &>/dev/null && echo yes || echo no" % label) == "yes\n"
|
||||
var exists_in_head = repository.shell.run("git cat-file -e HEAD:'%s' &>/dev/null && echo yes || echo no" % label) == "yes\n"
|
||||
|
||||
var wd_hash = repository.shell.run("git hash-object '%s' 2>/dev/null || true" % label)
|
||||
var index_hash = repository.shell.run("git ls-files -s '%s' | cut -f2 -d' '" % label)
|
||||
var head_hash = repository.shell.run("git ls-tree HEAD '%s' | cut -f1 | cut -f3 -d' '" % label)
|
||||
|
||||
var conflict = Array(index_hash.split("\n")).size() > 2
|
||||
|
||||
var offset_index = 0
|
||||
var offset_wd = 0
|
||||
var offset = 10
|
||||
|
||||
if exists_in_index and exists_in_head and index_hash != head_hash:
|
||||
offset_index += 1
|
||||
|
||||
if exists_in_wd and exists_in_head and wd_hash != head_hash:
|
||||
offset_wd += 1
|
||||
|
||||
if exists_in_wd and exists_in_index and wd_hash != index_hash and offset_index == offset_wd:
|
||||
offset_wd += 1
|
||||
|
||||
$VBoxContainer/Control/Index.rect_position.x += offset_index*offset
|
||||
$VBoxContainer/Control/Index.rect_position.y -= offset_index*offset
|
||||
|
||||
$VBoxContainer/Control/WD.rect_position.x += offset_wd*offset
|
||||
$VBoxContainer/Control/WD.rect_position.y -= offset_wd*offset
|
||||
|
||||
if conflict:
|
||||
$VBoxContainer/Control/Index.self_modulate = Color(1, 0.2, 0.2, 0.5)
|
||||
|
||||
$VBoxContainer/Control/HEAD.visible = exists_in_head
|
||||
$VBoxContainer/Control/Index.visible = exists_in_index
|
||||
$VBoxContainer/Control/WD.visible = exists_in_wd
|
||||
|
||||
func _set_label(new_label):
|
||||
label = new_label
|
||||
|
@ -25,33 +57,33 @@ func _set_label(new_label):
|
|||
func _gui_input(event):
|
||||
if event is InputEventMouseButton and event.is_pressed() and event.button_index == BUTTON_LEFT:
|
||||
emit_signal("clicked", self)
|
||||
if event is InputEventMouseButton and event.is_pressed() and event.button_index == BUTTON_RIGHT and status != IconStatus.REMOVED:
|
||||
$PopupMenu.set_position(get_global_mouse_position())
|
||||
$PopupMenu.popup()
|
||||
|
||||
func _set_status(new_status):
|
||||
if status_icon:
|
||||
match new_status:
|
||||
IconStatus.NEW:
|
||||
status_icon.texture = preload("res://images/new.svg")
|
||||
status_icon.modulate = Color("33BB33")
|
||||
IconStatus.REMOVED:
|
||||
status_icon.texture = preload("res://images/removed.svg")
|
||||
status_icon.modulate = Color("D10F0F")
|
||||
IconStatus.CONFLICT:
|
||||
status_icon.texture = preload("res://images/conflict.svg")
|
||||
status_icon.modulate = Color("DE5E09")
|
||||
IconStatus.EDIT:
|
||||
status_icon.texture = preload("res://images/modified.svg")
|
||||
status_icon.modulate = Color("344DED")
|
||||
IconStatus.UNTRACKED:
|
||||
status_icon.texture = preload("res://images/untracked.svg")
|
||||
status_icon.modulate = Color("9209B8")
|
||||
IconStatus.NONE:
|
||||
status_icon.texture = null
|
||||
|
||||
status = new_status
|
||||
# if event is InputEventMouseButton and event.is_pressed() and event.button_index == BUTTON_RIGHT and status != IconStatus.REMOVED:
|
||||
# $PopupMenu.set_position(get_global_mouse_position())
|
||||
# $PopupMenu.popup()
|
||||
|
||||
#func _set_status(new_status):
|
||||
# if status_icon:
|
||||
# match new_status:
|
||||
# IconStatus.NEW:
|
||||
# status_icon.texture = preload("res://images/new.svg")
|
||||
# status_icon.modulate = Color("33BB33")
|
||||
# IconStatus.REMOVED:
|
||||
# status_icon.texture = preload("res://images/removed.svg")
|
||||
# status_icon.modulate = Color("D10F0F")
|
||||
# IconStatus.CONFLICT:
|
||||
# status_icon.texture = preload("res://images/conflict.svg")
|
||||
# status_icon.modulate = Color("DE5E09")
|
||||
# IconStatus.EDIT:
|
||||
# status_icon.texture = preload("res://images/modified.svg")
|
||||
# status_icon.modulate = Color("344DED")
|
||||
# IconStatus.UNTRACKED:
|
||||
# status_icon.texture = preload("res://images/untracked.svg")
|
||||
# status_icon.modulate = Color("9209B8")
|
||||
# IconStatus.NONE:
|
||||
# status_icon.texture = null
|
||||
#
|
||||
# status = new_status
|
||||
#
|
||||
|
||||
|
||||
func _popup_menu_pressed(_id):
|
||||
|
|
|
@ -53,13 +53,15 @@ __meta__ = {
|
|||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="VBoxContainer/Control"]
|
||||
[node name="HEAD" type="TextureRect" parent="VBoxContainer/Control"]
|
||||
self_modulate = Color( 0, 0, 0, 0.317647 )
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = 8.0
|
||||
margin_top = 8.0
|
||||
margin_right = -8.0
|
||||
margin_bottom = -8.0
|
||||
margin_left = -9.54361
|
||||
margin_top = 0.372345
|
||||
margin_right = -25.5436
|
||||
margin_bottom = -15.6277
|
||||
rect_scale = Vector2( 1.2, 1.2 )
|
||||
texture = ExtResource( 3 )
|
||||
expand = true
|
||||
stretch_mode = 6
|
||||
|
@ -67,15 +69,30 @@ __meta__ = {
|
|||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="StatusIcon" type="TextureRect" parent="VBoxContainer/Control/TextureRect"]
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
margin_left = -11.2842
|
||||
margin_top = 0.810516
|
||||
margin_right = 13.7158
|
||||
margin_bottom = 25.8105
|
||||
[node name="Index" type="TextureRect" parent="VBoxContainer/Control"]
|
||||
self_modulate = Color( 0.54902, 0.45098, 1, 0.654902 )
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = -1.15317
|
||||
margin_top = 4.18617
|
||||
margin_right = -17.1532
|
||||
margin_bottom = -11.8138
|
||||
rect_scale = Vector2( 1.1, 1.1 )
|
||||
texture = ExtResource( 3 )
|
||||
expand = true
|
||||
stretch_mode = 6
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="WD" type="TextureRect" parent="VBoxContainer/Control"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = 8.0
|
||||
margin_top = 8.0
|
||||
margin_right = -8.0
|
||||
margin_bottom = -8.0
|
||||
texture = ExtResource( 3 )
|
||||
expand = true
|
||||
stretch_mode = 6
|
||||
__meta__ = {
|
||||
|
|
|
@ -15,7 +15,6 @@ onready var level_description = $Rows/Columns/RightSide/LevelInfo/LevelPanel/Tex
|
|||
onready var level_congrats = $Rows/Columns/RightSide/LevelInfo/LevelPanel/Text/LevelCongrats
|
||||
onready var cards = $Rows/Controls/Cards
|
||||
onready var file_browser = $Rows/Columns/RightSide/FileBrowser
|
||||
onready var index = $Rows/Columns/RightSide/Index
|
||||
|
||||
var _hint_server
|
||||
var _hint_client_connection
|
||||
|
@ -93,10 +92,8 @@ func load_level(level_id):
|
|||
new_repo.size_flags_horizontal = SIZE_EXPAND_FILL
|
||||
new_repo.size_flags_vertical = SIZE_EXPAND_FILL
|
||||
if new_repo.label == "yours":
|
||||
file_browser.shell = new_repo.shell
|
||||
file_browser.repository = new_repo
|
||||
file_browser.update()
|
||||
index.repository = new_repo
|
||||
index.update()
|
||||
repositories_node.add_child(new_repo)
|
||||
repositories[r] = new_repo
|
||||
|
||||
|
@ -169,7 +166,6 @@ func update_repos():
|
|||
var repo = repositories[r]
|
||||
repo.update_everything()
|
||||
file_browser.update()
|
||||
index.update()
|
||||
|
||||
func toggle_cards():
|
||||
cards.visible = not cards.visible
|
||||
|
|
|
@ -84,7 +84,7 @@ custom_constants/separation = 8
|
|||
|
||||
[node name="LevelInfo" type="VBoxContainer" parent="Rows/Columns/RightSide"]
|
||||
margin_right = 633.0
|
||||
margin_bottom = 383.0
|
||||
margin_bottom = 516.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
custom_constants/separation = 8
|
||||
|
@ -171,7 +171,7 @@ __meta__ = {
|
|||
[node name="LevelPanel" type="VBoxContainer" parent="Rows/Columns/RightSide/LevelInfo"]
|
||||
margin_top = 47.0
|
||||
margin_right = 633.0
|
||||
margin_bottom = 383.0
|
||||
margin_bottom = 516.0
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="LevelName" type="RichTextLabel" parent="Rows/Columns/RightSide/LevelInfo/LevelPanel"]
|
||||
|
@ -187,7 +187,7 @@ __meta__ = {
|
|||
[node name="Text" type="Control" parent="Rows/Columns/RightSide/LevelInfo/LevelPanel"]
|
||||
margin_top = 65.0
|
||||
margin_right = 633.0
|
||||
margin_bottom = 336.0
|
||||
margin_bottom = 469.0
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="LevelDescription" type="RichTextLabel" parent="Rows/Columns/RightSide/LevelInfo/LevelPanel/Text"]
|
||||
|
@ -213,26 +213,14 @@ __meta__ = {
|
|||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
[node name="Index" parent="Rows/Columns/RightSide" instance=ExtResource( 5 )]
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_top = 391.0
|
||||
margin_right = 633.0
|
||||
margin_bottom = 582.0
|
||||
size_flags_vertical = 3
|
||||
size_flags_stretch_ratio = 0.5
|
||||
title = "Plan for the next commit"
|
||||
mode = 2
|
||||
|
||||
[node name="FileBrowser" parent="Rows/Columns/RightSide" instance=ExtResource( 5 )]
|
||||
anchor_right = 0.0
|
||||
anchor_bottom = 0.0
|
||||
margin_top = 590.0
|
||||
margin_top = 524.0
|
||||
margin_right = 633.0
|
||||
margin_bottom = 782.0
|
||||
size_flags_vertical = 3
|
||||
size_flags_stretch_ratio = 0.5
|
||||
title = "Current environment"
|
||||
|
||||
[node name="Controls" type="HBoxContainer" parent="Rows"]
|
||||
margin_top = 790.0
|
||||
|
|
Loading…
Reference in a new issue