From e2fbe19d8499a625b5c62504e9cbbbf090982b03 Mon Sep 17 00:00:00 2001 From: Tot Maxim Date: Thu, 18 Dec 2025 22:33:11 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BB=D0=BE=D0=B3=20=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D0=B4=D0=B6=D0=B5=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.tscn | 110 +++++++--- ....gdshader => main_radial_gradient.gdshader | 0 ...r.uid => main_radial_gradient.gdshader.uid | 0 project.godot | 5 - sockets/ems_g/емс_г_в.gd | 1 - sockets/ems_g/емс_г_к.gd | 1 - sockets/ems_g/емс_г_н.gd | 1 - udp_broadcast.gd | 1 + журнал.gd | 191 ++++++++++++++++++ журнал.gd.uid | 1 + 10 files changed, 280 insertions(+), 31 deletions(-) rename main_ragial_gradient.gdshader => main_radial_gradient.gdshader (100%) rename main_ragial_gradient.gdshader.uid => main_radial_gradient.gdshader.uid (100%) create mode 100644 журнал.gd create mode 100644 журнал.gd.uid diff --git a/main.tscn b/main.tscn index 1fc8da1..eef1886 100644 --- a/main.tscn +++ b/main.tscn @@ -1,23 +1,30 @@ -[gd_scene load_steps=14 format=3 uid="uid://bxorauom63ib6"] +[gd_scene load_steps=16 format=3 uid="uid://bxorauom63ib6"] [ext_resource type="Script" uid="uid://d1qwoxkckvdbc" path="res://main.gd" id="1_ig7tw"] [ext_resource type="PackedScene" uid="uid://2rjgbflmbi7e" path="res://sockets/ems_g/емс-г-Н.tscn" id="2_0xm2m"] -[ext_resource type="Shader" uid="uid://cp2p2g3mgxm8o" path="res://main_ragial_gradient.gdshader" id="2_272bh"] +[ext_resource type="Shader" uid="uid://cp2p2g3mgxm8o" path="res://main_radial_gradient.gdshader" id="2_272bh"] [ext_resource type="Script" uid="uid://b3hcliukdo2wm" path="res://sockets/ems_g/емс_г_н.gd" id="3_1bvp3"] [ext_resource type="PackedScene" uid="uid://bhh0m5tbxjfmy" path="res://sockets/ems_g/емс-г-В.tscn" id="3_lquwl"] [ext_resource type="PackedScene" uid="uid://pq47qp2lye4o" path="res://sockets/ems_g/емс-г-К.tscn" id="4_1bvp3"] +[ext_resource type="Script" uid="uid://bwll70u61ocw6" path="res://журнал.gd" id="5_5vw27"] [ext_resource type="Script" uid="uid://cgtvbvw1xfqay" path="res://sockets/ems_g/емс_г_в.gd" id="5_lquwl"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_5vw27"] shader = ExtResource("2_272bh") shader_parameter/outerRadius = 4.405 shader_parameter/MainAlpha = 0.88 -shader_parameter/circle_color = Color(0.900141, 0.363478, 0.296518, 1) -shader_parameter/circle_color2 = Color(0.192389, 0.0130258, 0.00462306, 1) +shader_parameter/circle_color = Color(0.890196, 0.94902, 0.992157, 1) +shader_parameter/circle_color2 = Color(0.733333, 0.870588, 0.984314, 1) [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_kek77"] bg_color = Color(0.678977, 0.102543, 0.388891, 1) +[sub_resource type="Theme" id="Theme_272bh"] +CheckButton/colors/font_focus_color = Color(0, 0, 0, 1) +CheckButton/colors/font_hover_color = Color(0, 0, 0, 1) +CheckButton/colors/font_hover_pressed_color = Color(0, 0, 0, 1) +CheckButton/colors/font_pressed_color = Color(0, 0, 0, 1) + [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_0xm2m"] bg_color = Color(0.1167, 0.351514, 0.35159, 1) @@ -51,114 +58,151 @@ offset_left = 32.0 offset_top = 24.0 offset_right = 140.0 offset_bottom = 440.0 +theme = SubResource("Theme_272bh") columns = 2 [node name="CheckButton" type="CheckButton" parent="Yau-07-addr" groups=["device-addr"]] layout_mode = 2 +focus_mode = 0 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "ПРД-Н1" metadata/device = "ПРД-Н1" [node name="Label" type="Label" parent="Yau-07-addr"] layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "10.1.1.11" [node name="CheckButton2" type="CheckButton" parent="Yau-07-addr" groups=["device-addr"]] layout_mode = 2 +focus_mode = 0 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "ПРД-В1" metadata/device = "ПРД-В1" [node name="Label2" type="Label" parent="Yau-07-addr"] layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "10.1.1.12" [node name="CheckButton3" type="CheckButton" parent="Yau-07-addr" groups=["device-addr"]] layout_mode = 2 +focus_mode = 0 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "ПРД-К1" metadata/device = "ПРД-К1" [node name="Label3" type="Label" parent="Yau-07-addr"] layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "10.1.1.13" [node name="CheckButton4" type="CheckButton" parent="Yau-07-addr" groups=["device-addr"]] layout_mode = 2 +focus_mode = 0 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "ПРД-Н2" metadata/device = "ПРД-Н2" [node name="Label4" type="Label" parent="Yau-07-addr"] layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "10.1.1.21" [node name="CheckButton5" type="CheckButton" parent="Yau-07-addr" groups=["device-addr"]] layout_mode = 2 +focus_mode = 0 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "ПРД-В2" metadata/device = "ПРД-В2" [node name="Label5" type="Label" parent="Yau-07-addr"] layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "10.1.1.22" [node name="CheckButton6" type="CheckButton" parent="Yau-07-addr" groups=["device-addr"]] layout_mode = 2 +focus_mode = 0 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "ПРД-К2" metadata/device = "ПРД-К2" [node name="Label6" type="Label" parent="Yau-07-addr"] layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "10.1.1.23" [node name="CheckButton7" type="CheckButton" parent="Yau-07-addr" groups=["device-addr"]] layout_mode = 2 +focus_mode = 0 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "ПРД-Н3" metadata/device = "ПРД-Н3" [node name="Label7" type="Label" parent="Yau-07-addr"] layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "10.1.1.31" [node name="CheckButton8" type="CheckButton" parent="Yau-07-addr" groups=["device-addr"]] layout_mode = 2 +focus_mode = 0 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "ПРД-В3" metadata/device = "ПРД-В3" [node name="Label8" type="Label" parent="Yau-07-addr"] layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "10.1.1.32" [node name="CheckButton9" type="CheckButton" parent="Yau-07-addr" groups=["device-addr"]] layout_mode = 2 +focus_mode = 0 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "ПРД-К3" metadata/device = "ПРД-К3" [node name="Label9" type="Label" parent="Yau-07-addr"] layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "10.1.1.33" [node name="CheckButton10" type="CheckButton" parent="Yau-07-addr" groups=["device-addr"]] layout_mode = 2 +focus_mode = 0 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "ПРД-Н4" metadata/device = "ПРД-Н4" [node name="Label10" type="Label" parent="Yau-07-addr"] layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "10.1.1.41" [node name="CheckButton11" type="CheckButton" parent="Yau-07-addr" groups=["device-addr"]] layout_mode = 2 +focus_mode = 0 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "ПРД-В4" metadata/device = "ПРД-В4" [node name="Label11" type="Label" parent="Yau-07-addr"] layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "10.1.1.42" [node name="CheckButton12" type="CheckButton" parent="Yau-07-addr" groups=["device-addr"]] layout_mode = 2 +focus_mode = 0 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "ПРД-К4" metadata/device = "ПРД-К4" [node name="Label12" type="Label" parent="Yau-07-addr"] layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "10.1.1.43" [node name="TabContainer" type="TabContainer" parent="."] @@ -215,12 +259,31 @@ text = "Загрузка ЭМС" metadata/bit = 4 metadata/device = "ПРД-Н1" +[node name="dkm" type="GridContainer" parent="TabContainer/ПРД-Н1"] +layout_mode = 0 +offset_left = 19.0 +offset_top = 206.0 +offset_right = 97.0 +offset_bottom = 272.0 + +[node name="CheckBox" type="CheckBox" parent="TabContainer/ПРД-Н1/dkm" groups=["dkm"]] +layout_mode = 2 +text = "ДКМ 2" +metadata/bit = 1 +metadata/device = "ПРД-Н1" + +[node name="CheckBox2" type="CheckBox" parent="TabContainer/ПРД-Н1/dkm" groups=["dkm"]] +layout_mode = 2 +text = "ДКМ 3" +metadata/bit = 2 +metadata/device = "ПРД-Н1" + [node name="SocketsBar" type="TabContainer" parent="TabContainer/ПРД-Н1"] layout_mode = 0 offset_left = 199.0 offset_right = 1296.0 offset_bottom = 752.0 -current_tab = 2 +current_tab = 3 tabs_position = 1 tab_focus_mode = 0 @@ -433,6 +496,7 @@ metadata/device = "ПРД-Н1" metadata/place = 13 [node name="УГ" type="GridContainer" parent="TabContainer/ПРД-Н1/SocketsBar"] +visible = false layout_mode = 2 columns = 5 metadata/_tab_index = 2 @@ -669,29 +733,15 @@ metadata/bit = 7 metadata/device = "ПРД-Н1" [node name="ЕМС-Г" parent="TabContainer/ПРД-Н1/SocketsBar" groups=["ems_g"] instance=ExtResource("2_0xm2m")] -visible = false layout_mode = 2 script = ExtResource("3_1bvp3") metadata/device = "ПРД-Н1" -[node name="dkm" type="GridContainer" parent="TabContainer/ПРД-Н1"] -layout_mode = 0 -offset_left = 19.0 -offset_top = 206.0 -offset_right = 97.0 -offset_bottom = 272.0 - -[node name="CheckBox" type="CheckBox" parent="TabContainer/ПРД-Н1/dkm" groups=["dkm"]] +[node name="Журнал" type="RichTextLabel" parent="TabContainer/ПРД-Н1/SocketsBar"] +visible = false layout_mode = 2 -text = "ДКМ 2" -metadata/bit = 1 -metadata/device = "ПРД-Н1" - -[node name="CheckBox2" type="CheckBox" parent="TabContainer/ПРД-Н1/dkm" groups=["dkm"]] -layout_mode = 2 -text = "ДКМ 3" -metadata/bit = 2 -metadata/device = "ПРД-Н1" +script = ExtResource("5_5vw27") +metadata/_tab_index = 4 [node name="ПРД-В1" type="Panel" parent="TabContainer" groups=["prd"]] visible = false @@ -2224,6 +2274,12 @@ offset_left = 64.0 offset_top = 480.0 offset_right = 140.0 offset_bottom = 511.0 +focus_mode = 0 +theme_override_colors/font_hover_pressed_color = Color(0, 0, 0, 1) +theme_override_colors/font_hover_color = Color(0, 0, 0, 1) +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_colors/font_focus_color = Color(0, 0, 0, 1) +theme_override_colors/font_pressed_color = Color(0, 0, 0, 1) text = "УФ " metadata/device = "УФ" @@ -2233,6 +2289,7 @@ offset_left = 80.0 offset_top = 3.0 offset_right = 149.0 offset_bottom = 26.0 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "10.1.1.52" [node name="GridContainer" type="GridContainer" parent="."] @@ -2244,35 +2301,42 @@ offset_bottom = 761.0 [node name="CheckBox" type="CheckBox" parent="GridContainer" groups=["uf_status"]] layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "КЭМС-Б1" metadata/bit = 0 [node name="CheckBox2" type="CheckBox" parent="GridContainer" groups=["uf_status"]] layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "ЭМС-Б" metadata/bit = 1 [node name="CheckBox3" type="CheckBox" parent="GridContainer" groups=["uf_status"]] layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "ЭМС-Б" metadata/bit = 2 [node name="CheckBox4" type="CheckBox" parent="GridContainer" groups=["uf_status"]] layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "КЭМС-Б1 load" metadata/bit = 3 [node name="CheckBox5" type="CheckBox" parent="GridContainer" groups=["uf_status"]] layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "ЭМС-Б load" metadata/bit = 4 [node name="CheckBox6" type="CheckBox" parent="GridContainer" groups=["uf_status"]] layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "ЭМС-Б load" metadata/bit = 5 [node name="CheckBox7" type="CheckBox" parent="GridContainer" groups=["uf_status"]] layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) text = "ИП220-27Б" metadata/bit = 6 diff --git a/main_ragial_gradient.gdshader b/main_radial_gradient.gdshader similarity index 100% rename from main_ragial_gradient.gdshader rename to main_radial_gradient.gdshader diff --git a/main_ragial_gradient.gdshader.uid b/main_radial_gradient.gdshader.uid similarity index 100% rename from main_ragial_gradient.gdshader.uid rename to main_radial_gradient.gdshader.uid diff --git a/project.godot b/project.godot index 8b70b14..74bd9b8 100644 --- a/project.godot +++ b/project.godot @@ -19,8 +19,3 @@ config/icon="res://icon.svg" window/size/viewport_width=1500 window/size/viewport_height=850 - -[rendering] - -renderer/rendering_method="gl_compatibility" -renderer/rendering_method.mobile="gl_compatibility" diff --git a/sockets/ems_g/емс_г_в.gd b/sockets/ems_g/емс_г_в.gd index fa8b833..6efa960 100644 --- a/sockets/ems_g/емс_г_в.gd +++ b/sockets/ems_g/емс_г_в.gd @@ -19,7 +19,6 @@ signal bits_changed(input_impulse: int, input_const: int, output_impulse: int, o #endregion func _ready(): - print(get_meta('device')) _setup_connections() diff --git a/sockets/ems_g/емс_г_к.gd b/sockets/ems_g/емс_г_к.gd index 33aab97..58c4c88 100644 --- a/sockets/ems_g/емс_г_к.gd +++ b/sockets/ems_g/емс_г_к.gd @@ -19,7 +19,6 @@ signal bits_changed(input_impulse: int, input_const: int, output_impulse: int, o #endregion func _ready(): - print(get_meta('device')) _setup_connections() diff --git a/sockets/ems_g/емс_г_н.gd b/sockets/ems_g/емс_г_н.gd index dd1f5e1..5e025a5 100644 --- a/sockets/ems_g/емс_г_н.gd +++ b/sockets/ems_g/емс_г_н.gd @@ -19,7 +19,6 @@ signal bits_changed(input_impulse: int, input_const: int, output_impulse: int, o #endregion func _ready(): - print(get_meta('device')) _setup_connections() diff --git a/udp_broadcast.gd b/udp_broadcast.gd index d057f59..bb7fc94 100644 --- a/udp_broadcast.gd +++ b/udp_broadcast.gd @@ -39,6 +39,7 @@ const BROADCAST_ADDR: Array = [50000, '10.1.1.255'] # Приватные свойства var status_manager: StatusManager +var logs_manager: LogsRich var _socket: SocketUDP var _self_name: String var _isa_ports: Dictionary = {} diff --git a/журнал.gd b/журнал.gd new file mode 100644 index 0000000..0f19e31 --- /dev/null +++ b/журнал.gd @@ -0,0 +1,191 @@ +class_name LogsRich +extends RichTextLabel + +var _log_text: String = "": + set(value): + _log_text = value + text = _log_text + scroll_to_line(get_line_count()) + get: + return _log_text + +enum LogLevel { + INFO, + WARNING, + ERROR, + DEBUG +} + +var _level_colors: Dictionary = { + LogLevel.INFO: Color.WHITE, + LogLevel.WARNING: Color.YELLOW, + LogLevel.ERROR: Color.RED, + LogLevel.DEBUG: Color.CYAN +} + +var _level_prefixes: Dictionary = { + LogLevel.INFO: "[INFO]", + LogLevel.WARNING: "[WARNING]", + LogLevel.ERROR: "[ERROR]", + LogLevel.DEBUG: "[DEBUG]" +} + +var max_lines: int = 1000 + +func _ready(): + scroll_active = true + scroll_following = true + bbcode_enabled = true + + # Добавляем моноширинный шрифт для лучшего отображения логов + var font = get_theme_font("normal_font") + if font: + add_theme_font_override("normal_font", font.duplicate()) + + clear_logs() + +func add_log(message: String, level: LogLevel = LogLevel.INFO) -> void: + var timestamp = Time.get_time_string_from_system() + var prefix = _level_prefixes.get(level, "[INFO]") + var color = _level_colors.get(level, Color.WHITE) + + var formatted_message = "[%s] %s %s" % [timestamp, prefix, message] + + # Используем BBcode для цветного текста + # Важно: to_html() возвращает цвет без #, нужно добавить + var color_hex = color.to_html() + append_text("[color=#%s]%s[/color]\n" % [color_hex, formatted_message]) + + # Обновляем приватную переменную + _log_text = text + + # Ограничиваем количество строк + limit_line_count() + + # Прокручиваем к последней строке + scroll_to_line(get_line_count()) + +func info(message: String) -> void: + add_log(message, LogLevel.INFO) + +func warning(message: String) -> void: + add_log(message, LogLevel.WARNING) + +func error(message: String) -> void: + add_log(message, LogLevel.ERROR) + +func debug(message: String) -> void: + add_log(message, LogLevel.DEBUG) + +func clear_logs() -> void: + clear() + text = "" + _log_text = "" + +func limit_line_count() -> void: + var lines = get_parsed_text().split("\n") + if lines.size() > max_lines: + # Удаляем старые строки + var _new_lines = lines.slice(lines.size() - max_lines) + + # Очищаем и перестраиваем текст с сохранением форматирования + clear() + text = "" + + # Нужно переформатировать все строки снова + # Это сложно сделать правильно без хранения дополнительной информации о цветах + # Поэтому лучше использовать альтернативный подход: + + # Просто обрезаем raw текст + var current_text = get_parsed_text() + var all_lines = current_text.split("\n") + if all_lines.size() > max_lines: + var trimmed_lines = all_lines.slice(all_lines.size() - max_lines) + clear() + text = "\n".join(trimmed_lines) + _log_text = text + +# Альтернативная, более простая реализация limit_line_count +func limit_line_count_simple() -> void: + # Получаем сырой текст без BBcode тегов + var raw_text = get_parsed_text() + var lines = raw_text.split("\n") + + if lines.size() > max_lines: + # Удаляем первые строки сверх лимита + clear() + text = "" + + # Начинаем с индекса, где превышен лимит + var start_index = lines.size() - max_lines + for i in range(start_index, lines.size()): + # Здесь нужно определить уровень логирования для каждой строки + # Это сложно без хранения дополнительной информации + # Поэтому просто добавляем как INFO + var line = lines[i].strip_edges() + if line.length() > 0: + append_text("[color=#ffffff]%s[/color]\n" % line) + + _log_text = text + +# Лучший подход: хранить логи в массиве и перерисовывать при необходимости +var _log_entries: Array = [] # Каждая запись: {message: String, level: LogLevel, timestamp: String} + +func add_log_advanced(message: String, level: LogLevel = LogLevel.INFO) -> void: + var timestamp = Time.get_time_string_from_system() + var entry = { + "message": message, + "level": level, + "timestamp": timestamp + } + + _log_entries.append(entry) + + # Ограничиваем количество записей + if _log_entries.size() > max_lines: + _log_entries.pop_front() + + # Перерисовываем все логи + redraw_logs() + +func redraw_logs() -> void: + clear() + text = "" + + for entry in _log_entries: + var prefix = _level_prefixes.get(entry.level, "[INFO]") + var color = _level_colors.get(entry.level, Color.WHITE) + var formatted_message = "[%s] %s %s" % [entry.timestamp, prefix, entry.message] + var color_hex = color.to_html() + append_text("[color=#%s]%s[/color]\n" % [color_hex, formatted_message]) + + _log_text = text + scroll_to_line(get_line_count()) + +# Метод для сохранения логов в файл +func save_logs_to_file(path: String = "user://logs.txt") -> void: + var file = FileAccess.open(path, FileAccess.WRITE) + if file: + file.store_string(get_parsed_text()) + file.close() + info("Logs saved to: %s" % path) + else: + error("Failed to save logs to: %s" % path) + +# Метод для фильтрации логов по уровню +func filter_logs_by_level(min_level: LogLevel) -> void: + if _log_entries.is_empty(): + return + + clear() + text = "" + + for entry in _log_entries: + if entry.level >= min_level: + var prefix = _level_prefixes.get(entry.level, "[INFO]") + var color = _level_colors.get(entry.level, Color.WHITE) + var formatted_message = "[%s] %s %s" % [entry.timestamp, prefix, entry.message] + var color_hex = color.to_html() + append_text("[color=#%s]%s[/color]\n" % [color_hex, formatted_message]) + + _log_text = text diff --git a/журнал.gd.uid b/журнал.gd.uid new file mode 100644 index 0000000..e5a76a8 --- /dev/null +++ b/журнал.gd.uid @@ -0,0 +1 @@ +uid://bwll70u61ocw6