Добавление таблицы в настройках
This commit is contained in:
@@ -4,9 +4,9 @@ const TAB_TOSIGNAL_NAME = {0: 'режим_работа', 1: 'режим_конт
|
||||
|
||||
|
||||
func _enter_tree() -> void:
|
||||
repnetwork.logger_page = $Журнал
|
||||
repnetwork.logger_page = $Журнал
|
||||
|
||||
|
||||
func _on_tab_changed(tab) -> void:
|
||||
if TAB_TOSIGNAL_NAME.has(tab):
|
||||
signaller.emit_signal(TAB_TOSIGNAL_NAME[tab])
|
||||
if TAB_TOSIGNAL_NAME.has(tab):
|
||||
signaller.emit_signal(TAB_TOSIGNAL_NAME[tab])
|
||||
|
||||
@@ -2,41 +2,41 @@ class_name main_tilemap extends Sprite2D
|
||||
|
||||
## Возможные состояния конечного автомата заданий.
|
||||
enum TASK_STATE {
|
||||
DONE, ## Выполнено.
|
||||
WAIT, ## Ожидание плитки.
|
||||
RUN, ## Запуск выполнения.
|
||||
CHECK, ## Проверка пустого места.
|
||||
ERROR ## Ошибка.
|
||||
DONE, ## Выполнено.
|
||||
WAIT, ## Ожидание плитки.
|
||||
RUN, ## Запуск выполнения.
|
||||
CHECK, ## Проверка пустого места.
|
||||
ERROR ## Ошибка.
|
||||
}
|
||||
|
||||
|
||||
## Координаты для проверок [lng, lat].
|
||||
const TEST_DATA: = {
|
||||
'Калиниград': [ 20.51095, 54.70649 ],
|
||||
'Москва': [ 37.6156, 55.7522 ],
|
||||
'Нью-Йорк': [ -74.006, 40.7143 ],
|
||||
'Сидней': [ 151.20732, -33.8678500 ],
|
||||
'Таганрог': [ 38.8969, 47.2362 ],
|
||||
'Хельсинки': [ 24.9354, 60.1695 ],
|
||||
'Азорские о-ва': [ 28.3996582, 38.5397568 ],
|
||||
'Мехико': [ -99.12766, 19.42847 ],
|
||||
'Белое море': [ 68.136606, 42.045546 ],
|
||||
'море Беллинсгаузена': [ -72.406587, -74.857997 ],
|
||||
'Фиджи': [ 178.065032, -17.713371 ],
|
||||
'Ноль': [ 0.0, 0.0 ],
|
||||
'Точка1': [ 170.0, 0.0 ],
|
||||
'Точка2': [-170.0, 0.0 ],
|
||||
'Море' : [ 19.4, 54.91 ] }
|
||||
'Калиниград': [ 20.51095, 54.70649 ],
|
||||
'Москва': [ 37.6156, 55.7522 ],
|
||||
'Нью-Йорк': [ -74.006, 40.7143 ],
|
||||
'Сидней': [ 151.20732, -33.8678500 ],
|
||||
'Таганрог': [ 38.8969, 47.2362 ],
|
||||
'Хельсинки': [ 24.9354, 60.1695 ],
|
||||
'Азорские о-ва': [ 28.3996582, 38.5397568 ],
|
||||
'Мехико': [ -99.12766, 19.42847 ],
|
||||
'Белое море': [ 68.136606, 42.045546 ],
|
||||
'море Беллинсгаузена': [ -72.406587, -74.857997 ],
|
||||
'Фиджи': [ 178.065032, -17.713371 ],
|
||||
'Ноль': [ 0.0, 0.0 ],
|
||||
'Точка1': [ 170.0, 0.0 ],
|
||||
'Точка2': [-170.0, 0.0 ],
|
||||
'Море' : [ 19.4, 54.91 ] }
|
||||
|
||||
|
||||
const MAP_MODES: = {
|
||||
0: 'application/config/map_image_size_rto',
|
||||
1: 'application/config/map_image_size_rls' }
|
||||
0: 'application/config/map_image_size_rto',
|
||||
1: 'application/config/map_image_size_rls' }
|
||||
|
||||
|
||||
const MAP_RELATIVE_RADIUSES: = {
|
||||
0: 0.39,
|
||||
1: 0.466
|
||||
0: 0.39,
|
||||
1: 0.466
|
||||
}
|
||||
|
||||
|
||||
@@ -53,122 +53,122 @@ var map_mode: int ## Режим карты: 0 - приорите
|
||||
var prev_tiles_dic: Dictionary ##
|
||||
var lnglat: Array ## Текущие координаты.
|
||||
var root_rect: Rect2i
|
||||
|
||||
|
||||
func _ready():
|
||||
lnglat = TEST_DATA['Таганрог']
|
||||
map_tile_state = TASK_STATE.DONE
|
||||
map_request = HTTPRequest.new()
|
||||
add_child(map_request)
|
||||
map_request.request_completed.connect(self._map_request_completed)
|
||||
map_bcs = ProjectSettings.get_setting('application/config/map_bcs', Vector3(1.0, 1.0, 1.0))
|
||||
map_server_addr = ProjectSettings.get_setting('application/config/map_server_addr')
|
||||
map_tile_format = ProjectSettings.get_setting('application/config/map_tile_format', '%s/%d/%d/%d.png')
|
||||
var map_image_size = ProjectSettings.get_setting(MAP_MODES[0], Vector2i(512, 512))
|
||||
var map_tile_size = ProjectSettings.get_setting('application/config/map_tile_size', 256)
|
||||
map_image = Image.create(map_image_size.x, map_image_size.y, true, Image.FORMAT_RGB8)
|
||||
map_tile = Rect2i(0, 0, map_tile_size, map_tile_size)
|
||||
signaller.connect('zoom_changed', Callable(self, '_on_zoom_changed'))
|
||||
signaller.connect('map_mode_changed', Callable(self, '_on_map_mode_changed'))
|
||||
log.info('Адрес сервера поставщика карт: \"%s\"' % map_server_addr)
|
||||
log.info('Модуль географической карты готов')
|
||||
lnglat = TEST_DATA['Таганрог']
|
||||
map_tile_state = TASK_STATE.DONE
|
||||
map_request = HTTPRequest.new()
|
||||
add_child(map_request)
|
||||
map_request.request_completed.connect(self._map_request_completed)
|
||||
map_bcs = ProjectSettings.get_setting('application/config/map_bcs', Vector3(1.0, 1.0, 1.0))
|
||||
map_server_addr = ProjectSettings.get_setting('application/config/map_server_addr')
|
||||
map_tile_format = ProjectSettings.get_setting('application/config/map_tile_format', '%s/%d/%d/%d.png')
|
||||
var map_image_size = ProjectSettings.get_setting(MAP_MODES[0], Vector2i(512, 512))
|
||||
var map_tile_size = ProjectSettings.get_setting('application/config/map_tile_size', 256)
|
||||
map_image = Image.create(map_image_size.x, map_image_size.y, true, Image.FORMAT_RGB8)
|
||||
map_tile = Rect2i(0, 0, map_tile_size, map_tile_size)
|
||||
signaller.connect('zoom_changed', Callable(self, '_on_zoom_changed'))
|
||||
signaller.connect('map_mode_changed', Callable(self, '_on_map_mode_changed'))
|
||||
log.info('Адрес сервера поставщика карт: \"%s\"' % map_server_addr)
|
||||
log.info('Модуль географической карты готов')
|
||||
|
||||
|
||||
|
||||
func _on_map_mode_changed(mode: int) -> void:
|
||||
var map_image_size = ProjectSettings.get_setting(MAP_MODES[mode])
|
||||
material.set('shader_parameter/radius', MAP_RELATIVE_RADIUSES[mode])
|
||||
map_image.fill(Color(0, 0, 0, 0))
|
||||
map_image.resize(map_image_size.x, map_image_size.y)
|
||||
map_tile_state = TASK_STATE.DONE
|
||||
map_mode = mode
|
||||
var tile: = mercator.create_tile(lnglat[0], lnglat[1], map_zoom)
|
||||
map_tile_stack.clear()
|
||||
map_tile_stack.append(tile)
|
||||
prev_tiles_dic.clear()
|
||||
var map_image_size = ProjectSettings.get_setting(MAP_MODES[mode])
|
||||
material.set('shader_parameter/radius', MAP_RELATIVE_RADIUSES[mode])
|
||||
map_image.fill(Color(0, 0, 0, 0))
|
||||
map_image.resize(map_image_size.x, map_image_size.y)
|
||||
map_tile_state = TASK_STATE.DONE
|
||||
map_mode = mode
|
||||
var tile: = mercator.create_tile(lnglat[0], lnglat[1], map_zoom)
|
||||
map_tile_stack.clear()
|
||||
map_tile_stack.append(tile)
|
||||
prev_tiles_dic.clear()
|
||||
|
||||
|
||||
func mark_image_center(image: Image, color: Color = Color.RED):
|
||||
var c = image.get_size() / 2
|
||||
map_image.set_pixel(c.x - 1, c.y - 1, color)
|
||||
map_image.set_pixel(c.x - 1, c.y, color)
|
||||
map_image.set_pixel(c.x, c.y - 1, color)
|
||||
map_image.set_pixel(c.x, c.y, color)
|
||||
var c = image.get_size() / 2
|
||||
map_image.set_pixel(c.x - 1, c.y - 1, color)
|
||||
map_image.set_pixel(c.x - 1, c.y, color)
|
||||
map_image.set_pixel(c.x, c.y - 1, color)
|
||||
map_image.set_pixel(c.x, c.y, color)
|
||||
|
||||
|
||||
func _on_zoom_changed(zoom: int):
|
||||
if map_tile_stack.size() != 0:
|
||||
return
|
||||
map_zoom = zoom
|
||||
var tile: = mercator.create_tile(lnglat[0], lnglat[1], zoom)
|
||||
map_tile_stack.clear()
|
||||
map_tile_stack.append(tile)
|
||||
prev_tiles_dic.clear()
|
||||
if map_tile_stack.size() != 0:
|
||||
return
|
||||
map_zoom = zoom
|
||||
var tile: = mercator.create_tile(lnglat[0], lnglat[1], zoom)
|
||||
map_tile_stack.clear()
|
||||
map_tile_stack.append(tile)
|
||||
prev_tiles_dic.clear()
|
||||
|
||||
|
||||
func img_tile_to_map_image(image: Image, dst_pos: Vector2i):
|
||||
image.adjust_bcs(map_bcs.x, map_bcs.y, map_bcs.z)
|
||||
map_image.blit_rect(image, map_tile, dst_pos)
|
||||
image.adjust_bcs(map_bcs.x, map_bcs.y, map_bcs.z)
|
||||
map_image.blit_rect(image, map_tile, dst_pos)
|
||||
|
||||
|
||||
func _process(_delta: float):
|
||||
if (map_tile_state == TASK_STATE.DONE) and map_tile_stack.size():
|
||||
var tile: mercator.Tile = map_tile_stack[-1]
|
||||
var tile_addr: = map_tile_format % [map_server_addr, tile.z, tile.x , tile.y]
|
||||
var rc = map_request.request(tile_addr)
|
||||
if rc == OK:
|
||||
map_tile_state = TASK_STATE.WAIT
|
||||
else:
|
||||
log.error('%s: Невозможно сформировать запрос HTTP' % self)
|
||||
map_tile_state = TASK_STATE.ERROR
|
||||
elif map_tile_state == TASK_STATE.CHECK:
|
||||
var root_tile: = mercator.Tile.new(root_rect.size.x, root_rect.size.y, map_zoom)
|
||||
var neighbors_tiles = mercator.get_perimetr_tiles(root_tile, (map_image.get_size().x / map_tile.size.x) / 2)
|
||||
var neighbors_tiles_dic = {}
|
||||
for tile in neighbors_tiles:
|
||||
neighbors_tiles_dic[[tile.x, tile.y]] = false
|
||||
if neighbors_tiles_dic != prev_tiles_dic:
|
||||
for tile in neighbors_tiles:
|
||||
tile.is_root = false
|
||||
map_tile_stack.push_front(tile)
|
||||
prev_tiles_dic[[tile.x, tile.y]] = false
|
||||
else:
|
||||
if map_tile_stack.size() == 0:
|
||||
signaller.emit_signal('zoom_complete', map_zoom)
|
||||
map_tile_state = TASK_STATE.DONE
|
||||
if (map_tile_state == TASK_STATE.DONE) and map_tile_stack.size():
|
||||
var tile: mercator.Tile = map_tile_stack[-1]
|
||||
var tile_addr: = map_tile_format % [map_server_addr, tile.z, tile.x , tile.y]
|
||||
var rc = map_request.request(tile_addr)
|
||||
if rc == OK:
|
||||
map_tile_state = TASK_STATE.WAIT
|
||||
else:
|
||||
log.error('%s: Невозможно сформировать запрос HTTP' % self)
|
||||
map_tile_state = TASK_STATE.ERROR
|
||||
elif map_tile_state == TASK_STATE.CHECK:
|
||||
var root_tile: = mercator.Tile.new(root_rect.size.x, root_rect.size.y, map_zoom)
|
||||
var neighbors_tiles = mercator.get_perimetr_tiles(root_tile, (map_image.get_size().x / map_tile.size.x) / 2)
|
||||
var neighbors_tiles_dic = {}
|
||||
for tile in neighbors_tiles:
|
||||
neighbors_tiles_dic[[tile.x, tile.y]] = false
|
||||
if neighbors_tiles_dic != prev_tiles_dic:
|
||||
for tile in neighbors_tiles:
|
||||
tile.is_root = false
|
||||
map_tile_stack.push_front(tile)
|
||||
prev_tiles_dic[[tile.x, tile.y]] = false
|
||||
else:
|
||||
if map_tile_stack.size() == 0:
|
||||
signaller.emit_signal('zoom_complete', map_zoom)
|
||||
map_tile_state = TASK_STATE.DONE
|
||||
|
||||
|
||||
func _map_request_completed(result, response_code, headers, data):
|
||||
if result != HTTPRequest.RESULT_SUCCESS:
|
||||
log.error('%s: Запрос не обработан. result: \"%s\", response_code: \"%s\", headers: \"%s\"' % [self, result, response_code, headers])
|
||||
map_tile_state = TASK_STATE.ERROR
|
||||
return
|
||||
if result != HTTPRequest.RESULT_SUCCESS:
|
||||
log.error('%s: Запрос не обработан. result: \"%s\", response_code: \"%s\", headers: \"%s\"' % [self, result, response_code, headers])
|
||||
map_tile_state = TASK_STATE.ERROR
|
||||
return
|
||||
|
||||
var img_tile = Image.new()
|
||||
var error = img_tile.load_png_from_buffer(data)
|
||||
if error != OK:
|
||||
log.error('%s: Полученые данные невозможно использовать для формироания изображения. result: \"%s\", response_code: \"%s\", headers: \"%s\"' % [self, result, response_code, headers])
|
||||
map_tile_state = TASK_STATE.ERROR
|
||||
return
|
||||
var img_tile = Image.new()
|
||||
var error = img_tile.load_png_from_buffer(data)
|
||||
if error != OK:
|
||||
log.error('%s: Полученые данные невозможно использовать для формироания изображения. result: \"%s\", response_code: \"%s\", headers: \"%s\"' % [self, result, response_code, headers])
|
||||
map_tile_state = TASK_STATE.ERROR
|
||||
return
|
||||
|
||||
var tile = map_tile_stack.pop_back()
|
||||
map_tile_state = TASK_STATE.CHECK
|
||||
var tile = map_tile_stack.pop_back()
|
||||
map_tile_state = TASK_STATE.CHECK
|
||||
|
||||
if tile.is_root:
|
||||
# Отображение корневой плитки
|
||||
map_image.fill(Color(0, 0, 0, 0))
|
||||
var bounds: = mercator.bounds(tile)
|
||||
var lng_c = (bounds.east + bounds.west) / 2.0
|
||||
var lat_c = (bounds.north + bounds.south) / 2.0
|
||||
var sx: float = float(map_tile.size.x) / (bounds.east - bounds.west) * (lng_c - tile.lng) + map_tile.size.x / 2.0 # Cмещение в пискселях центра плитки от заданной точки по горизонтали.
|
||||
var sy: float = float(map_tile.size.y) / (bounds.north - bounds.south) * (lat_c - tile.lat) - map_tile.size.y / 2.0 # Cмещение в пискселях центра плитки от заданной точки по вертикали.
|
||||
var dst_pos: Vector2i = Vector2i(int(sx), int(-sy)) + map_tile.size * map_mode
|
||||
img_tile_to_map_image(img_tile, dst_pos)
|
||||
root_rect = Rect2i(dst_pos.x, dst_pos.y, tile.x, tile.y)
|
||||
else:
|
||||
# Отображение соседних плиток
|
||||
var delta: = Vector2i(tile.x - root_rect.size.x, tile.y - root_rect.size.y)
|
||||
var dst_pos: Vector2i = root_rect.position + delta * map_tile.size
|
||||
img_tile_to_map_image(img_tile, dst_pos)
|
||||
mark_image_center(map_image)
|
||||
texture = ImageTexture.create_from_image(map_image)
|
||||
|
||||
if tile.is_root:
|
||||
# Отображение корневой плитки
|
||||
map_image.fill(Color(0, 0, 0, 0))
|
||||
var bounds: = mercator.bounds(tile)
|
||||
var lng_c = (bounds.east + bounds.west) / 2.0
|
||||
var lat_c = (bounds.north + bounds.south) / 2.0
|
||||
var sx: float = float(map_tile.size.x) / (bounds.east - bounds.west) * (lng_c - tile.lng) + map_tile.size.x / 2.0 # Cмещение в пискселях центра плитки от заданной точки по горизонтали.
|
||||
var sy: float = float(map_tile.size.y) / (bounds.north - bounds.south) * (lat_c - tile.lat) - map_tile.size.y / 2.0 # Cмещение в пискселях центра плитки от заданной точки по вертикали.
|
||||
var dst_pos: Vector2i = Vector2i(int(sx), int(-sy)) + map_tile.size * map_mode
|
||||
img_tile_to_map_image(img_tile, dst_pos)
|
||||
root_rect = Rect2i(dst_pos.x, dst_pos.y, tile.x, tile.y)
|
||||
else:
|
||||
# Отображение соседних плиток
|
||||
var delta: = Vector2i(tile.x - root_rect.size.x, tile.y - root_rect.size.y)
|
||||
var dst_pos: Vector2i = root_rect.position + delta * map_tile.size
|
||||
img_tile_to_map_image(img_tile, dst_pos)
|
||||
mark_image_center(map_image)
|
||||
texture = ImageTexture.create_from_image(map_image)
|
||||
|
||||
|
||||
@@ -1,18 +1,82 @@
|
||||
class_name setting extends Panel
|
||||
|
||||
var TableHeader = preload('res://table/header.tscn')
|
||||
var TableLabel = preload('res://table/lable.tscn')
|
||||
var TableTaggle = preload('res://table/taggle.tscn')
|
||||
var TableEdit = preload('res://table/editl.tscn')
|
||||
var TableEmpti = preload('res://table/empti.tscn')
|
||||
|
||||
|
||||
## Вызывается, когда узел впервые попадает в дерево сцены.
|
||||
func _ready() -> void:
|
||||
$lbl_commit.text = 'Текущая версия ПО УАРЭП: \"%s\"' % commit.VCS_HEAD
|
||||
if not OS.get_cmdline_args().has('++ограниченный'):
|
||||
return
|
||||
$Label2.text = 'Текущий режим доступа: ограниченный'
|
||||
for node in $GridContainer.get_children().filter(func(b): return b is Button):
|
||||
node.disabled = true
|
||||
|
||||
|
||||
setting_tab()
|
||||
dop_set_tab()
|
||||
set_tab()
|
||||
$lbl_commit.text = ' \"%s\"' % commit.VCS_HEAD
|
||||
if not OS.get_cmdline_args().has('++ограниченный'):
|
||||
return
|
||||
$Label2.text = 'Текущий режим доступа: ограниченный'
|
||||
for node in $GridContainer.get_children().filter(func(b): return b is Button):
|
||||
node.disabled = true
|
||||
|
||||
|
||||
func _on_external_cu_btn_pressed() -> void:
|
||||
var state = $GridContainer2/external_cu_btn.button_pressed
|
||||
ProjectSettings.set_setting('application/config/external_cu', state)
|
||||
if state:
|
||||
signaller.emit_signal('interfer_off_all')
|
||||
var state = $GridContainer2/external_cu_btn.button_pressed
|
||||
ProjectSettings.set_setting('application/config/external_cu', state)
|
||||
if state:
|
||||
signaller.emit_signal('interfer_off_all')
|
||||
|
||||
|
||||
func setting_tab():
|
||||
var yams: Array = [ HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER ]
|
||||
$table.set_header([TableHeader, TableHeader])
|
||||
$table.set_header_text(['Элемент', ' Показывать '])
|
||||
|
||||
for i in range(15):
|
||||
$table.add_row([TableLabel, TableTaggle])
|
||||
|
||||
$table.set_row_text(0,([' Кнопка «ПД-М4» ']))
|
||||
$table.set_row_text(1,([' Кнопка «ПД-М2» ']))
|
||||
$table.set_row_text(2,([' Кнопка «ОЗП-1» ']))
|
||||
$table.set_row_text(3,([' Кнопка «МЧМ-1» ']))
|
||||
$table.set_row_text(4,([' Кнопка «ОРН-И1» ']))
|
||||
$table.set_row_text(5,([' Кнопка «ОРН-М2» ']))
|
||||
$table.set_row_text(6,([' Кнопка «ЛЧМ-1» ']))
|
||||
$table.set_row_text(7,([' Кнопка «ПД-М4С» ']))
|
||||
$table.set_row_text(8,([' Кнопка «ПД-ЧМ» ']))
|
||||
$table.set_row_text(9,([' Кнопка «СВ-И1» ']))
|
||||
$table.set_row_text(10,([' Кнопка «К1» ']))
|
||||
$table.set_row_text(11,([' Кнопка «СВ-М2» ']))
|
||||
$table.set_row_text(12,([' Кнопка «ОРН» ']))
|
||||
$table.set_row_text(13,([' Кнопка «JTIDS» ']))
|
||||
$table.set_row_text(14,([' Кнопка «КУПД» ']))
|
||||
|
||||
$table.set_columns_min_size([150, 100])
|
||||
$table.set_columns_alignments(yams)
|
||||
|
||||
|
||||
func dop_set_tab():
|
||||
var yams: Array = [ HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER ]
|
||||
$table2.add_row([TableLabel, TableEmpti])
|
||||
$table2.add_row([TableLabel, TableEmpti])
|
||||
$table2.add_row([TableLabel, TableTaggle])
|
||||
$table2.add_row([TableLabel, TableTaggle])
|
||||
|
||||
$table2.set_row_text(0, (['Текущая версия ПО УАРЭП:']))
|
||||
$table2.set_row_text(1, (['Адрес сервера карт:']))
|
||||
$table2.set_row_text(2, (['Внешнее целеуказание.']))
|
||||
$table2.set_row_text(3, (['Кнопка «Подавление».\nОтключить отображение этой кнопки,\nчто бы тип помех применялся сразу.']))
|
||||
|
||||
|
||||
$table2.set_columns_min_size([180, 50])
|
||||
$table2.set_columns_alignments(yams)
|
||||
|
||||
func set_tab():
|
||||
$table3.add_row([TableLabel, TableEmpti])
|
||||
$table3.add_row([TableLabel, TableEmpti])
|
||||
|
||||
$table3.set_row_text(0, ([' Текущий режим доступа: полный ']))
|
||||
$table3.set_row_text(1, ([' Управление элементами в режиме с ограниченным доступом ']))
|
||||
|
||||
$table3.set_columns_min_size([250, 5])
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://bnptm4rlp60dq"]
|
||||
[gd_scene load_steps=4 format=3 uid="uid://bnptm4rlp60dq"]
|
||||
|
||||
[ext_resource type="Script" path="res://scenes/настройки/настройки.gd" id="1_2l3rd"]
|
||||
[ext_resource type="Script" path="res://table/table.gd" id="2_ts42i"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_anjmx"]
|
||||
script/source = "extends LineEdit
|
||||
@@ -16,295 +17,47 @@ func _on_text_changed(new_text: String) -> void:
|
||||
[node name="Настройки" type="Panel"]
|
||||
script = ExtResource("1_2l3rd")
|
||||
|
||||
[node name="GridContainer" type="GridContainer" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 44.0
|
||||
offset_top = 87.0
|
||||
offset_right = 336.0
|
||||
offset_bottom = 193.0
|
||||
[node name="table" type="GridContainer" parent="."]
|
||||
layout_mode = 2
|
||||
offset_left = 32.0
|
||||
offset_top = 96.0
|
||||
offset_right = 241.0
|
||||
offset_bottom = 535.0
|
||||
columns = 2
|
||||
|
||||
[node name="Label" type="Label" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
text = "Элемент"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Label2" type="Label" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
text = "Показывать"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Label4" type="Label" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
text = "Кнопка «ПД-M4»"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="CheckButton" type="CheckButton" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_vertical = 6
|
||||
button_pressed = true
|
||||
|
||||
[node name="Label5" type="Label" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
text = "Кнопка «ПД-M2»"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="CheckButton3" type="CheckButton" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_vertical = 6
|
||||
button_pressed = true
|
||||
|
||||
[node name="Label6" type="Label" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
text = "Кнопка «ОЗП-1»"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="CheckButton5" type="CheckButton" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_vertical = 6
|
||||
button_pressed = true
|
||||
|
||||
[node name="Label7" type="Label" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
text = "Кнопка «МЧМ-1»"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="CheckButton6" type="CheckButton" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_vertical = 6
|
||||
button_pressed = true
|
||||
|
||||
[node name="Label8" type="Label" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
text = "Кнопка «СРН-И1»"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="CheckButton7" type="CheckButton" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_vertical = 6
|
||||
button_pressed = true
|
||||
|
||||
[node name="Label9" type="Label" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
text = "Кнопка «СРН-М2»"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="CheckButton8" type="CheckButton" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_vertical = 6
|
||||
button_pressed = true
|
||||
|
||||
[node name="Label10" type="Label" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
text = "Кнопка «ЛЧМ-1»"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="CheckButton9" type="CheckButton" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_vertical = 6
|
||||
button_pressed = true
|
||||
|
||||
[node name="Label11" type="Label" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
text = "Кнопка «ПД-М4С»"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="CheckButton10" type="CheckButton" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_vertical = 6
|
||||
button_pressed = true
|
||||
|
||||
[node name="Label12" type="Label" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
text = "Кнопка «ПД-ЧМ»"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="CheckButton11" type="CheckButton" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_vertical = 6
|
||||
button_pressed = true
|
||||
|
||||
[node name="Label13" type="Label" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
text = "Кнопка «СВ-И1»"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="CheckButton12" type="CheckButton" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_vertical = 6
|
||||
button_pressed = true
|
||||
|
||||
[node name="Label14" type="Label" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
text = "Кнопка «К1»"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="CheckButton13" type="CheckButton" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_vertical = 6
|
||||
button_pressed = true
|
||||
|
||||
[node name="Label15" type="Label" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
text = "Кнопка «СВ-М2»"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="CheckButton14" type="CheckButton" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_vertical = 6
|
||||
button_pressed = true
|
||||
|
||||
[node name="Label16" type="Label" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
text = "Кнопка «СРН»"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="CheckButton15" type="CheckButton" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_vertical = 6
|
||||
button_pressed = true
|
||||
|
||||
[node name="Label17" type="Label" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
text = "Кнопка «JTIDS»"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="CheckButton16" type="CheckButton" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_vertical = 6
|
||||
button_pressed = true
|
||||
|
||||
[node name="Label18" type="Label" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
text = "Кнопка «КУПД»"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="CheckButton17" type="CheckButton" parent="GridContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_vertical = 6
|
||||
button_pressed = true
|
||||
|
||||
[node name="Label1" type="Label" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 16.0
|
||||
offset_top = 60.0
|
||||
offset_right = 434.0
|
||||
offset_bottom = 82.0
|
||||
text = "Управление элементами в режиме с ограниченным доступом"
|
||||
|
||||
[node name="Label2" type="Label" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 16.0
|
||||
offset_top = 20.0
|
||||
offset_right = 476.0
|
||||
offset_bottom = 50.0
|
||||
text = "Текущий режим доступа: полный"
|
||||
vertical_alignment = 1
|
||||
script = ExtResource("2_ts42i")
|
||||
|
||||
[node name="edt_mapaddr" type="LineEdit" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 660.0
|
||||
offset_top = 80.0
|
||||
offset_right = 1032.0
|
||||
offset_bottom = 110.0
|
||||
layout_mode = 2
|
||||
offset_left = 560.0
|
||||
offset_top = 144.0
|
||||
offset_right = 896.0
|
||||
offset_bottom = 171.0
|
||||
theme_override_colors/font_color = Color(1, 0.596078, 0.4, 1)
|
||||
script = SubResource("GDScript_anjmx")
|
||||
|
||||
[node name="Label" type="Label" parent="edt_mapaddr"]
|
||||
layout_mode = 0
|
||||
offset_left = -180.0
|
||||
offset_right = -20.0
|
||||
offset_bottom = 30.0
|
||||
text = "Адрес сервера карт:"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="GridContainer2" type="GridContainer" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 478.0
|
||||
offset_top = 154.0
|
||||
offset_right = 784.0
|
||||
offset_bottom = 260.0
|
||||
columns = 2
|
||||
|
||||
[node name="external_cu_lbl" type="Label" parent="GridContainer2"]
|
||||
layout_mode = 2
|
||||
text = "Внешнее целеуказание."
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="external_cu_btn" type="CheckButton" parent="GridContainer2"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Label19" type="Label" parent="GridContainer2"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
text = "Кнопка «Подавление».
|
||||
Отключить отображение этой кнопки,
|
||||
что бы тип помех применялся сразу."
|
||||
|
||||
[node name="CheckButton18" type="CheckButton" parent="GridContainer2"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 6
|
||||
size_flags_vertical = 6
|
||||
button_pressed = true
|
||||
|
||||
[node name="lbl_commit" type="Label" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 480.0
|
||||
offset_top = 20.0
|
||||
offset_right = 1040.0
|
||||
offset_bottom = 50.0
|
||||
text = "Текущая версия ПО УАРЭП:"
|
||||
offset_left = 560.0
|
||||
offset_top = 112.0
|
||||
offset_right = 1120.0
|
||||
offset_bottom = 142.0
|
||||
theme_override_colors/font_color = Color(1, 0.596078, 0.4, 1)
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="table2" type="GridContainer" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 296.0
|
||||
offset_top = 120.0
|
||||
offset_right = 880.0
|
||||
offset_bottom = 408.0
|
||||
script = ExtResource("2_ts42i")
|
||||
|
||||
[node name="table3" type="GridContainer" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 24.0
|
||||
offset_top = 24.0
|
||||
offset_right = 440.0
|
||||
offset_bottom = 80.0
|
||||
script = ExtResource("2_ts42i")
|
||||
|
||||
[connection signal="text_changed" from="edt_mapaddr" to="edt_mapaddr" method="_on_text_changed"]
|
||||
[connection signal="pressed" from="GridContainer2/external_cu_btn" to="." method="_on_external_cu_btn_pressed"]
|
||||
|
||||
@@ -24,253 +24,253 @@ var posy: int = 70 ## Позиция элементов по y.
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
call_deferred('init_boards')
|
||||
call_deferred('init_boards')
|
||||
|
||||
|
||||
## Инициализация основных элементов экрана ЭМС.
|
||||
func init_boards():
|
||||
# Выставление позиций элементов ЭМС на экране
|
||||
$scrollin.set_position(Vector2(posx,posy))
|
||||
$scrollout.set_position(Vector2(posx+650,posy))
|
||||
$scrl_in_set.set_position(Vector2(posx,posy + 700))
|
||||
$scrl_out_set.set_position(Vector2(posx+650,posy + 700))
|
||||
$lbl_online.set_position(Vector2(posx,posy-60))
|
||||
$btn_flash_read.set_position(Vector2(posx,posy + 900))
|
||||
$btn_flash_write.set_position(Vector2(posx,posy+ 935))
|
||||
$btn_connect.set_position(Vector2(posx+590,posy-25))
|
||||
$btn_disconnect.set_position(Vector2(posx+587,posy + 675))
|
||||
# Выставление позиций элементов ЭМС на экране
|
||||
$scrollin.set_position(Vector2(posx,posy))
|
||||
$scrollout.set_position(Vector2(posx+650,posy))
|
||||
$scrl_in_set.set_position(Vector2(posx,posy + 700))
|
||||
$scrl_out_set.set_position(Vector2(posx+650,posy + 700))
|
||||
$lbl_online.set_position(Vector2(posx,posy-60))
|
||||
$btn_flash_read.set_position(Vector2(posx,posy + 900))
|
||||
$btn_flash_write.set_position(Vector2(posx,posy+ 935))
|
||||
$btn_connect.set_position(Vector2(posx+590,posy-25))
|
||||
$btn_disconnect.set_position(Vector2(posx+587,posy + 675))
|
||||
|
||||
g_boards['КЭМС'] = yemsboards.EmsBoard.new('КЭМС', 0x130, yemsconsts.INPUT_ROWS, yemsconsts.OUTPUT_ROWS)
|
||||
g_boards['П5-28'] = yemsboards.EmsBoard.new('П5-28', 0x140, yemsconsts.INPUT_ROWS1, yemsconsts.OUTPUT_ROWS1)
|
||||
init_tbl_in()
|
||||
$scrollin/tbl_in.pin_header($scrollin, self)
|
||||
init_tbl_out()
|
||||
$scrollout/tbl_out.pin_header($scrollout, self)
|
||||
$scrl_in_set/tbl_in_set.pin_header($scrl_in_set, self)
|
||||
$scrl_out_set/tbl_out_set.pin_header($scrl_out_set, self)
|
||||
init_tbl_files()
|
||||
$scrl_files/tbl_files.pin_header($scrl_files, self)
|
||||
$btn_connect.connect('pressed', Callable(self, 'on_btn_connect'))
|
||||
$btn_disconnect.connect('pressed', Callable(self, 'on_btn_disconnect'))
|
||||
$btn_flash_read.button_connect('pressed', Callable(self, 'on_btn_flash_read').bind($btn_flash_read))
|
||||
$btn_flash_write.button_connect('pressed', Callable(self, 'on_btn_flash_write').bind($btn_flash_write))
|
||||
g_boards['КЭМС'] = yemsboards.EmsBoard.new('КЭМС', 0x130, yemsconsts.INPUT_ROWS, yemsconsts.OUTPUT_ROWS)
|
||||
g_boards['П5-28'] = yemsboards.EmsBoard.new('П5-28', 0x140, yemsconsts.INPUT_ROWS1, yemsconsts.OUTPUT_ROWS1)
|
||||
init_tbl_in()
|
||||
$scrollin/tbl_in.pin_header($scrollin, self)
|
||||
init_tbl_out()
|
||||
$scrollout/tbl_out.pin_header($scrollout, self)
|
||||
$scrl_in_set/tbl_in_set.pin_header($scrl_in_set, self)
|
||||
$scrl_out_set/tbl_out_set.pin_header($scrl_out_set, self)
|
||||
init_tbl_files()
|
||||
$scrl_files/tbl_files.pin_header($scrl_files, self)
|
||||
$btn_connect.connect('pressed', Callable(self, 'on_btn_connect'))
|
||||
$btn_disconnect.connect('pressed', Callable(self, 'on_btn_disconnect'))
|
||||
$btn_flash_read.button_connect('pressed', Callable(self, 'on_btn_flash_read').bind($btn_flash_read))
|
||||
$btn_flash_write.button_connect('pressed', Callable(self, 'on_btn_flash_write').bind($btn_flash_write))
|
||||
|
||||
|
||||
## Обработчик нажатия кнопки disconnect.
|
||||
func on_btn_disconnect():
|
||||
var selected_rows_in: Array = []
|
||||
var selected_rows_out: Array = []
|
||||
$scrl_in_set/tbl_in_set.get_selected_rows(selected_rows_in)
|
||||
$scrl_out_set/tbl_out_set.get_selected_rows(selected_rows_out)
|
||||
if len(selected_rows_in):
|
||||
on_disconnect($scrl_in_set/tbl_in_set, selected_rows_in, 'вход')
|
||||
elif len(selected_rows_out):
|
||||
on_disconnect($scrl_out_set/tbl_out_set, selected_rows_out, 'выход')
|
||||
var selected_rows_in: Array = []
|
||||
var selected_rows_out: Array = []
|
||||
$scrl_in_set/tbl_in_set.get_selected_rows(selected_rows_in)
|
||||
$scrl_out_set/tbl_out_set.get_selected_rows(selected_rows_out)
|
||||
if len(selected_rows_in):
|
||||
on_disconnect($scrl_in_set/tbl_in_set, selected_rows_in, 'вход')
|
||||
elif len(selected_rows_out):
|
||||
on_disconnect($scrl_out_set/tbl_out_set, selected_rows_out, 'выход')
|
||||
|
||||
|
||||
## Разрывает связь входа и выхода, [param tbl] - таблица, [param selected_rows] - выбранные строки.
|
||||
## [param type_dev] - тип, 'вход' или 'выход'.
|
||||
func on_disconnect(tbl, selected_rows, type_dev: String):
|
||||
var dev = tbl.get_node_user_data(0, 0)
|
||||
var user_data: Array = tbl.get_node_user_data(0, selected_rows[0])
|
||||
var con_dev = user_data[0]
|
||||
var connector: String = con_dev.connector
|
||||
dev.connect_devs.erase(con_dev.connector)
|
||||
con_dev.connect_devs.erase(dev.connector)
|
||||
if type_dev == 'вход':
|
||||
set_in_dev(dev)
|
||||
set_out_dev(con_dev)
|
||||
elif type_dev == 'выход':
|
||||
set_in_dev(con_dev)
|
||||
set_out_dev(dev)
|
||||
var dev = tbl.get_node_user_data(0, 0)
|
||||
var user_data: Array = tbl.get_node_user_data(0, selected_rows[0])
|
||||
var con_dev = user_data[0]
|
||||
var connector: String = con_dev.connector
|
||||
dev.connect_devs.erase(con_dev.connector)
|
||||
con_dev.connect_devs.erase(dev.connector)
|
||||
if type_dev == 'вход':
|
||||
set_in_dev(dev)
|
||||
set_out_dev(con_dev)
|
||||
elif type_dev == 'выход':
|
||||
set_in_dev(con_dev)
|
||||
set_out_dev(dev)
|
||||
|
||||
|
||||
## Обработчик нажатия кнопки "Прочитать".
|
||||
func on_btn_flash_read(btn):
|
||||
await get_tree().create_timer(0.1).timeout
|
||||
btn.pressed = false
|
||||
await get_tree().create_timer(0.1).timeout
|
||||
btn.pressed = false
|
||||
|
||||
|
||||
## Обработчик нажатия кнопки "Записать".
|
||||
func on_btn_flash_write(btn):
|
||||
await get_tree().create_timer(0.1).timeout
|
||||
btn.pressed = false
|
||||
await get_tree().create_timer(0.1).timeout
|
||||
btn.pressed = false
|
||||
|
||||
|
||||
## Инициализация таблицы с файлами настроек ЭМС.
|
||||
func init_tbl_files():
|
||||
$scrl_files/tbl_files.set_header([TableHeader, TableHeader, TableHeader])
|
||||
$scrl_files/tbl_files.set_header_text(['Имя файла', 'Дата изменения', 'Размер'])
|
||||
$scrl_files/tbl_files.set_columns_min_size([200, 120, 70])
|
||||
$scrl_files/tbl_files.set_header([TableHeader, TableHeader, TableHeader])
|
||||
$scrl_files/tbl_files.set_header_text(['Имя файла', 'Дата изменения', 'Размер'])
|
||||
$scrl_files/tbl_files.set_columns_min_size([200, 120, 70])
|
||||
|
||||
|
||||
## Инициализация таблиц входов.
|
||||
func init_tbl_in():
|
||||
# Инициализация основной таблицы входов, в ней отображается информация о параметрах и состоянии
|
||||
var header_type: Array = [TableHeader, TableHeader, CellFront, CellFrontRear, TableHeader]
|
||||
var header_text: Array = ['Входы', 'Соединитель', 'мкс', 'мкс', 'Состояние']
|
||||
var row_type: Array = [CellLineEdit, CellLineEdit, CellLineEdit, CellLineEdit, CellState]
|
||||
var yams_alligment_in: Array = [ HORIZONTAL_ALIGNMENT_LEFT, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER]
|
||||
var column_size: Array = [250, 100, 70, 70, 50]
|
||||
$scrollin/tbl_in.set_header(header_type)
|
||||
$scrollin/tbl_in.set_header_text(header_text)
|
||||
for board in g_boards:
|
||||
for item in g_boards[board].in_tbl:
|
||||
$scrollin/tbl_in.add_row(row_type)
|
||||
var row_index : int = $scrollin/tbl_in.get_rows_count() - 1
|
||||
var params : Array = item[1]
|
||||
var in_dev: yemsdevs.InDev = yemsdevs.InDev.new(item[0], params, row_index)
|
||||
in_dev.board = board
|
||||
for i in range(len(row_type)):
|
||||
if i < len(params):
|
||||
var node = $scrollin/tbl_in.get_node2(i, row_index)
|
||||
node.text = params[i]
|
||||
node.editable = false
|
||||
$scrollin/tbl_in.set_node_user_data(i, row_index, [in_dev, board])
|
||||
$scrollin/tbl_in.set_columns_alignments(yams_alligment_in)
|
||||
$scrollin/tbl_in.set_columns_min_size(column_size)
|
||||
$scrollin/tbl_in.connect('row_pressed', Callable(self, 'on_row_pressed_in'))
|
||||
$scrollin/tbl_in.connect('selected_changed', Callable(self, 'on_selected_changed_in'))
|
||||
# Инициализация основной таблицы входов, в ней отображается информация о параметрах и состоянии
|
||||
var header_type: Array = [TableHeader, TableHeader, CellFront, CellFrontRear, TableHeader]
|
||||
var header_text: Array = ['Входы', 'Соединитель', 'мкс', 'мкс', 'Состояние']
|
||||
var row_type: Array = [CellLineEdit, CellLineEdit, CellLineEdit, CellLineEdit, CellState]
|
||||
var yams_alligment_in: Array = [ HORIZONTAL_ALIGNMENT_LEFT, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER]
|
||||
var column_size: Array = [250, 100, 70, 70, 50]
|
||||
$scrollin/tbl_in.set_header(header_type)
|
||||
$scrollin/tbl_in.set_header_text(header_text)
|
||||
for board in g_boards:
|
||||
for item in g_boards[board].in_tbl:
|
||||
$scrollin/tbl_in.add_row(row_type)
|
||||
var row_index : int = $scrollin/tbl_in.get_rows_count() - 1
|
||||
var params : Array = item[1]
|
||||
var in_dev: yemsdevs.InDev = yemsdevs.InDev.new(item[0], params, row_index)
|
||||
in_dev.board = board
|
||||
for i in range(len(row_type)):
|
||||
if i < len(params):
|
||||
var node = $scrollin/tbl_in.get_node2(i, row_index)
|
||||
node.text = params[i]
|
||||
node.editable = false
|
||||
$scrollin/tbl_in.set_node_user_data(i, row_index, [in_dev, board])
|
||||
$scrollin/tbl_in.set_columns_alignments(yams_alligment_in)
|
||||
$scrollin/tbl_in.set_columns_min_size(column_size)
|
||||
$scrollin/tbl_in.connect('row_pressed', Callable(self, 'on_row_pressed_in'))
|
||||
$scrollin/tbl_in.connect('selected_changed', Callable(self, 'on_selected_changed_in'))
|
||||
|
||||
# Инициализация таблицы изменения параметров входа и списка выходов связанных с ним
|
||||
header_text[0] = 'Вход'
|
||||
$scrl_in_set/tbl_in_set.set_header(header_type)
|
||||
$scrl_in_set/tbl_in_set.set_header_text(header_text)
|
||||
$scrl_in_set/tbl_in_set.set_columns_alignments(yams_alligment_in)
|
||||
$scrl_in_set/tbl_in_set.set_columns_min_size(column_size)
|
||||
$scrl_in_set/tbl_in_set.connect('row_pressed', Callable(self, 'on_row_pressed_si'))
|
||||
$scrl_in_set/tbl_in_set.connect('selected_changed', Callable(self, 'on_selected_changed_si'))
|
||||
# Инициализация таблицы изменения параметров входа и списка выходов связанных с ним
|
||||
header_text[0] = 'Вход'
|
||||
$scrl_in_set/tbl_in_set.set_header(header_type)
|
||||
$scrl_in_set/tbl_in_set.set_header_text(header_text)
|
||||
$scrl_in_set/tbl_in_set.set_columns_alignments(yams_alligment_in)
|
||||
$scrl_in_set/tbl_in_set.set_columns_min_size(column_size)
|
||||
$scrl_in_set/tbl_in_set.connect('row_pressed', Callable(self, 'on_row_pressed_si'))
|
||||
$scrl_in_set/tbl_in_set.connect('selected_changed', Callable(self, 'on_selected_changed_si'))
|
||||
|
||||
|
||||
## Обработчик редактирования Entry в таблице параметров входов/выходов.
|
||||
func on_edit_entry(text : String, entry):
|
||||
print_debug(text, entry)
|
||||
print_debug(text, entry)
|
||||
|
||||
|
||||
## Обработчик выбора строки в таблице входов.
|
||||
func on_selected_changed_in(i_row: int):
|
||||
var selecter_rows: Array = []
|
||||
$scrollin/tbl_in.get_selected_rows(selecter_rows)
|
||||
var user_data = $scrollin/tbl_in.get_node_user_data(0, i_row)
|
||||
var dev = user_data[0]
|
||||
set_in_dev(dev)
|
||||
var selecter_rows: Array = []
|
||||
$scrollin/tbl_in.get_selected_rows(selecter_rows)
|
||||
var user_data = $scrollin/tbl_in.get_node_user_data(0, i_row)
|
||||
var dev = user_data[0]
|
||||
set_in_dev(dev)
|
||||
|
||||
|
||||
## Обработчик нажатия на таблицу входов.
|
||||
func on_row_pressed_in(i_row: int):
|
||||
on_row_pressed(i_row, $scrollin/tbl_in)
|
||||
on_selected_changed_in(i_row)
|
||||
on_row_pressed(i_row, $scrollin/tbl_in)
|
||||
on_selected_changed_in(i_row)
|
||||
|
||||
|
||||
## Выбор входного устройства, для отображения в таблице соединений входа и изменения параметров.
|
||||
func set_in_dev(dev):
|
||||
var row_type: Array = [CellLineEdit, CellLineEdit, CellLineEdit, CellLineEdit, CellState]
|
||||
set_dev($scrl_in_set/tbl_in_set, dev, row_type, IN_SET_ROW, 'Список соединённых выходов :', [250, 100, 70, 70, 70])
|
||||
var row_type: Array = [CellLineEdit, CellLineEdit, CellLineEdit, CellLineEdit, CellState]
|
||||
set_dev($scrl_in_set/tbl_in_set, dev, row_type, IN_SET_ROW, 'Список соединённых выходов :', [250, 100, 70, 70, 70])
|
||||
|
||||
|
||||
## Обработчик выбора строки в таблице соединений входа и изменения параметров.
|
||||
func on_selected_changed_si(i_row: int):
|
||||
if i_row < 2:
|
||||
return
|
||||
var out_user_data = $scrl_in_set/tbl_in_set.get_node_user_data(0, i_row)
|
||||
var dev = out_user_data[0]
|
||||
var connector = dev.connector
|
||||
for i in range($scrollout/tbl_out.get_rows_count()):
|
||||
var node = $scrollout/tbl_out.get_node2(1, i)
|
||||
if connector == node.text:
|
||||
on_row_pressed_out(i)
|
||||
if i_row < 2:
|
||||
return
|
||||
var out_user_data = $scrl_in_set/tbl_in_set.get_node_user_data(0, i_row)
|
||||
var dev = out_user_data[0]
|
||||
var connector = dev.connector
|
||||
for i in range($scrollout/tbl_out.get_rows_count()):
|
||||
var node = $scrollout/tbl_out.get_node2(1, i)
|
||||
if connector == node.text:
|
||||
on_row_pressed_out(i)
|
||||
|
||||
|
||||
## Обработчик нажатия на таблицу соединений входа и изменения параметров.
|
||||
func on_row_pressed_si(i_row: int):
|
||||
if i_row < 2:
|
||||
return
|
||||
on_row_pressed(i_row, $scrl_in_set/tbl_in_set)
|
||||
on_selected_changed_si(i_row)
|
||||
if i_row < 2:
|
||||
return
|
||||
on_row_pressed(i_row, $scrl_in_set/tbl_in_set)
|
||||
on_selected_changed_si(i_row)
|
||||
|
||||
|
||||
## Инициализация таблиц выходов.
|
||||
func init_tbl_out():
|
||||
# Инициализация основной таблицы выходов, в ней отображается информация о параметрах и состоянии
|
||||
var header_text = ['Выходы', 'Соединитель', 'мкс', 'мкс', 'Состояние', 'Режим']
|
||||
var yams_alligment_out: Array = [ HORIZONTAL_ALIGNMENT_LEFT, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER]
|
||||
$scrollout/tbl_out.set_header([TableHeader, TableHeader, CellFront, CellFrontRear, TableHeader, TableHeader])
|
||||
$scrollout/tbl_out.set_header_text(header_text)
|
||||
for board in g_boards:
|
||||
for item in g_boards[board].out_tbl:
|
||||
$scrollout/tbl_out.add_row([CellLineEdit, CellLineEdit, CellLineEdit, CellLineEdit, CellState, CellLineEdit])
|
||||
var row_index : int = $scrollout/tbl_out.get_rows_count() - 1
|
||||
var params : Array = item[1]
|
||||
var out_dev = yemsdevs.OutDev.new(item[0], params, row_index)
|
||||
out_dev.board = board
|
||||
for i in range(len(header_text)):
|
||||
var cell = $scrollout/tbl_out.get_node2(i, row_index)
|
||||
if i < len(params):
|
||||
cell.text = params[i]
|
||||
cell.editable = false
|
||||
$scrollout/tbl_out.set_node_user_data(i, row_index, [out_dev, board])
|
||||
if i in COLUMN_OPTS_BTN:
|
||||
cell.text = out_dev.mode
|
||||
$scrollout/tbl_out.set_columns_min_size([250, 100, 70, 70, 70, 100])
|
||||
$scrollout/tbl_out.set_columns_alignments(yams_alligment_out)
|
||||
$scrollout/tbl_out.connect('row_pressed', Callable(self, 'on_row_pressed_out'))
|
||||
$scrollout/tbl_out.connect('selected_changed', Callable(self, 'on_selected_changed_out'))
|
||||
# Инициализация основной таблицы выходов, в ней отображается информация о параметрах и состоянии
|
||||
var header_text = ['Выходы', 'Соединитель', 'мкс', 'мкс', 'Состояние', 'Режим']
|
||||
var yams_alligment_out: Array = [ HORIZONTAL_ALIGNMENT_LEFT, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER]
|
||||
$scrollout/tbl_out.set_header([TableHeader, TableHeader, CellFront, CellFrontRear, TableHeader, TableHeader])
|
||||
$scrollout/tbl_out.set_header_text(header_text)
|
||||
for board in g_boards:
|
||||
for item in g_boards[board].out_tbl:
|
||||
$scrollout/tbl_out.add_row([CellLineEdit, CellLineEdit, CellLineEdit, CellLineEdit, CellState, CellLineEdit])
|
||||
var row_index : int = $scrollout/tbl_out.get_rows_count() - 1
|
||||
var params : Array = item[1]
|
||||
var out_dev = yemsdevs.OutDev.new(item[0], params, row_index)
|
||||
out_dev.board = board
|
||||
for i in range(len(header_text)):
|
||||
var cell = $scrollout/tbl_out.get_node2(i, row_index)
|
||||
if i < len(params):
|
||||
cell.text = params[i]
|
||||
cell.editable = false
|
||||
$scrollout/tbl_out.set_node_user_data(i, row_index, [out_dev, board])
|
||||
if i in COLUMN_OPTS_BTN:
|
||||
cell.text = out_dev.mode
|
||||
$scrollout/tbl_out.set_columns_min_size([250, 100, 70, 70, 70, 100])
|
||||
$scrollout/tbl_out.set_columns_alignments(yams_alligment_out)
|
||||
$scrollout/tbl_out.connect('row_pressed', Callable(self, 'on_row_pressed_out'))
|
||||
$scrollout/tbl_out.connect('selected_changed', Callable(self, 'on_selected_changed_out'))
|
||||
|
||||
# Инициализация таблицы изменения параметров выхода и списка входов связанных с ним
|
||||
header_text[0] = 'Выход'
|
||||
$scrl_out_set/tbl_out_set.set_header([TableHeader, TableHeader, CellFront, CellFrontRear, TableHeader, TableHeader])
|
||||
$scrl_out_set/tbl_out_set.set_header_text(header_text)
|
||||
$scrl_out_set/tbl_out_set.set_columns_min_size([250, 100, 70, 70, 70, 100])
|
||||
$scrl_out_set/tbl_out_set.connect('row_pressed', Callable(self, 'on_row_pressed_so'))
|
||||
$scrl_out_set/tbl_out_set.connect('selected_changed', Callable(self, 'on_selected_changed_so'))
|
||||
# Инициализация таблицы изменения параметров выхода и списка входов связанных с ним
|
||||
header_text[0] = 'Выход'
|
||||
$scrl_out_set/tbl_out_set.set_header([TableHeader, TableHeader, CellFront, CellFrontRear, TableHeader, TableHeader])
|
||||
$scrl_out_set/tbl_out_set.set_header_text(header_text)
|
||||
$scrl_out_set/tbl_out_set.set_columns_min_size([250, 100, 70, 70, 70, 100])
|
||||
$scrl_out_set/tbl_out_set.connect('row_pressed', Callable(self, 'on_row_pressed_so'))
|
||||
$scrl_out_set/tbl_out_set.connect('selected_changed', Callable(self, 'on_selected_changed_so'))
|
||||
|
||||
|
||||
## Обработчик выбора строки в таблице соединений выхода и изменения параметров.
|
||||
func on_selected_changed_so(i_row: int):
|
||||
if i_row < 2:
|
||||
return
|
||||
var in_user_data = $scrl_out_set/tbl_out_set.get_node_user_data(0, i_row)
|
||||
var dev = in_user_data[0]
|
||||
var connector = dev.connector
|
||||
for i in range($scrollin/tbl_in.get_rows_count()):
|
||||
var node = $scrollin/tbl_in.get_node2(1, i)
|
||||
if connector == node.text:
|
||||
on_row_pressed_in(i)
|
||||
if i_row < 2:
|
||||
return
|
||||
var in_user_data = $scrl_out_set/tbl_out_set.get_node_user_data(0, i_row)
|
||||
var dev = in_user_data[0]
|
||||
var connector = dev.connector
|
||||
for i in range($scrollin/tbl_in.get_rows_count()):
|
||||
var node = $scrollin/tbl_in.get_node2(1, i)
|
||||
if connector == node.text:
|
||||
on_row_pressed_in(i)
|
||||
|
||||
|
||||
## Обработчик нажатия на таблицу соединений выхода и изменения параметров.
|
||||
func on_row_pressed_so(i_row: int):
|
||||
if i_row < 2:
|
||||
return
|
||||
on_row_pressed(i_row, $scrl_out_set/tbl_out_set)
|
||||
on_selected_changed_so(i_row)
|
||||
if i_row < 2:
|
||||
return
|
||||
on_row_pressed(i_row, $scrl_out_set/tbl_out_set)
|
||||
on_selected_changed_so(i_row)
|
||||
|
||||
|
||||
## Обработчик выбора строки в таблице выходов.
|
||||
func on_selected_changed_out(i_row: int):
|
||||
var selecter_rows: Array = []
|
||||
$scrollout/tbl_out.get_selected_rows(selecter_rows)
|
||||
var user_data = $scrollout/tbl_out.get_node_user_data(0, i_row)
|
||||
var dev = user_data[0]
|
||||
set_out_dev(dev)
|
||||
var selecter_rows: Array = []
|
||||
$scrollout/tbl_out.get_selected_rows(selecter_rows)
|
||||
var user_data = $scrollout/tbl_out.get_node_user_data(0, i_row)
|
||||
var dev = user_data[0]
|
||||
set_out_dev(dev)
|
||||
|
||||
|
||||
## Обработчик выбора строки в таблице выходов.
|
||||
func on_row_pressed_out(i_row: int):
|
||||
on_row_pressed(i_row, $scrollout/tbl_out)
|
||||
on_selected_changed_out(i_row)
|
||||
on_row_pressed(i_row, $scrollout/tbl_out)
|
||||
on_selected_changed_out(i_row)
|
||||
|
||||
|
||||
## Выбор выходного устройства, для отображения в таблице соединений выхода и изменения параметров.
|
||||
func set_out_dev(dev):
|
||||
var row_type: Array = [CellLineEdit, CellLineEdit, CellLineEdit, CellLineEdit, CellState, CellOptBtn]
|
||||
set_dev($scrl_out_set/tbl_out_set, dev, row_type, OUT_SET_ROW, 'Список соединённых входов :', [250, 100, 70, 70, 70, 100])
|
||||
var mode = $scrl_out_set/tbl_out_set.get_node2(5, 0)
|
||||
for opt in OUT_MODE:
|
||||
mode.add_item(opt)
|
||||
var mode_index: int = OUT_MODE.find(dev.mode)
|
||||
if mode_index != -1:
|
||||
mode.select(mode_index)
|
||||
var row_type: Array = [CellLineEdit, CellLineEdit, CellLineEdit, CellLineEdit, CellState, CellOptBtn]
|
||||
set_dev($scrl_out_set/tbl_out_set, dev, row_type, OUT_SET_ROW, 'Список соединённых входов :', [250, 100, 70, 70, 70, 100])
|
||||
var mode = $scrl_out_set/tbl_out_set.get_node2(5, 0)
|
||||
for opt in OUT_MODE:
|
||||
mode.add_item(opt)
|
||||
var mode_index: int = OUT_MODE.find(dev.mode)
|
||||
if mode_index != -1:
|
||||
mode.select(mode_index)
|
||||
|
||||
|
||||
## Выбор входного или выходного устройства.[br]
|
||||
@@ -280,53 +280,53 @@ func set_out_dev(dev):
|
||||
## [param row_type_conn] - массив с пустыми LineEdit,[br]
|
||||
## [param lbl_text] - текст отображаемый во 2 строке: пример: ('Список соединённых входов :').[br]
|
||||
func set_dev(tbl, dev, row_type, row_type_conn, lbl_text, row_size):
|
||||
tbl.clear_rows()
|
||||
tbl.add_row(row_type)
|
||||
tbl.set_columns_min_size(row_size)
|
||||
var le_name: LineEdit = tbl.get_node2(0, 0)
|
||||
le_name.editable = false
|
||||
le_name.text = dev.dev_name
|
||||
var connector: LineEdit = tbl.get_node2(1, 0)
|
||||
connector.editable = false
|
||||
connector.text = dev.connector
|
||||
var delay: LineEdit = tbl.get_node2(2, 0)
|
||||
delay.text = '%4.2f'%dev.delay
|
||||
var offset: LineEdit = tbl.get_node2(3, 0)
|
||||
offset.text = '%4.2f'%dev.offset
|
||||
var state = tbl.get_node2(4, 0)
|
||||
state.set_frame(dev.state)
|
||||
tbl.add_row(row_type_conn)
|
||||
var lbl: LineEdit = tbl.get_node2(0, 1)
|
||||
lbl.text = lbl_text
|
||||
for i in len(row_type_conn):
|
||||
var le: LineEdit = tbl.get_node2(i, 1)
|
||||
tbl.set_node_user_data(i, 0, dev)
|
||||
le.editable = false
|
||||
tbl.clear_rows()
|
||||
tbl.add_row(row_type)
|
||||
tbl.set_columns_min_size(row_size)
|
||||
var le_name: LineEdit = tbl.get_node2(0, 0)
|
||||
le_name.editable = false
|
||||
le_name.text = dev.dev_name
|
||||
var connector: LineEdit = tbl.get_node2(1, 0)
|
||||
connector.editable = false
|
||||
connector.text = dev.connector
|
||||
var delay: LineEdit = tbl.get_node2(2, 0)
|
||||
delay.text = '%4.2f'%dev.delay
|
||||
var offset: LineEdit = tbl.get_node2(3, 0)
|
||||
offset.text = '%4.2f'%dev.offset
|
||||
var state = tbl.get_node2(4, 0)
|
||||
state.set_frame(dev.state)
|
||||
tbl.add_row(row_type_conn)
|
||||
var lbl: LineEdit = tbl.get_node2(0, 1)
|
||||
lbl.text = lbl_text
|
||||
for i in len(row_type_conn):
|
||||
var le: LineEdit = tbl.get_node2(i, 1)
|
||||
tbl.set_node_user_data(i, 0, dev)
|
||||
le.editable = false
|
||||
|
||||
for i in dev.connect_devs:
|
||||
var dev_con = dev.connect_devs[i][0]
|
||||
tbl.add_row(row_type_conn)
|
||||
var node_index: Array = [0, tbl.get_rows_count() -1]
|
||||
var le_name_out: LineEdit = tbl.get_node2(node_index[0], node_index[1])
|
||||
disable_edit(tbl, len(row_type_conn), node_index[1])
|
||||
le_name_out.text = dev_con.dev_name
|
||||
tbl.set_node_user_data(node_index[0], node_index[1], dev.connect_devs[i])
|
||||
tbl.connect_columns(self, 'text_submitted', 'on_edit_entry', TABLE_ENTRY_COLUMNS, [])
|
||||
for i in dev.connect_devs:
|
||||
var dev_con = dev.connect_devs[i][0]
|
||||
tbl.add_row(row_type_conn)
|
||||
var node_index: Array = [0, tbl.get_rows_count() -1]
|
||||
var le_name_out: LineEdit = tbl.get_node2(node_index[0], node_index[1])
|
||||
disable_edit(tbl, len(row_type_conn), node_index[1])
|
||||
le_name_out.text = dev_con.dev_name
|
||||
tbl.set_node_user_data(node_index[0], node_index[1], dev.connect_devs[i])
|
||||
tbl.connect_columns(self, 'text_submitted', 'on_edit_entry', TABLE_ENTRY_COLUMNS, [])
|
||||
|
||||
|
||||
## Обработчик нажатия кнопки connect.
|
||||
func on_btn_connect():
|
||||
var in_row_index: Array = []
|
||||
var out_row_index: Array = []
|
||||
$scrollin/tbl_in.get_selected_rows(in_row_index)
|
||||
$scrollout/tbl_out.get_selected_rows(out_row_index)
|
||||
if len(in_row_index) and len(out_row_index):
|
||||
var in_user_data = $scrollin/tbl_in.get_node_user_data(0, in_row_index[0])
|
||||
var out_user_data = $scrollout/tbl_out.get_node_user_data(0, out_row_index[0])
|
||||
var in_dev = in_user_data[0]
|
||||
var out_dev = out_user_data[0]
|
||||
add_connection_dev($scrl_out_set/tbl_out_set, in_dev, out_dev, OUT_SET_ROW, in_user_data)
|
||||
add_connection_dev($scrl_in_set/tbl_in_set, out_dev, in_dev, IN_SET_ROW, out_user_data)
|
||||
var in_row_index: Array = []
|
||||
var out_row_index: Array = []
|
||||
$scrollin/tbl_in.get_selected_rows(in_row_index)
|
||||
$scrollout/tbl_out.get_selected_rows(out_row_index)
|
||||
if len(in_row_index) and len(out_row_index):
|
||||
var in_user_data = $scrollin/tbl_in.get_node_user_data(0, in_row_index[0])
|
||||
var out_user_data = $scrollout/tbl_out.get_node_user_data(0, out_row_index[0])
|
||||
var in_dev = in_user_data[0]
|
||||
var out_dev = out_user_data[0]
|
||||
add_connection_dev($scrl_out_set/tbl_out_set, in_dev, out_dev, OUT_SET_ROW, in_user_data)
|
||||
add_connection_dev($scrl_in_set/tbl_in_set, out_dev, in_dev, IN_SET_ROW, out_user_data)
|
||||
|
||||
|
||||
## Образовывает связь между выбранным входом и выходом.[br]
|
||||
@@ -336,14 +336,14 @@ func on_btn_connect():
|
||||
## [param set_row] - массив с пустыми LineEdit,[br]
|
||||
## [param user_data] - пользовательские данные устройства1.[br]
|
||||
func add_connection_dev(tbl, dev1, dev2, set_row, user_data):
|
||||
if not dev1.connector in dev2.connect_devs:
|
||||
tbl.add_row(set_row)
|
||||
var node_index: Array = [0, tbl.get_rows_count() -1]
|
||||
var le_name: LineEdit = tbl.get_node2(node_index[0], node_index[1])
|
||||
le_name.text = dev1.connector
|
||||
disable_edit(tbl, len(set_row), node_index[1])
|
||||
tbl.set_node_user_data(node_index[0], node_index[1], user_data)
|
||||
dev2.connect_devs[dev1.connector] = user_data
|
||||
if not dev1.connector in dev2.connect_devs:
|
||||
tbl.add_row(set_row)
|
||||
var node_index: Array = [0, tbl.get_rows_count() -1]
|
||||
var le_name: LineEdit = tbl.get_node2(node_index[0], node_index[1])
|
||||
le_name.text = dev1.connector
|
||||
disable_edit(tbl, len(set_row), node_index[1])
|
||||
tbl.set_node_user_data(node_index[0], node_index[1], user_data)
|
||||
dev2.connect_devs[dev1.connector] = user_data
|
||||
|
||||
|
||||
## Отключает возможность редактирования LineEdit в таблице.[br]
|
||||
@@ -351,14 +351,14 @@ func add_connection_dev(tbl, dev1, dev2, set_row, user_data):
|
||||
## [param num_col] - номер колонки,[br]
|
||||
## [param i_row] - номер столбца.[br]
|
||||
func disable_edit(tbl, num_col: int, i_row: int):
|
||||
for col in range(num_col):
|
||||
var node: LineEdit = tbl.get_node2(col, i_row)
|
||||
node.editable = false
|
||||
for col in range(num_col):
|
||||
var node: LineEdit = tbl.get_node2(col, i_row)
|
||||
node.editable = false
|
||||
|
||||
|
||||
## Обработчик выбора строки с таблице.
|
||||
func on_row_pressed(i_row: int, tbl):
|
||||
tbl.clear_rows_selected()
|
||||
var is_row_selected = tbl.is_row_selected(i_row)
|
||||
tbl.set_row_selected(i_row, not is_row_selected)
|
||||
tbl.clear_rows_selected()
|
||||
var is_row_selected = tbl.is_row_selected(i_row)
|
||||
tbl.set_row_selected(i_row, not is_row_selected)
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,27 +5,27 @@ const PROTOCOL_TYPES: = {'yau07tx': yau07.YaU07, 'jsontx': capsrpb.CapsRpb, 'udp
|
||||
const TCP_PROTO: = {'5p28': tcp5p28.TCP5P28}
|
||||
|
||||
class Socket extends PacketPeerUDP:
|
||||
func send_to(addr, data):
|
||||
self.set_dest_address(addr[0], addr[1])
|
||||
self.put_packet(data)
|
||||
func send_to(addr, data):
|
||||
self.set_dest_address(addr[0], addr[1])
|
||||
self.put_packet(data)
|
||||
|
||||
|
||||
class SocketTCP extends TCPServer:
|
||||
const RX_TIMEOUT: int = 1000 ## Время сброса счётчика принятия части пакета.
|
||||
var peerstream: = PacketPeerStream.new()
|
||||
var unit_key: Array ## Клюс юнита.
|
||||
var head_len: int = 8 ## Длинна заголовка команды.
|
||||
var len_place: int = 4 ## Номер начального байта с длинной блока данных.
|
||||
var type_len: int = 4 ## Количество байт в размере длинны.
|
||||
var rx_tick: int ## Время приёма последнего пакета.
|
||||
var rx_all: bool = true ## Флаг, что пакет принят полностью.
|
||||
var rx_len: int ## Количество принятых байт.
|
||||
var rx_data: PackedByteArray ## Принятые данные.
|
||||
var data_len: int ## Размер ожидаемых данных.
|
||||
const RX_TIMEOUT: int = 1000 ## Время сброса счётчика принятия части пакета.
|
||||
var peerstream: = PacketPeerStream.new()
|
||||
var unit_key: Array ## Клюс юнита.
|
||||
var head_len: int = 8 ## Длинна заголовка команды.
|
||||
var len_place: int = 4 ## Номер начального байта с длинной блока данных.
|
||||
var type_len: int = 4 ## Количество байт в размере длинны.
|
||||
var rx_tick: int ## Время приёма последнего пакета.
|
||||
var rx_all: bool = true ## Флаг, что пакет принят полностью.
|
||||
var rx_len: int ## Количество принятых байт.
|
||||
var rx_data: PackedByteArray ## Принятые данные.
|
||||
var data_len: int ## Размер ожидаемых данных.
|
||||
|
||||
func send_to(data):
|
||||
var peer = peerstream.get_stream_peer()
|
||||
peer.put_data(data)
|
||||
func send_to(data):
|
||||
var peer = peerstream.get_stream_peer()
|
||||
peer.put_data(data)
|
||||
|
||||
|
||||
var poll_sockets: Array[Socket]
|
||||
@@ -38,129 +38,129 @@ var logger_page: Node
|
||||
|
||||
|
||||
func create_socket(nm) -> Socket:
|
||||
var addr = repsettings.UnitProfiles[nm][1]
|
||||
var port = repsettings.UnitProfiles[nm][2]
|
||||
var broad = repsettings.UnitProfiles[nm][3]
|
||||
var bind = repsettings.UnitProfiles[nm][4]
|
||||
var sock: = Socket.new()
|
||||
sock.set_broadcast_enabled(broad)
|
||||
var rc = Error.OK if not bind else sock.bind(port, addr)
|
||||
var errlevel = log.INFO if rc == Error.OK else log.ERROR
|
||||
log.message(errlevel, '%s: сокет:%s:%d привязанный:%s %s' % [nm, addr, port, ['нет', 'да'][int(bind)], error_string(rc)])
|
||||
return sock
|
||||
var addr = repsettings.UnitProfiles[nm][1]
|
||||
var port = repsettings.UnitProfiles[nm][2]
|
||||
var broad = repsettings.UnitProfiles[nm][3]
|
||||
var bind = repsettings.UnitProfiles[nm][4]
|
||||
var sock: = Socket.new()
|
||||
sock.set_broadcast_enabled(broad)
|
||||
var rc = Error.OK if not bind else sock.bind(port, addr)
|
||||
var errlevel = log.INFO if rc == Error.OK else log.ERROR
|
||||
log.message(errlevel, '%s: сокет:%s:%d привязанный:%s %s' % [nm, addr, port, ['нет', 'да'][int(bind)], error_string(rc)])
|
||||
return sock
|
||||
|
||||
|
||||
func create_tcpsocket(nm) -> SocketTCP:
|
||||
var addr = repsettings.UnitProfiles[nm][1]
|
||||
var port = repsettings.UnitProfiles[nm][2]
|
||||
var sock = SocketTCP.new()
|
||||
sock.unit_key = repsettings.get_unit_key(nm)
|
||||
sock.listen(port, addr)
|
||||
log.message(log.INFO, '%s: сокет:%s:%d привязанный:' % [nm, addr, port])
|
||||
return sock
|
||||
var addr = repsettings.UnitProfiles[nm][1]
|
||||
var port = repsettings.UnitProfiles[nm][2]
|
||||
var sock = SocketTCP.new()
|
||||
sock.unit_key = repsettings.get_unit_key(nm)
|
||||
sock.listen(port, addr)
|
||||
log.message(log.INFO, '%s: сокет:%s:%d привязанный:' % [nm, addr, port])
|
||||
return sock
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
log.info('Модуль работы с сетью готов')
|
||||
poll_sockets.append(create_socket('уарэп-яу07-частный'))
|
||||
poll_sockets.append(create_socket('уарэп-яу07-общий'))
|
||||
poll_sockets.append(create_socket('уарэп-капсрпб-пол'))
|
||||
sock_unicast = poll_sockets[0]
|
||||
sock_capsrpb = poll_sockets[2]
|
||||
log.info('Модуль работы с сетью готов')
|
||||
poll_sockets.append(create_socket('уарэп-яу07-частный'))
|
||||
poll_sockets.append(create_socket('уарэп-яу07-общий'))
|
||||
poll_sockets.append(create_socket('уарэп-капсрпб-пол'))
|
||||
sock_unicast = poll_sockets[0]
|
||||
sock_capsrpb = poll_sockets[2]
|
||||
|
||||
for unit_name in repsettings.UnitProfiles:
|
||||
var setting = repsettings.UnitProfiles[unit_name]
|
||||
var proto = setting[0]
|
||||
if proto in PROTOCOL_TYPES:
|
||||
var unit = PROTOCOL_TYPES[proto].new(unit_name)
|
||||
var unit_key = repsettings.get_unit_key(unit_name)
|
||||
units[unit_key] = unit
|
||||
if logger_page:
|
||||
unit.connect('line_changed', Callable(logger_page, 'on_line_changed').bind(unit_key))
|
||||
unit.connect('command_fail', Callable(logger_page, 'on_command_fail').bind(unit_key))
|
||||
for unit_name in repsettings.UnitProfiles:
|
||||
var setting_ = repsettings.UnitProfiles[unit_name]
|
||||
var proto = setting_[0]
|
||||
if proto in PROTOCOL_TYPES:
|
||||
var unit = PROTOCOL_TYPES[proto].new(unit_name)
|
||||
var unit_key = repsettings.get_unit_key(unit_name)
|
||||
units[unit_key] = unit
|
||||
if logger_page:
|
||||
unit.connect('line_changed', Callable(logger_page, 'on_line_changed').bind(unit_key))
|
||||
unit.connect('command_fail', Callable(logger_page, 'on_command_fail').bind(unit_key))
|
||||
|
||||
if proto in TCP_PROTO:
|
||||
var unit = TCP_PROTO[proto].new(unit_name)
|
||||
var unit_key = repsettings.get_unit_key(unit_name)
|
||||
units_tcp[unit_key] = unit
|
||||
if logger_page:
|
||||
unit.connect('line_changed', Callable(logger_page, 'on_line_changed').bind(unit_key))
|
||||
unit.connect('command_fail', Callable(logger_page, 'on_command_fail').bind(unit_key))
|
||||
if proto in TCP_PROTO:
|
||||
var unit = TCP_PROTO[proto].new(unit_name)
|
||||
var unit_key = repsettings.get_unit_key(unit_name)
|
||||
units_tcp[unit_key] = unit
|
||||
if logger_page:
|
||||
unit.connect('line_changed', Callable(logger_page, 'on_line_changed').bind(unit_key))
|
||||
unit.connect('command_fail', Callable(logger_page, 'on_command_fail').bind(unit_key))
|
||||
|
||||
tcp_sockets.append([create_tcpsocket('уарэп-5п28'), units_tcp[repsettings.get_unit_key('уарэп-5п28')]])
|
||||
tcp_sockets.append([create_tcpsocket('уарэп-5п28'), units_tcp[repsettings.get_unit_key('уарэп-5п28')]])
|
||||
|
||||
for key in units: log.info('%s %s:%d' % [units[key].name, key[0], key[1]])
|
||||
for key in units_tcp: log.info('%s %s:%d' % [units_tcp[key].name, key[0], key[1]])
|
||||
for key in units: log.info('%s %s:%d' % [units[key].name, key[0], key[1]])
|
||||
for key in units_tcp: log.info('%s %s:%d' % [units_tcp[key].name, key[0], key[1]])
|
||||
|
||||
|
||||
func poll_receive(sock: Socket, tick: int) -> bool:
|
||||
while sock.get_available_packet_count() > 0:
|
||||
var data: = sock.get_packet()
|
||||
var addr: = sock.get_packet_ip()
|
||||
var port: = sock.get_packet_port()
|
||||
var addr_port: = [addr, port]
|
||||
if addr_port in units: units[addr_port].parse(data, tick)
|
||||
return false
|
||||
while sock.get_available_packet_count() > 0:
|
||||
var data: = sock.get_packet()
|
||||
var addr: = sock.get_packet_ip()
|
||||
var port: = sock.get_packet_port()
|
||||
var addr_port: = [addr, port]
|
||||
if addr_port in units: units[addr_port].parse(data, tick)
|
||||
return false
|
||||
|
||||
|
||||
func poll_receive_tcp(sock: SocketTCP, tick: int) -> bool:
|
||||
if sock.is_connection_available(): # check if someone's trying to connect
|
||||
var client = sock.take_connection() # accept connection
|
||||
sock.peerstream.set_stream_peer(client) # bind peerstream to new client
|
||||
print_debug('client_is_connected')
|
||||
var peer = sock.peerstream.get_stream_peer()
|
||||
if peer:
|
||||
var peer_len_data = peer.get_available_bytes()
|
||||
if peer_len_data > 0:
|
||||
get_client_data(sock, peer_len_data, peer, tick)
|
||||
if sock.unit_key in units_tcp and sock.rx_all: units_tcp[sock.unit_key].parse(sock.rx_data, tick)
|
||||
return false
|
||||
if sock.is_connection_available(): # check if someone's trying to connect
|
||||
var client = sock.take_connection() # accept connection
|
||||
sock.peerstream.set_stream_peer(client) # bind peerstream to new client
|
||||
print_debug('client_is_connected')
|
||||
var peer = sock.peerstream.get_stream_peer()
|
||||
if peer:
|
||||
var peer_len_data = peer.get_available_bytes()
|
||||
if peer_len_data > 0:
|
||||
get_client_data(sock, peer_len_data, peer, tick)
|
||||
if sock.unit_key in units_tcp and sock.rx_all: units_tcp[sock.unit_key].parse(sock.rx_data, tick)
|
||||
return false
|
||||
|
||||
|
||||
func get_client_data(sock: SocketTCP, peer_len_data, peer, tick):
|
||||
if tick - sock.rx_tick > sock.RX_TIMEOUT:
|
||||
sock.rx_all = true
|
||||
sock.rx_tick = tick
|
||||
if sock.rx_all:
|
||||
if peer_len_data >= sock.head_len:
|
||||
sock.rx_all = false
|
||||
sock.rx_len = sock.head_len
|
||||
var head = peer.get_data(sock.head_len)
|
||||
sock.data_len = head[1].decode_u32(sock.len_place)
|
||||
var len_data_in_buf = peer.get_available_bytes()
|
||||
if len_data_in_buf > 0:
|
||||
sock.rx_data = head[1]
|
||||
var len_rx = len_data_in_buf
|
||||
if len_data_in_buf >= sock.data_len:
|
||||
len_rx = sock.data_len
|
||||
get_tcp_data(sock, peer, len_rx)
|
||||
else:
|
||||
var len_rx = (sock.head_len + sock.data_len) - sock.rx_len
|
||||
if peer_len_data < len_rx:
|
||||
len_rx = peer_len_data
|
||||
get_tcp_data(sock, peer, len_rx)
|
||||
if tick - sock.rx_tick > sock.RX_TIMEOUT:
|
||||
sock.rx_all = true
|
||||
sock.rx_tick = tick
|
||||
if sock.rx_all:
|
||||
if peer_len_data >= sock.head_len:
|
||||
sock.rx_all = false
|
||||
sock.rx_len = sock.head_len
|
||||
var head = peer.get_data(sock.head_len)
|
||||
sock.data_len = head[1].decode_u32(sock.len_place)
|
||||
var len_data_in_buf = peer.get_available_bytes()
|
||||
if len_data_in_buf > 0:
|
||||
sock.rx_data = head[1]
|
||||
var len_rx = len_data_in_buf
|
||||
if len_data_in_buf >= sock.data_len:
|
||||
len_rx = sock.data_len
|
||||
get_tcp_data(sock, peer, len_rx)
|
||||
else:
|
||||
var len_rx = (sock.head_len + sock.data_len) - sock.rx_len
|
||||
if peer_len_data < len_rx:
|
||||
len_rx = peer_len_data
|
||||
get_tcp_data(sock, peer, len_rx)
|
||||
|
||||
|
||||
func get_tcp_data(sock: SocketTCP, peer, len_rx):
|
||||
var temp_data = peer.get_data(len_rx)[1]
|
||||
sock.rx_data.append_array(temp_data)
|
||||
sock.rx_len += len_rx
|
||||
if sock.rx_len >= sock.head_len + sock.data_len:
|
||||
sock.rx_all = true
|
||||
var temp_data = peer.get_data(len_rx)[1]
|
||||
sock.rx_data.append_array(temp_data)
|
||||
sock.rx_len += len_rx
|
||||
if sock.rx_len >= sock.head_len + sock.data_len:
|
||||
sock.rx_all = true
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
var tick = Time.get_ticks_msec()
|
||||
for addr in units:
|
||||
var unit = units[addr]
|
||||
match unit.process(tick):
|
||||
Error.OK: sock_unicast.send_to(addr, unit.tx_data)
|
||||
Error.FAILED: emit_signal('socket_error', 'ошибка: %s %s:%d' % [unit, addr[0], addr[1]])
|
||||
for sock_unit in tcp_sockets:
|
||||
var sock = sock_unit[0]
|
||||
var unit = sock_unit[1]
|
||||
match unit.process(tick):
|
||||
Error.OK: sock.send_to(unit.tx_data)
|
||||
Error.FAILED: emit_signal('socket_error', 'ошибка: %s' %unit)
|
||||
poll_receive_tcp(sock, tick)
|
||||
poll_sockets.any(func(sock): poll_receive(sock, tick))
|
||||
var tick = Time.get_ticks_msec()
|
||||
for addr in units:
|
||||
var unit = units[addr]
|
||||
match unit.process(tick):
|
||||
Error.OK: sock_unicast.send_to(addr, unit.tx_data)
|
||||
Error.FAILED: emit_signal('socket_error', 'ошибка: %s %s:%d' % [unit, addr[0], addr[1]])
|
||||
for sock_unit in tcp_sockets:
|
||||
var sock = sock_unit[0]
|
||||
var unit = sock_unit[1]
|
||||
match unit.process(tick):
|
||||
Error.OK: sock.send_to(unit.tx_data)
|
||||
Error.FAILED: emit_signal('socket_error', 'ошибка: %s' %unit)
|
||||
poll_receive_tcp(sock, tick)
|
||||
poll_sockets.any(func(sock): poll_receive(sock, tick))
|
||||
|
||||
@@ -9,185 +9,185 @@ const BUFFER_SIZE = 2048 ## Размер приёмного буфера д
|
||||
|
||||
## Тип модуляции для запаковки в пакет для 5П-28.
|
||||
const MOD_TYPES: Array = ['',
|
||||
'am',
|
||||
'ook',
|
||||
'ask',
|
||||
'fm',
|
||||
'qpsk',
|
||||
'oqpsk',
|
||||
'pi4qpsk',
|
||||
'qam16',
|
||||
'qam32',
|
||||
'qam64',
|
||||
'qam128',
|
||||
'qam256',
|
||||
'qam512',
|
||||
'cpfsk',
|
||||
'psk',
|
||||
'ofdm',]
|
||||
'am',
|
||||
'ook',
|
||||
'ask',
|
||||
'fm',
|
||||
'qpsk',
|
||||
'oqpsk',
|
||||
'pi4qpsk',
|
||||
'qam16',
|
||||
'qam32',
|
||||
'qam64',
|
||||
'qam128',
|
||||
'qam256',
|
||||
'qam512',
|
||||
'cpfsk',
|
||||
'psk',
|
||||
'ofdm',]
|
||||
|
||||
const CU_STATE: Dictionary = {
|
||||
0:2, # Подготовка к выполнению
|
||||
1:1, # Выполняется
|
||||
2:9, # Ошибка в команде
|
||||
3:7, # Занят выполнением другого ЦУ
|
||||
4:9, # Неисправность
|
||||
}
|
||||
0:2, # Подготовка к выполнению
|
||||
1:1, # Выполняется
|
||||
2:9, # Ошибка в команде
|
||||
3:7, # Занят выполнением другого ЦУ
|
||||
4:9, # Неисправность
|
||||
}
|
||||
|
||||
class TCP5P28:
|
||||
const PACK_TYPE_CMD: int = 1
|
||||
const PACK_TYPE_RES: int = 2
|
||||
const CMD_TYPE_STATE: int = 1
|
||||
const CMD_TYPE_TH: int = 2
|
||||
const CMD_TYPE_IN: int = 3
|
||||
const PACK_TYPE_CMD: int = 1
|
||||
const PACK_TYPE_RES: int = 2
|
||||
const CMD_TYPE_STATE: int = 1
|
||||
const CMD_TYPE_TH: int = 2
|
||||
const CMD_TYPE_IN: int = 3
|
||||
|
||||
signal line_changed(unit: TCP5P28) ## Сигнал состояние связи изменилось.
|
||||
signal data_received(unit: TCP5P28) ## Сигнал данные приняты.
|
||||
signal command_fail(unit: TCP5P28) ## Сигнал при не выполнении команды.
|
||||
signal parse_error(unit: TCP5P28, msg: String) ## Сигнал ошибки разбора сообщения.
|
||||
signal get_threats(unit: TCP5P28) ## Сигнал запрос целей.
|
||||
signal get_interfers(unit: TCP5P28) ## Запрос состояния выполнения целеуказания.
|
||||
signal line_changed(unit: TCP5P28) ## Сигнал состояние связи изменилось.
|
||||
signal data_received(unit: TCP5P28) ## Сигнал данные приняты.
|
||||
signal command_fail(unit: TCP5P28) ## Сигнал при не выполнении команды.
|
||||
signal parse_error(unit: TCP5P28, msg: String) ## Сигнал ошибки разбора сообщения.
|
||||
signal get_threats(unit: TCP5P28) ## Сигнал запрос целей.
|
||||
signal get_interfers(unit: TCP5P28) ## Запрос состояния выполнения целеуказания.
|
||||
|
||||
var online: = false ## Состояние связи с источником сообщений.
|
||||
var name: String ## Имя экземпляра.
|
||||
var rx_tick: = 0 ## Тик время последнего приёма, мс.
|
||||
var tx_data: = PackedByteArray() ## Пакет для отправки.
|
||||
var tx_stack: Array ## Массив пакетов для отправки.
|
||||
var online: = false ## Состояние связи с источником сообщений.
|
||||
var name: String ## Имя экземпляра.
|
||||
var rx_tick: = 0 ## Тик время последнего приёма, мс.
|
||||
var tx_data: = PackedByteArray() ## Пакет для отправки.
|
||||
var tx_stack: Array ## Массив пакетов для отправки.
|
||||
|
||||
func _to_string() -> String: return String('капсрпб: "%s" %s ' % [self.name, ['отключен', 'на связи'][int(online)]])
|
||||
func _init(nm): self.name = nm
|
||||
func _to_string() -> String: return String('капсрпб: "%s" %s ' % [self.name, ['отключен', 'на связи'][int(online)]])
|
||||
func _init(nm): self.name = nm
|
||||
|
||||
func parse(data: PackedByteArray, now_tick: int):
|
||||
rx_tick = now_tick
|
||||
if not online:
|
||||
online = true
|
||||
emit_signal('line_changed', self)
|
||||
var pack_type = data.decode_u8(2)
|
||||
if pack_type == PACK_TYPE_CMD:
|
||||
var cmd_type = data.decode_u8(8)
|
||||
if cmd_type == CMD_TYPE_TH:
|
||||
emit_signal('get_threats')
|
||||
if cmd_type == CMD_TYPE_STATE:
|
||||
emit_signal('get_interfers')
|
||||
var external_cu = ProjectSettings.get_setting('application/config/external_cu', false)
|
||||
if cmd_type == CMD_TYPE_IN and external_cu:
|
||||
set_interfer(data)
|
||||
func parse(data: PackedByteArray, now_tick: int):
|
||||
rx_tick = now_tick
|
||||
if not online:
|
||||
online = true
|
||||
emit_signal('line_changed', self)
|
||||
var pack_type = data.decode_u8(2)
|
||||
if pack_type == PACK_TYPE_CMD:
|
||||
var cmd_type = data.decode_u8(8)
|
||||
if cmd_type == CMD_TYPE_TH:
|
||||
emit_signal('get_threats')
|
||||
if cmd_type == CMD_TYPE_STATE:
|
||||
emit_signal('get_interfers')
|
||||
var external_cu = ProjectSettings.get_setting('application/config/external_cu', false)
|
||||
if cmd_type == CMD_TYPE_IN and external_cu:
|
||||
set_interfer(data)
|
||||
|
||||
func process(now_tick: int):
|
||||
if online and ((now_tick - rx_tick) > ONLINE_TIMEOUT):
|
||||
online = false
|
||||
emit_signal('line_changed', self)
|
||||
if len(tx_stack):
|
||||
tx_data = tx_stack[0]
|
||||
tx_stack.remove_at(0)
|
||||
return Error.OK
|
||||
else:
|
||||
return Error.ERR_UNAVAILABLE
|
||||
func process(now_tick: int):
|
||||
if online and ((now_tick - rx_tick) > ONLINE_TIMEOUT):
|
||||
online = false
|
||||
emit_signal('line_changed', self)
|
||||
if len(tx_stack):
|
||||
tx_data = tx_stack[0]
|
||||
tx_stack.remove_at(0)
|
||||
return Error.OK
|
||||
else:
|
||||
return Error.ERR_UNAVAILABLE
|
||||
|
||||
func pack_threats(ths):
|
||||
var data = PackedByteArray()
|
||||
var data_len = 4 + len(ths) * 80 # длинна блока данных в байтах
|
||||
var tick = Time.get_ticks_msec()
|
||||
data.resize(4)
|
||||
data.encode_u16(0, 0) # Код ошибки
|
||||
data.encode_u16(2, len(ths)) # Количество целей
|
||||
for th in ths.values():
|
||||
data.append_array(get_threats_data(th, int(tick)))
|
||||
var data_to_send: PackedByteArray = create_header(data_len)
|
||||
data_to_send.append_array(data)
|
||||
tx_stack.append(data_to_send)
|
||||
func pack_threats(ths):
|
||||
var data = PackedByteArray()
|
||||
var data_len = 4 + len(ths) * 80 # длинна блока данных в байтах
|
||||
var tick = Time.get_ticks_msec()
|
||||
data.resize(4)
|
||||
data.encode_u16(0, 0) # Код ошибки
|
||||
data.encode_u16(2, len(ths)) # Количество целей
|
||||
for th in ths.values():
|
||||
data.append_array(get_threats_data(th, int(tick)))
|
||||
var data_to_send: PackedByteArray = create_header(data_len)
|
||||
data_to_send.append_array(data)
|
||||
tx_stack.append(data_to_send)
|
||||
|
||||
func pack_interfers(interfers, ecms):
|
||||
var data = PackedByteArray()
|
||||
var data_len = 12 # длинна блока данных в байтах
|
||||
data.resize(data_len)
|
||||
data.encode_u16(0, 0) # Код ошибки
|
||||
data.encode_u16(2, len(interfers)) # Количество целей
|
||||
data.encode_u32(4, 0) # Состояние УА-РЕП
|
||||
data.encode_u32(8, 0) # Состояние линий связи
|
||||
for id in interfers.values():
|
||||
var cu_data: PackedByteArray = []
|
||||
cu_data.resize(4)
|
||||
var cu = ecms[id]
|
||||
cu_data.encode_u16(0, cu.ispp)
|
||||
var state: int
|
||||
if CU_STATE.has(cu.svk):
|
||||
state = CU_STATE[cu.svk]
|
||||
else:
|
||||
state = 9
|
||||
cu_data.encode_u8(2, state) # Состояние выполнения команды
|
||||
cu_data.encode_u8(3, 0xFF) # Эффективность работы помехи
|
||||
data.append_array(cu_data)
|
||||
var data_to_send: PackedByteArray = create_header(data_len + 4 * len(interfers))
|
||||
data_to_send.append_array(data)
|
||||
tx_stack.append(data_to_send)
|
||||
func pack_interfers(interfers, ecms):
|
||||
var data = PackedByteArray()
|
||||
var data_len = 12 # длинна блока данных в байтах
|
||||
data.resize(data_len)
|
||||
data.encode_u16(0, 0) # Код ошибки
|
||||
data.encode_u16(2, len(interfers)) # Количество целей
|
||||
data.encode_u32(4, 0) # Состояние УА-РЕП
|
||||
data.encode_u32(8, 0) # Состояние линий связи
|
||||
for id in interfers.values():
|
||||
var cu_data: PackedByteArray = []
|
||||
cu_data.resize(4)
|
||||
var cu = ecms[id]
|
||||
cu_data.encode_u16(0, cu.ispp)
|
||||
var state: int
|
||||
if CU_STATE.has(cu.svk):
|
||||
state = CU_STATE[cu.svk]
|
||||
else:
|
||||
state = 9
|
||||
cu_data.encode_u8(2, state) # Состояние выполнения команды
|
||||
cu_data.encode_u8(3, 0xFF) # Эффективность работы помехи
|
||||
data.append_array(cu_data)
|
||||
var data_to_send: PackedByteArray = create_header(data_len + 4 * len(interfers))
|
||||
data_to_send.append_array(data)
|
||||
tx_stack.append(data_to_send)
|
||||
|
||||
func create_header(data_len):
|
||||
var head_data = PackedByteArray()
|
||||
head_data.resize(8) # Размер заголовка
|
||||
head_data.encode_u16(0, 0) # Код ошибки
|
||||
head_data.encode_u8(2, 2) # Тип пакета, ответ на запрос
|
||||
head_data.encode_u8(3, 5) # Версия протокола, всегда 5
|
||||
head_data.encode_u32(4, data_len) # Длинна пакета данных
|
||||
return head_data
|
||||
func create_header(data_len):
|
||||
var head_data = PackedByteArray()
|
||||
head_data.resize(8) # Размер заголовка
|
||||
head_data.encode_u16(0, 0) # Код ошибки
|
||||
head_data.encode_u8(2, 2) # Тип пакета, ответ на запрос
|
||||
head_data.encode_u8(3, 5) # Версия протокола, всегда 5
|
||||
head_data.encode_u32(4, data_len) # Длинна пакета данных
|
||||
return head_data
|
||||
|
||||
func get_threats_data(th, tick):
|
||||
var th_data = PackedByteArray()
|
||||
th_data.resize(80) # Количество байт в массиве
|
||||
th_data.encode_u64(0, tick)
|
||||
var flags: int = 0 # с 0 по 7 бит рекомендованная помеха
|
||||
flags |= 0 << 8 # Флаг рекомендуемой помехи
|
||||
flags |= int(th.fflags['aoa']) << 9 # Флаг доставерности пеленга
|
||||
flags |= int(th.fflags['alt']) << 10 # Флаг доставерности высоты
|
||||
flags |= int(th.fflags['power']) << 11 # Флаг доставерности мощности
|
||||
flags |= int(th.fflags['baud']) << 12 # Флаг доставерности ск. мод.
|
||||
flags |= int(th.fflags['slon']) << 13 # Флаг доставерности долготы ст. позиции
|
||||
flags |= int(th.fflags['slat']) << 14 # Флаг доставерности широты ст. позиции
|
||||
flags |= int(th.fflags['lon']) << 15 # Флаг доставерности долготы
|
||||
flags |= int(th.fflags['lat']) << 16 # Флаг доставерности широты
|
||||
flags |= int(0) << 30 # Флаг признак назначения помехи на цель
|
||||
flags |= int(0) << 31 # Флаг признак назначения опасной цель
|
||||
th_data.encode_u32(8, flags) # Флаги
|
||||
th_data.encode_u16(12, th.id) # Идентификатор объекта
|
||||
th_data.encode_u16(14, int(round(th.aoa/0.1))) # Пеленг объекта
|
||||
th_data.encode_u16(16, int(th.alt)) # Высота объекта
|
||||
th_data.encode_u16(18, int(th.freq)) # Частота объекта
|
||||
th_data.encode_u16(20, int(th.width)) # Ширина частотной полосы объекта
|
||||
th_data.encode_u8(22, int(th.power)) # Мощность излучения объекта
|
||||
var mod = MOD_TYPES.find(th.tmod)
|
||||
if mod == -1: mod = 0
|
||||
th_data.encode_u8(23, int(mod)) # Тип модуляции
|
||||
th_data.encode_u32(24, int(th.baud)) # Скорость модуляции, бод
|
||||
to_cp866(th.proto, th_data)
|
||||
var c1 = pow(2, 30) / 180.0
|
||||
th_data.encode_s32(64, int(th.slon * c1))
|
||||
th_data.encode_s32(68, int(th.slat * c1))
|
||||
th_data.encode_s32(72, int(th.lon * c1))
|
||||
th_data.encode_s32(76, int(th.lat * c1))
|
||||
return th_data
|
||||
func get_threats_data(th, tick):
|
||||
var th_data = PackedByteArray()
|
||||
th_data.resize(80) # Количество байт в массиве
|
||||
th_data.encode_u64(0, tick)
|
||||
var flags: int = 0 # с 0 по 7 бит рекомендованная помеха
|
||||
flags |= 0 << 8 # Флаг рекомендуемой помехи
|
||||
flags |= int(th.fflags['aoa']) << 9 # Флаг доставерности пеленга
|
||||
flags |= int(th.fflags['alt']) << 10 # Флаг доставерности высоты
|
||||
flags |= int(th.fflags['power']) << 11 # Флаг доставерности мощности
|
||||
flags |= int(th.fflags['baud']) << 12 # Флаг доставерности ск. мод.
|
||||
flags |= int(th.fflags['slon']) << 13 # Флаг доставерности долготы ст. позиции
|
||||
flags |= int(th.fflags['slat']) << 14 # Флаг доставерности широты ст. позиции
|
||||
flags |= int(th.fflags['lon']) << 15 # Флаг доставерности долготы
|
||||
flags |= int(th.fflags['lat']) << 16 # Флаг доставерности широты
|
||||
flags |= int(0) << 30 # Флаг признак назначения помехи на цель
|
||||
flags |= int(0) << 31 # Флаг признак назначения опасной цель
|
||||
th_data.encode_u32(8, flags) # Флаги
|
||||
th_data.encode_u16(12, th.id) # Идентификатор объекта
|
||||
th_data.encode_u16(14, int(round(th.aoa/0.1))) # Пеленг объекта
|
||||
th_data.encode_u16(16, int(th.alt)) # Высота объекта
|
||||
th_data.encode_u16(18, int(th.freq)) # Частота объекта
|
||||
th_data.encode_u16(20, int(th.width)) # Ширина частотной полосы объекта
|
||||
th_data.encode_u8(22, int(th.power)) # Мощность излучения объекта
|
||||
var mod = MOD_TYPES.find(th.tmod)
|
||||
if mod == -1: mod = 0
|
||||
th_data.encode_u8(23, int(mod)) # Тип модуляции
|
||||
th_data.encode_u32(24, int(th.baud)) # Скорость модуляции, бод
|
||||
to_cp866(th.proto, th_data)
|
||||
var c1 = pow(2, 30) / 180.0
|
||||
th_data.encode_s32(64, int(th.slon * c1))
|
||||
th_data.encode_s32(68, int(th.slat * c1))
|
||||
th_data.encode_s32(72, int(th.lon * c1))
|
||||
th_data.encode_s32(76, int(th.lat * c1))
|
||||
return th_data
|
||||
|
||||
func to_cp866(proto: String, th_data):
|
||||
var cp866_proto: PackedByteArray = proto.to_ascii_buffer()
|
||||
cp866_proto.resize(36)
|
||||
for i in len(cp866_proto):
|
||||
th_data[28 + i] = cp866_proto[i]
|
||||
func to_cp866(proto: String, th_data):
|
||||
var cp866_proto: PackedByteArray = proto.to_ascii_buffer()
|
||||
cp866_proto.resize(36)
|
||||
for i in len(cp866_proto):
|
||||
th_data[28 + i] = cp866_proto[i]
|
||||
|
||||
func set_interfer(data):
|
||||
var mode = data.decode_u8(9)
|
||||
var id = data.decode_u16(10)
|
||||
var aoa = float(data.decode_u16(12)) / 10
|
||||
var ela = float(data.decode_u16(14)) / 10
|
||||
var freq = data.decode_u16(16)
|
||||
var width = data.decode_u16(18)
|
||||
var interfer_params: Array = [mode, id, aoa, ela, freq, width]
|
||||
signaller.emit_signal('interfer_rcv', interfer_params)
|
||||
func set_interfer(data):
|
||||
var mode = data.decode_u8(9)
|
||||
var id = data.decode_u16(10)
|
||||
var aoa = float(data.decode_u16(12)) / 10
|
||||
var ela = float(data.decode_u16(14)) / 10
|
||||
var freq = data.decode_u16(16)
|
||||
var width = data.decode_u16(18)
|
||||
var interfer_params: Array = [mode, id, aoa, ela, freq, width]
|
||||
signaller.emit_signal('interfer_rcv', interfer_params)
|
||||
|
||||
func on_interfer_accept(err: bool):
|
||||
var data_tx = PackedByteArray()
|
||||
var data_len = 2 # длинна блока данных в байтах
|
||||
data_tx.resize(data_len)
|
||||
data_tx.encode_u16(0, err) # Код ошибки
|
||||
var data_to_send: PackedByteArray = create_header(data_len)
|
||||
data_to_send.append_array(data_tx)
|
||||
tx_stack.append(data_to_send)
|
||||
func on_interfer_accept(err: bool):
|
||||
var data_tx = PackedByteArray()
|
||||
var data_len = 2 # длинна блока данных в байтах
|
||||
data_tx.resize(data_len)
|
||||
data_tx.encode_u16(0, err) # Код ошибки
|
||||
var data_to_send: PackedByteArray = create_header(data_len)
|
||||
data_to_send.append_array(data_tx)
|
||||
tx_stack.append(data_to_send)
|
||||
|
||||
|
||||
714
table/table.gd
714
table/table.gd
@@ -57,94 +57,94 @@ func defaultselector_color_proc(_i_row: int): return selector_color
|
||||
## [param scrl] - Прокрутка родитель таблицы.[br]
|
||||
## [param prnt] - Родитель прокрутки.[br]
|
||||
func pin_header(scrl: ScrollContainer, prnt: Control):
|
||||
scrl.remove_child(header)
|
||||
prnt.add_child(header)
|
||||
var v_separation = get_theme_constant('v_separation')
|
||||
header.position = scrl.position - Vector2(0, header.size.y + v_separation)
|
||||
scroll = scrl
|
||||
scroll_adj = scrl.position
|
||||
scrl.remove_child(header)
|
||||
prnt.add_child(header)
|
||||
var v_separation = get_theme_constant('v_separation')
|
||||
header.position = scrl.position - Vector2(0, header.size.y + v_separation)
|
||||
scroll = scrl
|
||||
scroll_adj = scrl.position
|
||||
|
||||
|
||||
## Перемещает указатель на одну строку вверх
|
||||
func selector_up():
|
||||
var i_rows: = []
|
||||
get_selected_rows(i_rows)
|
||||
for i in i_rows:
|
||||
set_row_selected(i, false)
|
||||
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
|
||||
if i_row < 0:
|
||||
i_row = rows_count - 1
|
||||
set_row_selected(i_row, true)
|
||||
var node = get_node2(0, i_row)
|
||||
if scroll is ScrollContainer:
|
||||
scroll.ensure_control_visible(node)
|
||||
emit_signal('selected_changed', i_row)
|
||||
var i_rows: = []
|
||||
get_selected_rows(i_rows)
|
||||
for i in i_rows:
|
||||
set_row_selected(i, false)
|
||||
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
|
||||
if i_row < 0:
|
||||
i_row = rows_count - 1
|
||||
set_row_selected(i_row, true)
|
||||
var node = get_node2(0, i_row)
|
||||
if scroll is ScrollContainer:
|
||||
scroll.ensure_control_visible(node)
|
||||
emit_signal('selected_changed', i_row)
|
||||
|
||||
|
||||
## Перемещает указатель на одну строку вниз
|
||||
func selector_down():
|
||||
var i_rows: = []
|
||||
get_selected_rows(i_rows)
|
||||
for i in i_rows:
|
||||
set_row_selected(i, false)
|
||||
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
|
||||
i_row %= rows_count
|
||||
set_row_selected(i_row, true)
|
||||
var node = get_node2(0, i_row)
|
||||
if scroll is ScrollContainer:
|
||||
scroll.ensure_control_visible(node)
|
||||
emit_signal('selected_changed', i_row)
|
||||
var i_rows: = []
|
||||
get_selected_rows(i_rows)
|
||||
for i in i_rows:
|
||||
set_row_selected(i, false)
|
||||
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
|
||||
i_row %= rows_count
|
||||
set_row_selected(i_row, true)
|
||||
var node = get_node2(0, i_row)
|
||||
if scroll is ScrollContainer:
|
||||
scroll.ensure_control_visible(node)
|
||||
emit_signal('selected_changed', i_row)
|
||||
|
||||
|
||||
## Делает ряд [param i_row] видимым.
|
||||
func ensure_row_visible(i_row: int):
|
||||
assert(scroll is ScrollContainer, 'Таблица должна быть дочерней к ScrollContainer')
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, 0, i_row)
|
||||
var node = nodes[key]
|
||||
scroll.ensure_control_visible(node)
|
||||
assert(scroll is ScrollContainer, 'Таблица должна быть дочерней к ScrollContainer')
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, 0, i_row)
|
||||
var node = nodes[key]
|
||||
scroll.ensure_control_visible(node)
|
||||
|
||||
|
||||
## Устанавливает выравнивание из массива [param alignments] для всех колонок.
|
||||
func set_columns_alignments(alignments: Array):
|
||||
assert(columns == alignments.size())
|
||||
var rows_count: = get_rows_count()
|
||||
for i_row in rows_count:
|
||||
for i_col in alignments.size():
|
||||
set_node_alligment(i_col, i_row, alignments[i_col])
|
||||
assert(columns == alignments.size())
|
||||
var rows_count: = get_rows_count()
|
||||
for i_row in rows_count:
|
||||
for i_col in alignments.size():
|
||||
set_node_alligment(i_col, i_row, alignments[i_col])
|
||||
|
||||
|
||||
##
|
||||
func load_selector_scene(file_name: String):
|
||||
selector_type_file = file_name
|
||||
ScnSelector = load(file_name)
|
||||
selector_type_file = file_name
|
||||
ScnSelector = load(file_name)
|
||||
|
||||
|
||||
##
|
||||
func load_node_scene(file_name: String):
|
||||
node_type_file = file_name
|
||||
ScnNode = load(file_name)
|
||||
node_type_file = file_name
|
||||
ScnNode = load(file_name)
|
||||
|
||||
|
||||
##
|
||||
func _ready():
|
||||
ScnSelector = load(selector_type_file)
|
||||
ScnNode = load(node_type_file)
|
||||
assert(ScnSelector is PackedScene)
|
||||
assert(ScnNode is PackedScene)
|
||||
ScnSelector = load(selector_type_file)
|
||||
ScnNode = load(node_type_file)
|
||||
assert(ScnSelector is PackedScene)
|
||||
assert(ScnNode is PackedScene)
|
||||
|
||||
|
||||
## Выравнивает по нижнему левому углу. Используется для выравнивания по заголовку.
|
||||
func align_to_left_bottompos(hdr: Control, gap: = Vector2(0, 0)):
|
||||
position.x = hdr.position.x + gap.x
|
||||
position.y = hdr.position.y + hdr.size.y + gap.y
|
||||
position.x = hdr.position.x + gap.x
|
||||
position.y = hdr.position.y + hdr.size.y + gap.y
|
||||
|
||||
|
||||
## Устанавливает пользовательские данные для ячейки.[br]
|
||||
@@ -153,9 +153,9 @@ func align_to_left_bottompos(hdr: Control, gap: = Vector2(0, 0)):
|
||||
## [param pname] - Имя пользовательских данных.[br]
|
||||
## [param val] - Значение пользовательских данных.[br]
|
||||
func set_node_meta(i_col: int, i_row: int, pname: String, val) -> void:
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
var node = nodes[key]
|
||||
node.set_meta(pname, val)
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
var node = nodes[key]
|
||||
node.set_meta(pname, val)
|
||||
|
||||
|
||||
## Возвращает пользовательские данные для ячейки.[br]
|
||||
@@ -163,10 +163,10 @@ func set_node_meta(i_col: int, i_row: int, pname: String, val) -> void:
|
||||
## [param i_row] - Индекс ряда.[br]
|
||||
## [param pname] - Имя пользовательских данных.[br]
|
||||
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)
|
||||
return node.get_meta(pname)
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
var node = nodes[key]
|
||||
assert_meta(i_col, i_row, pname, node)
|
||||
return node.get_meta(pname)
|
||||
|
||||
|
||||
## Устанавливает свойство ячейки.[br]
|
||||
@@ -176,9 +176,9 @@ func get_node_meta(i_col: int, i_row: int, pname: String):
|
||||
## [param val] - Значение свойства.[br]
|
||||
## [i]Свойство[/i] [param pname] [i]ячейки должно существовать.[/i]
|
||||
func set_node_property(i_col: int, i_row: int, pname: String, val) -> void:
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
var node = nodes[key]
|
||||
node.set(pname, val)
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
var node = nodes[key]
|
||||
node.set(pname, val)
|
||||
|
||||
|
||||
## Возвращает значение поля ячейки.[br]
|
||||
@@ -186,9 +186,9 @@ func set_node_property(i_col: int, i_row: int, pname: String, val) -> void:
|
||||
## [param i_col] - Индекс колонки.[br]
|
||||
## [param i_row] - Индекс ряда.
|
||||
func get_node_property(i_col: int, i_row: int, pname: String):
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
var node = nodes[key]
|
||||
return node.get(pname)
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
var node = nodes[key]
|
||||
return node.get(pname)
|
||||
|
||||
|
||||
## Возвращает ключ для существующей ячейки. Если ячейки с заданными индексами нет,
|
||||
@@ -196,313 +196,313 @@ func get_node_property(i_col: int, i_row: int, pname: String):
|
||||
## [param i_col] - Индекс колонки.[br]
|
||||
## [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])
|
||||
return key
|
||||
var key: String = format % [i_row, i_col]
|
||||
assert(nodes.has(key), 'ошибка: нет такой ячейки - колонка:%d ряд:%d' % [i_col, i_row])
|
||||
return key
|
||||
|
||||
|
||||
## Возвращает массив с индексом ячейки:[br]
|
||||
## [b][0][/b] - индекс колонки,[br]
|
||||
## [b][1][/b] - индекс строки.
|
||||
func get_key_indexes(key: String) -> Array:
|
||||
var tokens: = key.split('_')
|
||||
assert(tokens.size() == 3, 'ошибка: неверный ключ: \"%s\"' % key)
|
||||
return [int(tokens[2]), int(tokens[1])]
|
||||
var tokens: = key.split('_')
|
||||
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()))
|
||||
columns = sizes.size()
|
||||
var rows_count: = get_rows_count()
|
||||
columns_min_size.clear()
|
||||
for sz in sizes:
|
||||
columns_min_size.append(sz)
|
||||
for i_row in rows_count:
|
||||
set_nodes_min_size(i_row, sizes, NODE_KEY_FORMAT)
|
||||
if nodes.has(HEAD_KEY_FORMAT % [0, 0]):
|
||||
set_nodes_min_size(0, sizes, HEAD_KEY_FORMAT)
|
||||
assert((columns == 1) or (columns == sizes.size()))
|
||||
columns = sizes.size()
|
||||
var rows_count: = get_rows_count()
|
||||
columns_min_size.clear()
|
||||
for sz in sizes:
|
||||
columns_min_size.append(sz)
|
||||
for i_row in rows_count:
|
||||
set_nodes_min_size(i_row, sizes, NODE_KEY_FORMAT)
|
||||
if nodes.has(HEAD_KEY_FORMAT % [0, 0]):
|
||||
set_nodes_min_size(0, sizes, HEAD_KEY_FORMAT)
|
||||
|
||||
|
||||
##
|
||||
func set_columns_aligment(alignments: Array) -> void:
|
||||
var rows_count: = get_rows_count()
|
||||
for i_row in rows_count:
|
||||
for i_col in alignments.size():
|
||||
set_node_alligment(i_col, i_row, alignments[i_col])
|
||||
var rows_count: = get_rows_count()
|
||||
for i_row in rows_count:
|
||||
for i_col in alignments.size():
|
||||
set_node_alligment(i_col, i_row, alignments[i_col])
|
||||
|
||||
|
||||
##
|
||||
func _input(event) -> void:
|
||||
if not is_visible_in_tree(): return
|
||||
if event is InputEventKey:
|
||||
if event.pressed and in_focus:
|
||||
if event.keycode == selector_key_up:
|
||||
selector_up()
|
||||
elif event.keycode == selector_key_down:
|
||||
selector_down()
|
||||
elif event is InputEventMouseButton:
|
||||
if not event.pressed:
|
||||
return
|
||||
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')
|
||||
if not is_visible_in_tree(): return
|
||||
if event is InputEventKey:
|
||||
if event.pressed and in_focus:
|
||||
if event.keycode == selector_key_up:
|
||||
selector_up()
|
||||
elif event.keycode == selector_key_down:
|
||||
selector_down()
|
||||
elif event is InputEventMouseButton:
|
||||
if not event.pressed:
|
||||
return
|
||||
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:
|
||||
selector_color_proc = Callable(self, 'defaultselector_color_proc')
|
||||
assert(selector_color_proc.is_valid())
|
||||
selector_size_proc = Callable(self, 'default_selector_size_proc')
|
||||
assert(selector_size_proc.is_valid())
|
||||
scroll = self
|
||||
selector_color_proc = Callable(self, 'defaultselector_color_proc')
|
||||
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))
|
||||
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 setselector_color_proc(instance: Object, function: String) -> void:
|
||||
selector_color_proc = Callable(instance, function)
|
||||
assert(selector_color_proc.is_valid())
|
||||
selector_color_proc = Callable(instance, function)
|
||||
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())
|
||||
selector_size_proc = Callable(instance, function)
|
||||
assert(selector_size_proc.is_valid())
|
||||
|
||||
|
||||
## [param i_row] - Индекс ряда
|
||||
func default_selector_size_proc(i_row: int, rect: Array) -> void:
|
||||
get_row_rect(i_row, rect)
|
||||
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
|
||||
get_row_rect(i_row, rect)
|
||||
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():
|
||||
var rows_count: = get_rows_count()
|
||||
for i_row in rows_count:
|
||||
set_row_selected(i_row, false)
|
||||
var rows_count: = get_rows_count()
|
||||
for i_row in rows_count:
|
||||
set_row_selected(i_row, false)
|
||||
|
||||
|
||||
## [param i_row] - Индекс ряда.
|
||||
func set_row_selected(i_row: int, selected: bool = true) -> void:
|
||||
call_deferred('_set_row_selected', i_row, selected)
|
||||
call_deferred('_set_row_selected', i_row, selected)
|
||||
|
||||
|
||||
## [param i_row] - Индекс ряда.
|
||||
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
|
||||
if nodes.has(selector_key) and (not selected):
|
||||
var node = nodes[node_key]
|
||||
var selector = nodes[selector_key]
|
||||
node.remove_child(selector)
|
||||
selector.queue_free()
|
||||
nodes.erase(selector_key)
|
||||
elif (not nodes.has(selector_key)) and selected:
|
||||
var selector = ScnSelector.instantiate()
|
||||
var rect: = [0, 0, 0, 0]
|
||||
selector_size_proc.call(i_row, rect)
|
||||
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[selector_key] = selector
|
||||
var node = nodes[node_key]
|
||||
node.add_child(selector)
|
||||
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
|
||||
if nodes.has(selector_key) and (not selected):
|
||||
var node = nodes[node_key]
|
||||
var selector = nodes[selector_key]
|
||||
node.remove_child(selector)
|
||||
selector.queue_free()
|
||||
nodes.erase(selector_key)
|
||||
elif (not nodes.has(selector_key)) and selected:
|
||||
var selector = ScnSelector.instantiate()
|
||||
var rect: = [0, 0, 0, 0]
|
||||
selector_size_proc.call(i_row, rect)
|
||||
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[selector_key] = selector
|
||||
var node = nodes[node_key]
|
||||
node.add_child(selector)
|
||||
|
||||
|
||||
## [param i_row] - Индекс ряда.
|
||||
func is_row_selected(i_row: int) -> bool:
|
||||
var key: = SELECTOR_KEY_FORMAT % [i_row, 0]
|
||||
return nodes.has(key)
|
||||
var key: = SELECTOR_KEY_FORMAT % [i_row, 0]
|
||||
return nodes.has(key)
|
||||
|
||||
|
||||
## [param i_row] - Индексы рядов.
|
||||
func get_selected_rows(i_rows: Array) -> void:
|
||||
for key in nodes.keys():
|
||||
if SLCT_PREFIX in key:
|
||||
var indexes = get_key_indexes(key)
|
||||
i_rows.append(indexes[1])
|
||||
for key in nodes.keys():
|
||||
if SLCT_PREFIX in key:
|
||||
var indexes = get_key_indexes(key)
|
||||
i_rows.append(indexes[1])
|
||||
|
||||
|
||||
## Возвращает количество рядов
|
||||
func get_rows_count() -> int:
|
||||
var nodes_count: int = 0
|
||||
for key in nodes:
|
||||
nodes_count += int(NODE_PREFIX in key)
|
||||
return nodes_count / columns
|
||||
var nodes_count: int = 0
|
||||
for key in nodes:
|
||||
nodes_count += int(NODE_PREFIX in key)
|
||||
return nodes_count / columns
|
||||
|
||||
|
||||
## [param i_col] - Индекс колонки. [param i_row] - Индекс ряда.
|
||||
func get_node2(i_col: int, i_row: int) -> Node:
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
return nodes[key]
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
return nodes[key]
|
||||
|
||||
|
||||
## Добавляет ряд. [param row_types] - Массив типов ячеек ряда
|
||||
func add_row(row_types: Array) -> void:
|
||||
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()])
|
||||
var i_row: int = get_rows_count()
|
||||
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\"')
|
||||
var node_key: String = NODE_KEY_FORMAT % [i_row, i_col]
|
||||
node.name = node_key
|
||||
add_child(node)
|
||||
if allow_set_size:
|
||||
node.custom_minimum_size.x = columns_min_size[i_col]
|
||||
node.set_deferred('size.x', columns_min_size[i_col])
|
||||
nodes[node_key] = node
|
||||
var conn = Callable(self, '_on_focus_entered').bind(node)
|
||||
node.connect('focus_entered', conn)
|
||||
set_node_meta(i_col, i_row, 'callable_focus_entered', conn)
|
||||
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()])
|
||||
var i_row: int = get_rows_count()
|
||||
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\"')
|
||||
var node_key: String = NODE_KEY_FORMAT % [i_row, i_col]
|
||||
node.name = node_key
|
||||
add_child(node)
|
||||
if allow_set_size:
|
||||
node.custom_minimum_size.x = columns_min_size[i_col]
|
||||
node.set_deferred('size.x', columns_min_size[i_col])
|
||||
nodes[node_key] = node
|
||||
var conn = Callable(self, '_on_focus_entered').bind(node)
|
||||
node.connect('focus_entered', conn)
|
||||
set_node_meta(i_col, i_row, 'callable_focus_entered', conn)
|
||||
|
||||
|
||||
##
|
||||
func _on_focus_entered(node):
|
||||
var indexes = get_key_indexes(node.name)
|
||||
emit_signal('row_pressed', indexes[1])
|
||||
var indexes = get_key_indexes(node.name)
|
||||
emit_signal('row_pressed', indexes[1])
|
||||
|
||||
|
||||
##
|
||||
func set_header(header_types: Array):
|
||||
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])
|
||||
var do_adj: = false
|
||||
if not header:
|
||||
header = GridContainer.new()
|
||||
var parent = scroll.get_parent()
|
||||
parent.add_child(header)
|
||||
header.position = position
|
||||
header.columns = header_types.size()
|
||||
do_adj = true
|
||||
else:
|
||||
var childrens = header.get_children()
|
||||
for node in childrens:
|
||||
childrens.erase(node.name)
|
||||
childrens.remove_child(node)
|
||||
node.queue_free()
|
||||
for i_col in columns:
|
||||
var node = header_types[i_col].instantiate()
|
||||
var key: String = HEAD_KEY_FORMAT % [0, i_col]
|
||||
node.name = key
|
||||
nodes[key] = node
|
||||
header.add_child(node)
|
||||
if do_adj:
|
||||
var rect = [0, 0, 0, 0]
|
||||
get_node_rect(0, 0, rect, HEAD_KEY_FORMAT)
|
||||
position.y += rect[3]
|
||||
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])
|
||||
var do_adj: = false
|
||||
if not header:
|
||||
header = GridContainer.new()
|
||||
var parent = scroll.get_parent()
|
||||
parent.add_child(header)
|
||||
header.position = position
|
||||
header.columns = header_types.size()
|
||||
do_adj = true
|
||||
else:
|
||||
var childrens = header.get_children()
|
||||
for node in childrens:
|
||||
childrens.erase(node.name)
|
||||
childrens.remove_child(node)
|
||||
node.queue_free()
|
||||
for i_col in columns:
|
||||
var node = header_types[i_col].instantiate()
|
||||
var key: String = HEAD_KEY_FORMAT % [0, i_col]
|
||||
node.name = key
|
||||
nodes[key] = node
|
||||
header.add_child(node)
|
||||
if do_adj:
|
||||
var rect = [0, 0, 0, 0]
|
||||
get_node_rect(0, 0, rect, HEAD_KEY_FORMAT)
|
||||
position.y += rect[3]
|
||||
|
||||
|
||||
##
|
||||
func set_header_text(headers: Array):
|
||||
assert(columns == headers.size())
|
||||
set_row_text(0, headers, 0, HEAD_KEY_FORMAT)
|
||||
assert(columns == headers.size())
|
||||
set_row_text(0, headers, 0, HEAD_KEY_FORMAT)
|
||||
|
||||
|
||||
## [param i_row] - индекс ряда.
|
||||
func remove_row(i_row: int):
|
||||
var sel_key: String = SELECTOR_KEY_FORMAT % [i_row, 0]
|
||||
var sel_key: String = SELECTOR_KEY_FORMAT % [i_row, 0]
|
||||
|
||||
if nodes.has(sel_key):
|
||||
var selector = nodes[sel_key]
|
||||
var prnt = selector.get_parent()
|
||||
prnt.remove_child(selector)
|
||||
selector.queue_free()
|
||||
nodes.erase(sel_key)
|
||||
if nodes.has(sel_key):
|
||||
var selector = nodes[sel_key]
|
||||
var prnt = selector.get_parent()
|
||||
prnt.remove_child(selector)
|
||||
selector.queue_free()
|
||||
nodes.erase(sel_key)
|
||||
|
||||
for i_col in columns:
|
||||
for i_col in columns:
|
||||
|
||||
var node_key: String = NODE_KEY_FORMAT % [i_row, i_col]
|
||||
var node = nodes[node_key]
|
||||
var node_key: String = NODE_KEY_FORMAT % [i_row, i_col]
|
||||
var node = nodes[node_key]
|
||||
|
||||
var conn = get_node_meta(i_col, i_row, 'callable_focus_entered')
|
||||
node.disconnect('focus_entered', conn)
|
||||
var conn = get_node_meta(i_col, i_row, 'callable_focus_entered')
|
||||
node.disconnect('focus_entered', conn)
|
||||
|
||||
if node.has_meta(META_CALLABLE):
|
||||
conn = node.get_meta(META_CALLABLE)
|
||||
var event_name = node.get_meta(META_EVENT_NAME)
|
||||
node.disconnect(event_name, conn)
|
||||
if node.has_meta(META_CALLABLE):
|
||||
conn = node.get_meta(META_CALLABLE)
|
||||
var event_name = node.get_meta(META_EVENT_NAME)
|
||||
node.disconnect(event_name, conn)
|
||||
|
||||
remove_child(node)
|
||||
nodes.erase(node_key)
|
||||
node.queue_free()
|
||||
rehash()
|
||||
remove_child(node)
|
||||
nodes.erase(node_key)
|
||||
node.queue_free()
|
||||
rehash()
|
||||
|
||||
|
||||
##
|
||||
func next_index(indexes: Array) -> void:
|
||||
indexes[0].x += 1
|
||||
if indexes[0].x == columns:
|
||||
indexes[0].x = 0
|
||||
indexes[0].y += 1
|
||||
indexes[0].x += 1
|
||||
if indexes[0].x == columns:
|
||||
indexes[0].x = 0
|
||||
indexes[0].y += 1
|
||||
|
||||
|
||||
##
|
||||
func swap_nodes(nodes_copy, node_key_format, i0, i1) -> void:
|
||||
var key0 = node_key_format % [i0.y, i0.x]
|
||||
var key1 = node_key_format % [i1.y, i1.x]
|
||||
nodes_copy[key1] = nodes[key0]
|
||||
nodes_copy[key1].name = key1
|
||||
var key0 = node_key_format % [i0.y, i0.x]
|
||||
var key1 = node_key_format % [i1.y, i1.x]
|
||||
nodes_copy[key1] = nodes[key0]
|
||||
nodes_copy[key1].name = key1
|
||||
|
||||
|
||||
## Переназначает ключи в соответствии с размерами таблицы.
|
||||
func rehash():
|
||||
var i_node: = [Vector2i()]
|
||||
var i_hdr: = [Vector2i()]
|
||||
var i_slct: = [Vector2i()]
|
||||
var nodes_copy = {}
|
||||
for key in nodes:
|
||||
var iv = get_key_indexes(key)
|
||||
var i0 = Vector2(iv[0], iv[1])
|
||||
if HEAD_PREFIX in key:
|
||||
swap_nodes(nodes_copy, HEAD_KEY_FORMAT, i0, i_hdr[0])
|
||||
next_index(i_hdr)
|
||||
elif NODE_PREFIX in key:
|
||||
swap_nodes(nodes_copy, NODE_KEY_FORMAT, i0, i_node[0])
|
||||
next_index(i_node)
|
||||
elif SLCT_PREFIX in key:
|
||||
swap_nodes(nodes_copy, SELECTOR_KEY_FORMAT, i0, i_slct[0])
|
||||
next_index(i_slct)
|
||||
nodes.clear()
|
||||
nodes.merge(nodes_copy)
|
||||
var i_node: = [Vector2i()]
|
||||
var i_hdr: = [Vector2i()]
|
||||
var i_slct: = [Vector2i()]
|
||||
var nodes_copy = {}
|
||||
for key in nodes:
|
||||
var iv = get_key_indexes(key)
|
||||
var i0 = Vector2(iv[0], iv[1])
|
||||
if HEAD_PREFIX in key:
|
||||
swap_nodes(nodes_copy, HEAD_KEY_FORMAT, i0, i_hdr[0])
|
||||
next_index(i_hdr)
|
||||
elif NODE_PREFIX in key:
|
||||
swap_nodes(nodes_copy, NODE_KEY_FORMAT, i0, i_node[0])
|
||||
next_index(i_node)
|
||||
elif SLCT_PREFIX in key:
|
||||
swap_nodes(nodes_copy, SELECTOR_KEY_FORMAT, i0, i_slct[0])
|
||||
next_index(i_slct)
|
||||
nodes.clear()
|
||||
nodes.merge(nodes_copy)
|
||||
|
||||
|
||||
## Удаляет все строки таблицы
|
||||
func clear_rows() -> void:
|
||||
var rows_count: int = get_rows_count()
|
||||
for i_row in range(rows_count - 1, -1, -1):
|
||||
remove_row(i_row)
|
||||
var rows_count: int = get_rows_count()
|
||||
for i_row in range(rows_count - 1, -1, -1):
|
||||
remove_row(i_row)
|
||||
|
||||
|
||||
## Настраевает обратные вызовы для колонок.[br]
|
||||
@@ -512,57 +512,57 @@ func clear_rows() -> void:
|
||||
## [param clmns] - Индексы колонок[br]
|
||||
## [param user_data] - Аргументы функции получателя события[br]
|
||||
func connect_columns(dest_node: Node, event_name: String, callback: String, clmns: Array, user_data: Array = []) -> void:
|
||||
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)
|
||||
var node = get_node2(i_col, i_row)
|
||||
if node.has_meta(META_CALLABLE):
|
||||
var conn_prev = node.get_meta(META_CALLABLE)
|
||||
node.disconnect(event_name, conn_prev)
|
||||
var conn = Callable(dest_node, callback).bind([node] + user_data)
|
||||
var rc = node.connect(event_name, conn)
|
||||
if rc == Error.OK:
|
||||
node.set_meta(META_CALLABLE, conn)
|
||||
node.set_meta(META_EVENT_NAME, event_name)
|
||||
else:
|
||||
var es = error_string(rc)
|
||||
push_error('ошибка: событие \"%s\" не может быть подключено к %s: %s' % [event_name, node, es])
|
||||
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)
|
||||
var node = get_node2(i_col, i_row)
|
||||
if node.has_meta(META_CALLABLE):
|
||||
var conn_prev = node.get_meta(META_CALLABLE)
|
||||
node.disconnect(event_name, conn_prev)
|
||||
var conn = Callable(dest_node, callback).bind([node] + user_data)
|
||||
var rc = node.connect(event_name, conn)
|
||||
if rc == Error.OK:
|
||||
node.set_meta(META_CALLABLE, conn)
|
||||
node.set_meta(META_EVENT_NAME, event_name)
|
||||
else:
|
||||
var es = error_string(rc)
|
||||
push_error('ошибка: событие \"%s\" не может быть подключено к %s: %s' % [event_name, node, es])
|
||||
|
||||
|
||||
##
|
||||
func set_rows_text(rows: Array) -> void:
|
||||
for i_row in rows.size():
|
||||
for i_col in columns:
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
var node = nodes[key]
|
||||
node.text = rows[i_row][i_col]
|
||||
for i_row in rows.size():
|
||||
for i_col in columns:
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
var node = nodes[key]
|
||||
node.text = rows[i_row][i_col]
|
||||
|
||||
|
||||
## [param i_row] - Индекс ряда.
|
||||
func set_nodes_min_size(i_row: int, sizes: Array, key_format: String = NODE_KEY_FORMAT) -> void:
|
||||
columns_min_size.clear()
|
||||
for sz in sizes:
|
||||
columns_min_size.append(sz)
|
||||
for i_col in columns:
|
||||
var key: = get_node_key(key_format, i_col, i_row)
|
||||
var node = nodes[key]
|
||||
node.custom_minimum_size.x = sizes[i_col]
|
||||
node.set_deferred('size.x', sizes[i_col])
|
||||
columns_min_size.clear()
|
||||
for sz in sizes:
|
||||
columns_min_size.append(sz)
|
||||
for i_col in columns:
|
||||
var key: = get_node_key(key_format, i_col, i_row)
|
||||
var node = nodes[key]
|
||||
node.custom_minimum_size.x = sizes[i_col]
|
||||
node.set_deferred('size.x', sizes[i_col])
|
||||
|
||||
|
||||
## [param i_col] - Индекс колонки.[br][param i_row] - Индекс ряда.
|
||||
func set_node_text(i_col: int, i_row: int, val: String) -> void:
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
nodes[key].text = val
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
nodes[key].text = val
|
||||
|
||||
|
||||
##
|
||||
func set_rows_state(rows: Array) -> void:
|
||||
for i_row in rows.size():
|
||||
for i_col in columns:
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
nodes[key].button_pressed = rows[i_row][i_col]
|
||||
for i_row in rows.size():
|
||||
for i_col in columns:
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
nodes[key].button_pressed = rows[i_row][i_col]
|
||||
|
||||
|
||||
## Устанавливает состояние ячейки.
|
||||
@@ -571,59 +571,59 @@ func set_rows_state(rows: Array) -> void:
|
||||
## [param val] - Новое состояние.[br]
|
||||
## [i]Ячейка должна иметь свойство[/i] [param button_pressed]
|
||||
func set_node_state(i_col: int, i_row: int, val: bool) -> void:
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
nodes[key].button_pressed = val
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
nodes[key].button_pressed = val
|
||||
|
||||
|
||||
## [param i_col] - Индекс колонки.[br]
|
||||
## [param i_row] - Индекс ряда.
|
||||
func set_node_frame(i_col: int, i_row: int, node_name: String, val: int) -> void:
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
var node = nodes[key]
|
||||
var sprite = node.get_node(node_name)
|
||||
sprite.frame = val
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
var node = nodes[key]
|
||||
var sprite = node.get_node(node_name)
|
||||
sprite.frame = val
|
||||
|
||||
|
||||
## Разрешает редактирование ячейки. Ячейка должна иметь свойство [param editable].[br]
|
||||
## [param i_col] - Индекс колонки.[br]
|
||||
## [param i_row] - Индекс ряда.
|
||||
func set_node_editable(i_col: int, i_row: int, val: bool) -> void:
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
nodes[key].editable = val
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
nodes[key].editable = val
|
||||
|
||||
|
||||
## Разрешает редактирование ряда. Ячейки ряда должны иметь свойство [param editable].[br]
|
||||
## [param i_row] - Индекс ряда.
|
||||
func set_row_editable(i_row: int, val: bool) -> void:
|
||||
for i_col in columns:
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
nodes[key].editable = val
|
||||
for i_col in columns:
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
nodes[key].editable = val
|
||||
|
||||
|
||||
## [param i_col] - Индекс колонки.[br]
|
||||
## [param i_row] - Индекс ряда.
|
||||
func set_node_alligment(i_col: int, i_row: int, val: int) -> void:
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
if 'horizontal_alignment' in nodes[key]:
|
||||
nodes[key].horizontal_alignment = val
|
||||
elif 'alignment' in nodes[key]:
|
||||
nodes[key].alignment = val
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
if 'horizontal_alignment' in nodes[key]:
|
||||
nodes[key].horizontal_alignment = val
|
||||
elif 'alignment' in nodes[key]:
|
||||
nodes[key].alignment = val
|
||||
|
||||
|
||||
## [param i_row] - Индекс ряда.
|
||||
func set_row_alligments(i_row: int, aligns: Array) -> void:
|
||||
for i_col in columns:
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
nodes[key].align = aligns[i_col]
|
||||
for i_col in columns:
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
nodes[key].align = aligns[i_col]
|
||||
|
||||
|
||||
## [param i_row] - Индекс ряда.
|
||||
func get_row_text(i_row: int) -> Array:
|
||||
var row: = []
|
||||
for i_col in columns:
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
row.append(nodes[key].text)
|
||||
return row
|
||||
var row: = []
|
||||
for i_col in columns:
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
row.append(nodes[key].text)
|
||||
return row
|
||||
|
||||
|
||||
## Устанавливает текст ячеек ряда.[br]
|
||||
@@ -632,51 +632,51 @@ 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())
|
||||
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]
|
||||
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]
|
||||
|
||||
|
||||
## Возвращает все строки таблицы в двумерном массиве
|
||||
func get_rows_text() -> Array:
|
||||
var rows_count: = get_rows_count()
|
||||
var rows: = []
|
||||
for i_row in rows_count:
|
||||
var row = get_row_text(i_row)
|
||||
rows.append(row)
|
||||
return rows
|
||||
var rows_count: = get_rows_count()
|
||||
var rows: = []
|
||||
for i_row in rows_count:
|
||||
var row = get_row_text(i_row)
|
||||
rows.append(row)
|
||||
return rows
|
||||
|
||||
|
||||
## Возвращает массив ячеек из ряда [param i_row]
|
||||
func get_row(i_row: int) -> Array:
|
||||
var row: = []
|
||||
for i_col in columns:
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
row.append(nodes[key])
|
||||
return row
|
||||
var row: = []
|
||||
for i_col in columns:
|
||||
var key: = get_node_key(NODE_KEY_FORMAT, i_col, i_row)
|
||||
row.append(nodes[key])
|
||||
return row
|
||||
|
||||
|
||||
## Возвращает прямоугольник [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, 'ошибка: мало элементов для возврата результата')
|
||||
var key: = get_node_key(key_format, i_col, i_row)
|
||||
var cell = nodes[key]
|
||||
rect[0] = cell.position.x
|
||||
rect[1] = cell.position.y
|
||||
rect[2] = cell.size.x
|
||||
rect[3] = cell.size.y
|
||||
assert(rect.size() >= 4, 'ошибка: мало элементов для возврата результата')
|
||||
var key: = get_node_key(key_format, i_col, i_row)
|
||||
var cell = nodes[key]
|
||||
rect[0] = cell.position.x
|
||||
rect[1] = cell.position.y
|
||||
rect[2] = cell.size.x
|
||||
rect[3] = cell.size.y
|
||||
|
||||
|
||||
## Возвращает прямоугольник [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, 'ошибка: мало элементов для возврата результата')
|
||||
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
|
||||
rect[1] = cell0.position.y + scroll_adj.y
|
||||
rect[2] = (cell1.position.x - cell0.position.x) + cell1.size.x
|
||||
rect[3] = cell0.size.y
|
||||
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
|
||||
rect[1] = cell0.position.y + scroll_adj.y
|
||||
rect[2] = (cell1.position.x - cell0.position.x) + cell1.size.x
|
||||
rect[3] = cell0.size.y
|
||||
|
||||
Reference in New Issue
Block a user