Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Аdd Github mirror to RemoteEditors #36

Merged
merged 1 commit into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
434 changes: 37 additions & 397 deletions src/components/editors/remote/remote_editors.gd

Large diffs are not rendered by default.

24 changes: 6 additions & 18 deletions src/components/editors/remote/remote_editors.tscn
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
[gd_scene load_steps=6 format=3 uid="uid://dxnoecc3ruw3t"]
[gd_scene load_steps=7 format=3 uid="uid://dxnoecc3ruw3t"]

[ext_resource type="Script" path="res://src/components/editors/remote/remote_editors.gd" id="1_80m0a"]
[ext_resource type="PackedScene" uid="uid://cb6u1mub27xo" path="res://src/components/asset_download/asset_download.tscn" id="2_obpx8"]
[ext_resource type="PackedScene" uid="uid://ca7g1asyno8ik" path="res://src/components/editors/remote/remote_editor_install/remote_editor_install.tscn" id="3_wvg3b"]
[ext_resource type="PackedScene" uid="uid://dhvesrdvhm6lv" path="res://src/components/editors/remote/remote_editor_direct_link/remote_editor_direct_link.tscn" id="4_nu1uq"]
[ext_resource type="PackedScene" uid="uid://cuuiumge42ghh" path="res://src/components/actions_sidebar/actions_sidebar.tscn" id="4_s82j0"]
[ext_resource type="PackedScene" uid="uid://jq7lowjivf6a" path="res://src/components/editors/remote/remote_editors_tree/remote_editors_tree.tscn" id="5_yj8hk"]

[node name="RemoteEditors" type="Control"]
layout_mode = 3
Expand All @@ -30,25 +31,10 @@ grow_vertical = 2
layout_mode = 2
size_flags_vertical = 3

