import dearpygui.dearpygui as dpg import numpy as np import threading from constants import * def get_current_ui_type(): for child in dpg.get_item_children('ui', 1): if dpg.get_value(child): return dpg.get_item_alias(child) def get_current_theme(): for child in dpg.get_item_children('theme', 1): if dpg.get_value(child): return dpg.get_item_alias(child) def get_config_file_path(): return dpg.get_item_user_data('main')['config_file_path'] def get_config(): return dpg.get_item_user_data('main')['config'] def set_main_window_value(key, value): data = dpg.get_item_user_data('main') data[key] = value dpg.set_item_user_data('main', data) def get_height_map_path(): return dpg.get_item_user_data('map_window')['height_map_file_path'] def get_height_map(): return dpg.get_item_user_data('map_window')['height_map'] def is_drawing(): return dpg.get_item_user_data('map_window')['drawing'] def get_prev_coords(): return dpg.get_item_user_data('map_window')['prev_coords'] def get_current_action(): return dpg.get_item_user_data('map_window')['current_action'] def set_map_window_value(key, value): data = dpg.get_item_user_data('map_window') data[key] = value dpg.set_item_user_data('map_window', data) def show_status_text(message): dpg.set_item_pos('status_text', (dpg.get_item_width('main') - dpg.get_text_size(message)[0] - 2 * SPACE, dpg.get_item_pos('status_text')[1])) dpg.set_value('status_text', message) def path_iter(path, prefix=""): namespaces = path.split('.') for i in range(len(namespaces)): yield prefix + '.' + '.'.join(namespaces[:i+1]) def delete_item_and_clear_alias(item): alias = dpg.get_item_alias(item) if alias: dpg.remove_alias(alias) if dpg.does_item_exist(item): dpg.delete_item(item) def delete_item_children_and_clear_aliases_(item): if dpg.does_item_exist(item): for child in dpg.get_item_children(item, 1): delete_item_children_and_clear_aliases_(child) delete_item_and_clear_alias(child) def delete_item_children_and_clear_aliases(): if len(dpg.get_item_children('main', 1)) > 1: delete_item_children_and_clear_aliases_(dpg.get_item_children('main', 1)[1]) delete_item_and_clear_alias(dpg.get_item_children('main', 1)[1]) #################################################################################### # # search utils # #################################################################################### def change_color_temporarily(text_tag, color, duration=1): color = list(color)[:-1] + [255] dpg.configure_item(text_tag, color=color) threading.Timer(duration, lambda: revert_color(text_tag)).start() def revert_color(text_tag): dpg.configure_item(text_tag, color=(255, 255, 255, 255)) #################################################################################### # # edit map utils # #################################################################################### def update_texture(height_map): max_height = np.max(height_map) normalized_map = height_map / max_height texture_data = normalized_map.flatten() texture_data = np.tile(texture_data, (4, 1)).T.flatten() texture_data.resize(800 * 800 * 4) width, height = height_map.shape dpg.set_value('heatmap_texture', texture_data) def check_coords(x, y, w, h): mx, my = dpg.get_item_pos('map') mw, mh = dpg.get_item_width('map'), dpg.get_item_height('map') return mx <= x <= x + w <= mx + mw and my <= y <= y + h <= my + mh def apply_tint(color, tint=(0, 119, 200)): tint = np.array(tint) / 255 color = np.array(color) / 255 color *= tint return list(map(int, (color * 255))) def adjust_coords(coords): x, y = coords return int(x - dpg.get_item_pos('map')[0] + dpg.get_x_scroll('map_window')), int(y - dpg.get_item_pos('map')[1] + dpg.get_text_size('edit map')[1] + 2 * SPACE + dpg.get_y_scroll('map_window')) def get_rect(cur_pos, end_pos): x1, y1 = adjust_coords(cur_pos) x2, y2 = adjust_coords(end_pos) if y2 < y1: y1, y2 = y2, y1 if x2 < x1: x1, x2 = x2, x1 return y1, y2, x1, x2 def load_height_map(file_path): with open(file_path, "r") as file: lines = file.readlines()[1:] height_map = [list(map(int, line.strip().split())) for line in lines] return np.array(height_map) def dump_map(height_map, file_path): with open(file_path, "w", encoding="utf-8") as file: w, h = height_map.shape file.write(f"{w} {h}\n") for row in height_map: file.write(" ".join(list(map(str, row))) + "\n") #################################################################################### # # main menu utils # #################################################################################### def combo_menu(callback): def func(s, a, u): for child in dpg.get_item_children(dpg.get_item_parent(s), 1): if dpg.get_item_alias(child) != dpg.get_item_alias(s): dpg.set_value(child, False) else: dpg.set_value(child, True) dpg.set_item_user_data(s, dpg.get_item_alias(s)) callback(s, a, u) return func #################################################################################### # # tabs ui utils # #################################################################################### def does_tab_bar_child_exist(item): for uuid in dpg.get_item_children(item, 1): if dpg.get_item_type(uuid) == "mvAppItemType::mvTabBar": return True, uuid return False, None def get_absolute_y(item): y = dpg.get_item_pos(item)[1] parent = dpg.get_item_parent(item) while parent: if dpg.get_item_type(parent) == 'mvAppItemType::mvChildWindow': y += dpg.get_item_pos(parent)[1] parent = dpg.get_item_parent(parent) return y def get_item_level(item): level = 0 parent = dpg.get_item_parent(item) while parent: if dpg.get_item_type(parent) == 'mvAppItemType::mvTabBar': level += 1 parent = dpg.get_item_parent(parent) return level def change_height(item): if not dpg.does_item_exist(item): return if dpg.get_item_type(item) == 'mvAppItemType::mvChildWindow': uuid = dpg.get_item_parent(item) new_height = dpg.get_viewport_client_height() - get_absolute_y(uuid) - SPACE * get_item_level(item) dpg.set_item_height(item, max(new_height, dpg.get_item_user_data(item))) for child in dpg.get_item_children(item, 1): change_height(child)