extends HBoxContainer class_name LogItem #signal save(data:ItemData) signal update(data: ItemData) signal remove const TAG_BTN_GROUP_PREFIX = "tag_btn" @onready var log_content := %LogContent as TextEdit @onready var event_date := %EventDate as Label #@onready var update_date := %LogUpdateDate as Label @onready var tags_container := %TagsContainer as GridContainer @onready var add_tag_btn := %AddTag as MenuButton @onready var reload_btn = %Reload @onready var save_btn = %Save @onready var delete_btn = %Delete var original_data := ItemData.new() var data: ItemData = original_data class ItemData: var item_id := _generate_random_id() var log_content := "": set(new_val): if new_val != log_content: update_date = _get_current_time() log_content = new_val var tags := []: set(new_val): update_date = _get_current_time() tags = new_val var event_date := _get_current_time() var update_date := _get_current_time() func _generate_random_id() -> String: # float time var timestamp := Time.get_unix_time_from_system() return str(int(timestamp * 10000 + randi_range(0, 10000))) func _get_current_time() -> String: # Returns the current date as a dictionary of keys: year, month, day, and weekday. var dict = Time.get_date_dict_from_system() return str(dict["month"]) + "/" + str(dict["day"]) + "/" + str(dict["year"]) func duplicate() -> ItemData: var item := ItemData.new() item.item_id = item_id item.log_content = log_content item.tags = tags.duplicate() item.event_date = event_date item.update_date = update_date return item func to_json_dict() -> Dictionary: # JSON.stringify(self) doesn't work return { "item_id": item_id, "log_content": log_content, "tags": tags, "event_date": event_date, "update_date": update_date, } static func parse(data: Dictionary) -> ItemData: var item := ItemData.new() if data.has("item_id"): item.item_id = data["item_id"] if data.has("tags"): item.tags = data["tags"] if data.has("log_content"): item.log_content = data["log_content"] if data.has("event_date"): item.event_date = data["event_date"] if data.has("update_date"): item.update_date = data["update_date"] return item # {id:{"btn":btn,"key":key,"name":name,"id":id}} static var tag_btns = {} static var tag_key_to_id_map = {} static var tag_shadow_color = Color.html("1b1b1b") static var tag_shadow_outline_size = 1 # id->key var current_tags = {} func _ready(): _load_tag_popup() reload_btn.pressed.connect(_on_reload_pressed) #save_btn.pressed.connect(_save_item) delete_btn.pressed.connect(_remove_signal) log_content.text_changed.connect(_on_log_content_changed) call_deferred("_update_signal") #load_item(original_data) static func _static_init(): var tag_id := 0 for tag_type in ProjectLogPanel.TAG_TYPE.values(): var tag_color = ProjectLogPanel.TAG_TYPE_COLOR_DICT[tag_type] for tag in ProjectLogPanel.TAG_DICT[tag_type]: var tag_btn = Button.new() as Button tag_btn.add_theme_color_override("font_color", tag_color) tag_btn.add_theme_color_override("font_shadow_color", tag_shadow_color) tag_btn.add_theme_constant_override("shadow_outline_size", tag_shadow_outline_size) tag_btn.text = tag var tag_key = _get_tag_key(tag_type, tag) tag_btns[tag_id] = {"btn": tag_btn, "id": tag_id, "name": tag, "key": tag_key} tag_key_to_id_map[tag_key] = tag_id tag_id += 1 static func _get_tag_key(tag_type: ProjectLogPanel.TAG_TYPE, tag: String): return str(tag_type) + "@" + tag func _load_tag_popup(): var popup = add_tag_btn.get_popup() as PopupMenu for btn_dict in tag_btns.values(): popup.add_item(btn_dict["name"], btn_dict["id"]) popup.id_pressed.connect(_on_popup_menu_pressed) func _reload_tag_btns(): var btn_group = TAG_BTN_GROUP_PREFIX + data.item_id get_tree().call_group(btn_group, "queue_free") current_tags.clear() for tag_key in data["tags"]: if !tag_key_to_id_map.has(tag_key): push_error("tag_key has been removed!! tag_key=", tag_key) continue var tag_id = tag_key_to_id_map[tag_key] current_tags[tag_id] = tag_key var btn = (tag_btns[tag_id]["btn"] as Button).duplicate() btn.pressed.connect(_on_tag_btn_pressed.bind(btn, tag_id)) btn.add_to_group(btn_group) tags_container.add_child(btn) func load_item(new_data: Dictionary): if new_data.keys().size() != 0: original_data = ItemData.parse(new_data) _reload_original_data() func _reload_original_data(): data = original_data.duplicate() #print("_load_item_data data=", data) log_content.text = data.log_content event_date.text = data.event_date #update_date.text = data["update_date"] _reload_tag_btns() func _on_popup_menu_pressed(id: int): #{"btn":btn,"key":key,"name":name,"id":id} if !current_tags.has(id): current_tags[id] = tag_btns[id]["key"] data.tags = current_tags.values() _update_signal() #_save_item() _reload_tag_btns() func _on_log_content_changed(): data["log_content"] = log_content.text _update_signal() func _on_tag_btn_pressed(btn: Control, id: int): current_tags.erase(id) btn.queue_free() data.tags = current_tags.values() _update_signal() #_save_item() #func _save_item(): #save.emit(data) func _update_signal(): update.emit(data) func _remove_signal(): remove.emit() func _on_reload_pressed(): _reload_original_data() _update_signal()