[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3

[node name="Tree" type="Tree" parent="VBoxContainer/HBoxContainer/VBoxContainer"]
[node name="RemoteEditorsTree" parent="VBoxContainer/HBoxContainer" instance=ExtResource("5_yj8hk")]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
hide_root = true

[node name="CheckBoxPanelContainer" type="PanelContainer" parent="VBoxContainer/HBoxContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2

[node name="CheckBoxContainer" type="HFlowContainer" parent="VBoxContainer/HBoxContainer/VBoxContainer/CheckBoxPanelContainer"]
unique_name_in_owner = true
layout_mode = 2
alignment = 1

[node name="ActionsSidebar" parent="VBoxContainer/HBoxContainer" instance=ExtResource("4_s82j0")]
layout_mode = 2
Expand All @@ -71,6 +57,8 @@ text = "Refresh"
[node name="HSeparator" parent="VBoxContainer/HBoxContainer/ActionsSidebar" index="1"]
visible = false

[connection signal="visibility_changed" from="." to="." method="_on_visibility_changed"]
[node name="TreeMirrorButton" type="OptionButton" parent="VBoxContainer/HBoxContainer/ActionsSidebar"]
unique_name_in_owner = true
layout_mode = 2

[editable path="VBoxContainer/HBoxContainer/ActionsSidebar"]
91 changes: 91 additions & 0 deletions src/components/editors/remote/remote_editors_tree/data_source.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
class_name RemoteEditorsTreeDataSource


class I:
func setup(tree: Tree):
pass

func cleanup(tree: Tree):
pass

func get_platform_suffixes():
pass

func to_remote_item(item: TreeItem) -> Item:
return null


# TODO looks bad
class RemoteAssets:
func download(url, file_name):
pass


class RemoteAssetsCallable extends RemoteAssets:
var _callable: Callable

func _init(callable: Callable):
_callable = callable

func download(url, file_name):
_callable.call(url, file_name)


class FilterTarget:
func is_possible_version_folder() -> bool:
return false

func is_file() -> bool:
return false

func is_for_different_platform(platform_suffixes) -> bool:
return false

func get_name() -> String:
return ''


class RemoteTree:
var _tree: Tree
var _theme_source: Control

var theme_source: Control:
get: return _theme_source

func _init(tree, theme_source: Control):
_tree = tree
_theme_source = theme_source

func create_item(parent: TreeItem) -> TreeItem:
var result = _tree.create_item(parent)
return result

func free_loading_placeholder(tree_item: TreeItem):
if tree_item.has_meta("loading_placeholder"):
tree_item.get_meta("loading_placeholder").free()

func set_as_folder(tree_item: TreeItem):
tree_item.set_icon(0, _theme_source.get_theme_icon("Folder", "EditorIcons"))
tree_item.set_icon_modulate(0, _theme_source.get_theme_color("folder_icon_color", "FileDialog"))
var placeholder = _tree.create_item(tree_item)
placeholder.set_text(0, tr("loading..."))
# TODO animate
placeholder.set_icon(0, _theme_source.get_theme_icon("Progress1", "EditorIcons"))
tree_item.set_meta("loading_placeholder", placeholder)


class Item:
func is_loaded() -> bool:
return false

func async_expand(tree: RemoteTree):
return

func handle_button_clicked(col, id, mouse):
pass

func update_visibility(filters):
pass

func get_children() -> Array[Item]:
return []
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
extends VBoxContainer


signal _loadings_number_changed(value)

const uuid = preload("res://addons/uuid.gd")

@onready var _tree: Tree = %Tree
@onready var _check_box_container: HFlowContainer = %CheckBoxContainer

var _refresh_button: Button
var _remote_assets: RemoteEditorsTreeDataSource.RemoteAssets

var _src: RemoteEditorsTreeDataSource.I
var _i_remote_tree: RemoteEditorsTreeDataSource.RemoteTree
var _root_loaded = false
var _row_filters: Array[RowFilter] = [NotRelatedFilter.new()]
var _current_loadings_number = 0:
set(value):
_current_loadings_number = value
_loadings_number_changed.emit(value)
var _remote_editors_checkbox_checked = Cache.smart_section(
Cache.section_of(self) + ".checkbox_checked", true
)


func post_ready(refresh_button: Button):
_refresh_button = refresh_button

_setup_tree()
_setup_checkboxes()

_refresh_button.pressed.connect(func():
_refresh()
)

_loadings_number_changed.connect(func(value):
_refresh_button.disabled = value != 0
)


func _ready():
visibility_changed.connect(_on_visibility_changed)


func set_data_source(src: RemoteEditorsTreeDataSource.I):
if _src != null:
_src.cleanup(_tree)
_src = src
_src.setup(_tree)
_refresh()


func _refresh():
for c in _tree.get_root().get_children():
c.free()
_expand(_delegate_of(_tree.get_root()))


func _setup_checkboxes():
%CheckBoxPanelContainer.add_theme_stylebox_override("panel", get_theme_stylebox("panel", "Tree"))

var checkbox = func(text, filter, button_pressed=false):
var box = CheckBox.new()
box.text = text
box.button_pressed = button_pressed
if button_pressed:
_row_filters.append(filter)
box.toggled.connect(func(pressed):
if pressed:
_row_filters.append(filter)
else:
var idx = _row_filters.find(filter)
_row_filters.remove_at(idx)
_remote_editors_checkbox_checked.set_value(text, pressed)
_update_whole_tree_visibility(_delegate_of(_tree.get_root()))
)
return box

var inverted_checkbox = func(text, filter, button_pressed=false):
var box = CheckBox.new()
box.text = text
box.button_pressed = button_pressed
if not button_pressed:
_row_filters.append(filter)
box.toggled.connect(func(pressed):
if pressed:
var idx = _row_filters.find(filter)
if idx >= 0:
_row_filters.remove_at(idx)
else:
_row_filters.append(filter)
_remote_editors_checkbox_checked.set_value(text, pressed)
_update_whole_tree_visibility(_delegate_of(_tree.get_root()))
)
return box

var contains_any = func(words):
return func(row: RemoteEditorsTreeDataSource.FilterTarget):
return words.any(func(x): return row.get_name().to_lower().contains(x.to_lower()))

var _not = func(original):
return func(row): return not original.call(row)

_check_box_container.add_child(
inverted_checkbox.call(
tr("mono"),
RowFilter.new(contains_any.call(["mono"])),
_remote_editors_checkbox_checked.get_value("mono", true)
)
)

_check_box_container.add_child(
inverted_checkbox.call(
tr("unstable"),
RowFilter.new(contains_any.call(["rc", "beta", "alpha", "dev", "fixup"])),
_remote_editors_checkbox_checked.get_value("unstable", false)
)
)

_check_box_container.add_child(
inverted_checkbox.call(
tr("any platform"),
RowFilter.new(func(row):
return row.is_file() and row.is_for_different_platform(_src.get_platform_suffixes())),
_remote_editors_checkbox_checked.get_value("any platform", false)
)
)

if not OS.has_feature("macos"):
var bit
var opposite
if OS.has_feature("32"):
bit = "32"
opposite = "64"
elif OS.has_feature("64"):
bit = "64"
opposite = "32"
if bit:
_check_box_container.add_child(
checkbox.call(
"%s-bit" % bit,
RowFilter.new(contains_any.call([opposite])),
_remote_editors_checkbox_checked.get_value("%s-bit" % bit, true)
)
)

_check_box_container.add_child(
inverted_checkbox.call(
tr("4.x"),
RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget):
return row.is_possible_version_folder() and row.get_name().begins_with("4")),
_remote_editors_checkbox_checked.get_value("4.x", true)
)
)

