Merge remote-tracking branch 'refs/remotes/Cat/master'

# Conflicts:
#	scenes/настройки/настройки.gd
This commit is contained in:
lepshiy
2025-02-25 16:11:20 +03:00
144 changed files with 587 additions and 27439 deletions

View File

@@ -10,8 +10,8 @@ class_name GDTable extends GridContainer
@export_file var selector_type_file: = 'res://table/selector.tscn': set = load_selector_scene ## Сцена селектора для выбранного ряда
const HEAD_PREFIX = 'HEAD_' ## Префикс ключа заголовка таблицы
const INDEX_FORMAT = '%02d_%02d' ## Формат индекса ключа
const MAX_INDEX = 99 ## Максимальное значение индекса для колонки и строки. Связано с форматом индекса ключа
const INDEX_FORMAT = '%03d_%03d' ## Формат индекса ключа
const MAX_INDEX = 199 ## Максимальное значение индекса для колонки и строки. Связано с форматом индекса ключа
const NODE_PREFIX = 'NODE_' ## Префикс ключа ячейки таблицы
const SLCT_PREFIX = 'SLCT_' ## Префикс ключа индикатора выбранного ряда таблицы
@@ -47,12 +47,18 @@ var scroll_adj: = Vector2(0, 0)
func get_node_scene(): return node_type_file
func assert_meta(i_col: int, i_row: int, pname: String, node): assert(node.has_meta(pname), 'ошибка: нет мета-свойства \"%s\" у ячейки колонка:%d ряд:%d' % [pname, i_col, i_row])
func _assert_meta(i_col: int, i_row: int, pname: String, node): _assert(node.has_meta(pname), 'нет мета-свойства \"%s\" у ячейки колонка:%d ряд:%d' % [pname, i_col, i_row])
func get_node_user_data(i_col: int, i_row: int): return get_node_meta(i_col, i_row, META_USER_DATA)
func set_node_user_data(i_col: int, i_row: int, val) -> void: set_node_meta(i_col, i_row, META_USER_DATA, val)
func defaultselector_color_proc(_i_row: int): return selector_color
func _assert(val: bool, msg: String = '<не указано>'):
if val: return
push_error('ошибка: %s\n' % msg)
get_tree().quit(1)
## Закрепляет заголовок таблицы.[br]
## [param scrl] - Прокрутка родитель таблицы.[br]
## [param prnt] - Родитель прокрутки.[br]
@@ -74,8 +80,7 @@ func selector_up():
var rows_count: = get_rows_count()
if not (i_rows.size() and (rows_count > 1)):
return
var i_row = i_rows[0]
i_row -= 1
var i_row = i_rows[0] - 1
if i_row < 0:
i_row = rows_count - 1
set_row_selected(i_row, true)
@@ -94,8 +99,7 @@ func selector_down():
var rows_count: = get_rows_count()
if not (i_rows.size() and (rows_count > 1)):
return
var i_row = i_rows[0]
i_row += 1
var i_row = i_rows[0] + 1
i_row %= rows_count
set_row_selected(i_row, true)
var node = get_node2(0, i_row)
@@ -106,7 +110,7 @@ func selector_down():
## Делает ряд [param i_row] видимым.
func ensure_row_visible(i_row: int):
assert(scroll is ScrollContainer, 'Таблица должна быть дочерней к ScrollContainer')
_assert(scroll is ScrollContainer, 'таблица %s должна быть дочерней к ScrollContainer' % self)
var key: = get_node_key(NODE_KEY_FORMAT, 0, i_row)
var node = nodes[key]
scroll.ensure_control_visible(node)
@@ -114,7 +118,7 @@ func ensure_row_visible(i_row: int):
## Устанавливает выравнивание из массива [param alignments] для всех колонок.
func set_columns_alignments(alignments: Array):
assert(columns == alignments.size())
_assert(columns == alignments.size())
var rows_count: = get_rows_count()
for i_row in rows_count:
for i_col in alignments.size():
@@ -123,22 +127,26 @@ func set_columns_alignments(alignments: Array):
##
func load_selector_scene(file_name: String):
_assert(ResourceLoader.exists(file_name), '\"%s\" не найден' % file_name)
selector_type_file = file_name
ScnSelector = load(file_name)
_assert(ScnSelector is PackedScene, '\"%s\" не PackedScene' % ScnSelector)
##
func load_node_scene(file_name: String):
_assert(ResourceLoader.exists(file_name), '\"%s\" не найден' % file_name)
node_type_file = file_name
ScnNode = load(file_name)
_assert(ScnNode is PackedScene, '\"%s\" не PackedScene' % ScnNode)
##
func _ready():
ScnSelector = load(selector_type_file)
ScnNode = load(node_type_file)
assert(ScnSelector is PackedScene)
assert(ScnNode is PackedScene)
_assert(ScnSelector is PackedScene, '\"%s\" не PackedScene' % ScnSelector)
_assert(ScnNode is PackedScene, '\"%s\" не PackedScene' % ScnNode)
## Выравнивает по нижнему левому углу. Используется для выравнивания по заголовку.
@@ -165,7 +173,7 @@ func set_node_meta(i_col: int, i_row: int, pname: String, val) -> void:
func get_node_meta(i_col: int, i_row: int, pname: String):
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
var node = nodes[key]
assert_meta(i_col, i_row, pname, node)
_assert_meta(i_col, i_row, pname, node)
return node.get_meta(pname)
@@ -197,7 +205,7 @@ func get_node_property(i_col: int, i_row: int, pname: String):
## [param i_row] - Индекс ряда
func get_node_key(format: String, i_col: int, i_row: int) -> String:
var key: String = format % [i_row, i_col]
assert(nodes.has(key), 'ошибка: нет такой ячейки - колонка:%d ряд:%d' % [i_col, i_row])
_assert(nodes.has(key), 'нет такой ячейки - колонка:%d ряд:%d' % [i_col, i_row])
return key
@@ -206,13 +214,13 @@ func get_node_key(format: String, i_col: int, i_row: int) -> String:
## [b][1][/b] - индекс строки.
func get_key_indexes(key: String) -> Array:
var tokens: = key.split('_')
assert(tokens.size() == 3, 'ошибка: неверный ключ: \"%s\"' % key)
_assert(tokens.size() == 3, 'неверный ключ: \"%s\"' % key)
return [int(tokens[2]), int(tokens[1])]
##
func set_columns_min_size(sizes: Array) -> void:
assert((columns == 1) or (columns == sizes.size()))
_assert(columns == sizes.size(), 'неверный размер массива с ширинами колонок: передано %d, но требуется %d' % [sizes.size(), columns])
columns = sizes.size()
var rows_count: = get_rows_count()
columns_min_size.clear()
@@ -257,9 +265,9 @@ func _input(event) -> void:
##
func _init() -> void:
selector_color_proc = Callable(self, 'defaultselector_color_proc')
assert(selector_color_proc.is_valid())
_assert(selector_color_proc.is_valid(), 'defaultselector_color_proc(): обработчик \"%s\" не является Callable' % selector_color_proc)
selector_size_proc = Callable(self, 'default_selector_size_proc')
assert(selector_size_proc.is_valid())
_assert(selector_size_proc.is_valid(), 'default_selector_size_proc(): обработчик \"%s\" не является Callable' % selector_size_proc)
scroll = self
@@ -275,13 +283,13 @@ func check_event_pos(event_pos: Vector2, obj: Control):
##
func setselector_color_proc(instance: Object, function: String) -> void:
selector_color_proc = Callable(instance, function)
assert(selector_color_proc.is_valid())
_assert(selector_color_proc.is_valid())
##
func set_selector_size_proc(instance: Object, function: String) -> void:
selector_size_proc = Callable(instance, function)
assert(selector_size_proc.is_valid())
_assert(selector_size_proc.is_valid())
## [param i_row] - Индекс ряда
@@ -309,9 +317,7 @@ func set_row_selected(i_row: int, selected: bool = true) -> void:
func _set_row_selected(i_row: int, selected: bool = true) -> void:
var selector_key: = SELECTOR_KEY_FORMAT % [i_row, 0]
var node_key: = NODE_KEY_FORMAT % [i_row, 0]
if not nodes.has(node_key):
push_error('ошибка: нет такого ряда: %d' % i_row)
return
_assert(nodes.has(node_key), 'нет такого ряда: %d' % i_row)
if nodes.has(selector_key) and (not selected):
var node = nodes[node_key]
var selector = nodes[selector_key]
@@ -361,18 +367,18 @@ func get_node2(i_col: int, i_row: int) -> Node:
## Добавляет ряд. [param row_types] - Массив типов ячеек ряда
func add_row(row_types: Array) -> void:
assert(row_types.size() < MAX_INDEX, 'ошибка: слишком много колонок, больше %d' % (MAX_INDEX + 1))
_assert(row_types.size() < MAX_INDEX, 'колонок больше, чем %d' % (MAX_INDEX + 1))
if columns == 1:
set_columns(row_types.size())
else:
assert(columns == row_types.size(), 'ошибка: %s количество колонок установлено ранее - %d, но требуется %d' % [self, columns, row_types.size()])
_assert(columns == row_types.size(), '%s количество колонок установлено ранее - %d, но требуется %d' % [self, columns, row_types.size()])
var i_row: int = get_rows_count()
assert(i_row < MAX_INDEX, 'ошибка: слишком много рядов, больше %d' % (MAX_INDEX + 1))
_assert(i_row < MAX_INDEX, 'рядов больше, чем %d' % (MAX_INDEX + 1))
var allow_set_size = columns_min_size.size() >= row_types.size()
for i_col in columns:
var node_type = row_types[i_col]
var node = node_type.instantiate()
assert(node.name == node.name, 'ошибка: экземпляр не имеет поля \"name\"')
_assert(node.get('name') is StringName, 'экземпляр не имеет поля \"name\"')
var node_key: String = NODE_KEY_FORMAT % [i_row, i_col]
node.name = node_key
add_child(node)
@@ -393,11 +399,11 @@ func _on_focus_entered(node):
##
func set_header(header_types: Array):
assert(header_types.size() < MAX_INDEX, 'ошибка: количество колонок в заголовке: %d больше допустимого: %d' % [header_types.size(), MAX_INDEX + 1])
_assert(header_types.size() < MAX_INDEX, 'количество колонок в заголовке: %d больше допустимого: %d' % [header_types.size(), MAX_INDEX + 1])
if columns == 1:
set_columns(header_types.size())
else:
assert(columns == header_types.size(), 'ошибка: количество колонок в заголовке %d, но ранее установлено: %d' % [header_types.size(), columns])
_assert(columns == header_types.size(), 'количество колонок в заголовке %d, но ранее установлено: %d' % [header_types.size(), columns])
var do_adj: = false
if not header:
header = GridContainer.new()
@@ -426,7 +432,7 @@ func set_header(header_types: Array):
##
func set_header_text(headers: Array):
assert(columns == headers.size())
_assert(columns == headers.size(), 'количество элементов для заголовка %d, а должно быть %d' % [headers.size(), columns])
set_row_text(0, headers, 0, HEAD_KEY_FORMAT)
@@ -515,7 +521,7 @@ func connect_columns(dest_node: Node, event_name: String, callback: String, clmn
var rows_count = get_rows_count()
for i_row in rows_count:
for i_col in clmns:
assert(i_col >= 0 and i_col < columns, 'ошибка: нет такой колонки: %d' % i_col)
_assert(i_col >= 0 and i_col < columns, 'нет такой колонки: %d' % i_col)
var node = get_node2(i_col, i_row)
if node.has_meta(META_CALLABLE):
var conn_prev = node.get_meta(META_CALLABLE)
@@ -632,8 +638,8 @@ func get_row_text(i_row: int) -> Array:
## [param i_begin] - Начальный индекс колонки начиная с которого установить новые значения.[br]
## [i]Ячейки ряда должны иметь свойство[/i] [param text]
func set_row_text(i_row: int, row: Array, i_begin: int = 0, key_format: String = NODE_KEY_FORMAT) -> void:
assert((i_begin >= 0) and (i_begin < columns))
assert((columns - i_begin) >= row.size())
_assert((i_begin >= 0) and (i_begin < columns))
_assert((columns - i_begin) >= row.size())
for i_col in row.size():
var key: = get_node_key(key_format, i_col + i_begin, i_row)
nodes[key].text = row[i_col]
@@ -661,7 +667,7 @@ func get_row(i_row: int) -> Array:
## Возвращает прямоугольник [param rect] занимаемый ячейкой в ряду [param i_row] и колонке [param i_col].
## [param key_format] - Формат ключа ячейки
func get_node_rect(i_col: int, i_row: int, rect: Array, key_format: String = NODE_KEY_FORMAT) -> void:
assert(rect.size() >= 4, 'ошибка: мало элементов для возврата результата')
_assert(rect.size() >= 4, 'мало элементов для возврата результата')
var key: = get_node_key(key_format, i_col, i_row)
var cell = nodes[key]
rect[0] = cell.position.x
@@ -673,7 +679,7 @@ func get_node_rect(i_col: int, i_row: int, rect: Array, key_format: String = NOD
## Возвращает прямоугольник [param rect] занимаемый рядом [param i_row].[br]
## [param key_format] - Формат ключа ячейки
func get_row_rect(i_row: int, rect: Array, key_format: String = NODE_KEY_FORMAT) -> void:
assert(rect.size() >= 4, 'ошибка: мало элементов для возврата результата')
_assert(rect.size() >= 4, 'мало элементов для возврата результата')
var cell0 = nodes[get_node_key(key_format, 0, i_row)]
var cell1 = nodes[get_node_key(key_format, columns - 1, i_row)]
rect[0] = cell0.position.x + scroll_adj.x