diff --git a/table/table.gd b/table/table.gd index ec132002..7637cfe7 100644 --- a/table/table.gd +++ b/table/table.gd @@ -32,6 +32,19 @@ var header: GridContainer # Заголовок таблицы signal row_pressed(i_row: int) # Вызывается при нажатии кнопкой мыши на строку signal selected_changed(i_row: int) # Вызывается при изменении выбранного ряда. i_row - текущий выбранный ряд +var scroll: Control +var scroll_adj: = Vector2(0, 0) + + +func pin_header(scrl: ScrollContainer, prnt): + scrl.remove_child(header) + prnt.add_child(header) + # TODO: Это значение следует получить из темы + var v_separation: = 3.0 + header.position = scrl.position - Vector2(0, header.size.y + v_separation) + scroll = scrl + scroll_adj = scrl.position + func selector_up(): var i_rows: = [] @@ -93,11 +106,11 @@ func _ready(): assert(ScnNode) -func align_to_left_bottom(header, gap: = Vector2(0, 0)): +func align_to_left_bottompos(hdr: Control, gap: = Vector2(0, 0)): """ Выравнивает по нижнему левому углу. Используется для выравнивания по заголовку """ - position.x = header.position.x + gap.x - position.y = header.position.y + header.size.y + gap.y + position.x = hdr.position.x + gap.x + position.y = hdr.position.y + hdr.size.y + gap.y func _assert_meta(i_col: int, i_row: int, pname: String, node): @@ -165,26 +178,14 @@ func _input(event) -> void: elif event is InputEventMouseButton: if not event.pressed: return - if (event.position.x < position.x) \ - or (event.position.x > (position.x + size.x)) \ - or (event.position.y < position.y) \ - or (event.position.y > (position.y + size.y)): - in_focus = false - emit_signal('focus_exited') - return - var rows_count: = get_rows_count() - in_focus = true - emit_signal('focus_entered') - for i_row in rows_count: - var rect = [0, 0, 0, 0] - get_node_rect(0, i_row, rect) - var y = rect[1] + position.y - if event.position.y < y: - continue - if event.position.y > (y + rect[3]): - continue - emit_signal('row_pressed', i_row) - break + if check_event_pos(event.position, scroll): + if not in_focus: + in_focus = true + emit_signal('focus_entered') + elif not check_event_pos(event.position, scroll): + if in_focus: + in_focus = false + emit_signal('focus_exited') func _init() -> void: @@ -192,6 +193,15 @@ func _init() -> void: assert(selector_color_proc.is_valid()) selector_size_proc = Callable(self, 'default_selector_size_proc') assert(selector_size_proc.is_valid()) + scroll = self + + +func check_event_pos(event_pos: Vector2, obj: Control): + return \ + (event_pos.x > obj.position.x) \ + and (event_pos.x < (obj.position.x + obj.size.x)) \ + and (event_pos.y > obj.position.y) \ + and (event_pos.y < (obj.position.y + obj.size.y)) func defaultselector_color_proc(_i_row: int): @@ -210,10 +220,10 @@ func set_selector_size_proc(instance: Object, function: String) -> void: func default_selector_size_proc(i_row: int, rect: Array) -> void: get_row_rect(i_row, rect) - rect[0] = rect[0] + position.x - node_gap.x / 2.0 - rect[1] = rect[1] + position.y - node_gap.y / 2.0 - rect[2] = rect[2] + node_gap.x - rect[3] = rect[3] + node_gap.y + rect[0] += position.x - node_gap.x / 2.0 + rect[1] += position.y - node_gap.y / 2.0 + rect[2] += node_gap.x + rect[3] += node_gap.y func clear_rows_selected(): @@ -224,35 +234,34 @@ func clear_rows_selected(): func set_row_selected(i_row: int, selected: bool = true) -> void: var key: = ROW_SELECTOR_KEY_FORMAT % [i_row, 0] - var parent = get_parent() + var node = nodes[NODE_KEY_FORMAT % [i_row, 0]] if nodes.has(key) and (not selected): var selector = nodes[key] - parent.remove_child(selector) + node.remove_child(selector) selector.queue_free() nodes.erase(key) elif (not nodes.has(key)) and selected: var selector = ScnSelector.instantiate() var rect: = [0, 0, 0, 0] selector_size_proc.call(i_row, rect) - selector.position.x = rect[0] - selector.position.y = rect[1] selector.size.x = rect[2] selector.size.y = rect[3] selector.modulate = selector_color_proc.call(i_row) + selector.z_index = z_index + 1 nodes[key] = selector - parent.add_child(selector) + node.add_child(selector) func is_row_selected(i_row: int) -> bool: - var key: = get_node_key(ROW_SELECTOR_KEY_FORMAT, 0, i_row) + var key: = ROW_SELECTOR_KEY_FORMAT % [i_row, 0] return nodes.has(key) -func get_selected_rows(rows: Array) -> void: +func get_selected_rows(i_rows: Array) -> void: for key in nodes.keys(): if SLCT_PREFIX in key: var indexes = get_key_indexes(key) - rows.append(indexes[1]) + i_rows.append(indexes[1]) func get_rows_count() -> int: @@ -282,10 +291,19 @@ func add_row(row_types: Array) -> void: assert(rows_count < MAX_INDEX, 'ошибка: слишком много рядов, больше %d' % (MAX_INDEX + 1)) for i_col in columns: var node = row_types[i_col].instantiate() + var head = nodes[HEAD_KEY_FORMAT % [0, i_col]] + node.custom_minimum_size.x = head.custom_minimum_size.x + node.size.x = head.size.x var key: String = NODE_KEY_FORMAT % [rows_count, i_col] node.name = key add_child(node) nodes[key] = node + node.connect('focus_entered', Callable(self, '_on_focus_entered').bind(key)) + + +func _on_focus_entered(key): + var indexes = get_key_indexes(key) + emit_signal('row_pressed', indexes[1]) func set_header(header_types: Array): @@ -300,7 +318,7 @@ func set_header(header_types: Array): header.position = position header.columns = header_types.size() header.size.x = size.x - var parent = get_parent() + var parent = scroll.get_parent() parent.add_child(header) do_adj = true else: @@ -335,7 +353,9 @@ func remove_row(i_row: int): var sel_key: String = ROW_SELECTOR_KEY_FORMAT % [i_row, 0] if nodes.has(sel_key): var selector = nodes[sel_key] - get_parent().remove_child(selector) + var node_key: String = get_node_key(NODE_KEY_FORMAT, 0, i_row) + var node = nodes[node_key] + node.get_parent().remove_child(selector) selector.queue_free() nodes.erase(sel_key) for i_col in columns: @@ -405,7 +425,7 @@ func clear_rows() -> void: remove_row(i_row) -func set_callbacks(dest_node: Node, event_name: String, callback: String, clmns: Array, user_data: Array) -> void: +func connect_columns(dest_node: Node, event_name: String, callback: String, clmns: Array, user_data: Array) -> void: """ Настраивает обратные вызовы для колонок. :dest_node: Получатель события :event_name: Имя события @@ -496,7 +516,8 @@ func get_row_text(i_row: int) -> Array: func set_row_text(i_row: int, row: Array, i_begin: int = 0, key_format: String = NODE_KEY_FORMAT) -> void: - assert((i_begin + row.size()) < columns) + assert(i_begin >= 0) + assert((columns - i_begin) <= row.size()) for i_col in columns - i_begin: var key: = get_node_key(key_format, i_col + i_begin, i_row) nodes[key].text = row[i_col] @@ -533,7 +554,7 @@ func get_row_rect(i_row: int, rect: Array, key_format: String = NODE_KEY_FORMAT) 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 - rect[1] = cell0.position.y + rect[0] = cell0.position.x + scroll_adj.x + rect[1] = cell0.position.y + scroll_adj.y rect[2] = (cell1.position.x - cell0.position.x) + cell1.size.x rect[3] = cell0.size.y