_check_box_container.add_child(
inverted_checkbox.call(
tr("3.x"),
RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget):
return row.is_possible_version_folder() and row.get_name().begins_with("3")),
_remote_editors_checkbox_checked.get_value("3.x", true)
)
)

_check_box_container.add_child(
inverted_checkbox.call(
tr("x.x"),
RowFilter.new(func(row: RemoteEditorsTreeDataSource.FilterTarget):
return row.is_possible_version_folder() and not (row.get_name().begins_with("4") or row.get_name().begins_with("3"))),
_remote_editors_checkbox_checked.get_value("x.x", false)
)
)


func _delegate_of(item: TreeItem) -> RemoteEditorsTreeDataSource.Item:
return _src.to_remote_item(item)


func _setup_tree():
_i_remote_tree = RemoteEditorsTreeDataSource.RemoteTree.new(_tree, self)

_tree.item_collapsed.connect(
func(x: TreeItem):
var expanded = not x.collapsed
var delegate = _delegate_of(x)
var not_loaded_yet = not delegate.is_loaded()
if expanded and not_loaded_yet:
_expand.call_deferred(delegate)
# _expand(delegate)
)

_tree.button_clicked.connect(func(item, col, id, mouse):
var delegate = _delegate_of(item)
delegate.handle_button_clicked(col, id, mouse)
)


func _expand(remote_tree_item: RemoteEditorsTreeDataSource.Item):
_current_loadings_number += 1
await remote_tree_item.async_expand(_i_remote_tree)
_update_whole_tree_visibility(remote_tree_item)
_current_loadings_number -= 1


func _update_whole_tree_visibility(from: RemoteEditorsTreeDataSource.Item):
from.update_visibility(_row_filters)
for child in from.get_children():
_update_whole_tree_visibility(child)


func _on_visibility_changed() -> void:
if is_visible_in_tree() and not _root_loaded:
_expand(_delegate_of(_tree.get_root()))
_root_loaded = true


class RowFilter:
var _delegate

func _init(delegate):
_delegate = delegate

func test(row: RemoteEditorsTreeDataSource.FilterTarget) -> bool:
return _delegate.call(row)


class SimpleContainsFilter extends RowFilter:
func _init(what: String):
super._init(
func(row: RemoteEditorsTreeDataSource.FilterTarget):
return row.get_name().to_lower().contains(what)
)


class NotRelatedFilter extends RowFilter:
func _init():
super._init(
func(row: RemoteEditorsTreeDataSource.FilterTarget):
return ["media", "patreon", "testing", "toolchains"].any(
func(x): return row.get_name() == x
)
)
Loading