├── .github └── FUNDING.yml ├── .gitignore ├── DefaultPythonSource └── TA │ └── TAPython │ ├── Config │ └── config.ini │ ├── Python │ ├── ChameleonGallery │ │ ├── ChameleonGallery.json │ │ ├── ChameleonGallery.py │ │ ├── Images │ │ │ ├── ChameleonLogo_b.png │ │ │ ├── ChameleonLogo_c.png │ │ │ └── cartoon_game_map.png │ │ ├── __init__.py │ │ ├── auto_gen │ │ │ ├── border_brushes_Gallery.json │ │ │ ├── box_brushes_Gallery.json │ │ │ ├── button_style_Gallery.json │ │ │ ├── check_box_style_Gallery.json │ │ │ ├── editable_text_box_style_Gallery.json │ │ │ ├── fonts_Gallery.json │ │ │ ├── image_brushes_Gallery.json │ │ │ ├── link_Styles_Gallery.json │ │ │ ├── richtext_editor_style.json │ │ │ ├── slate_color_brushes_Gallery.json │ │ │ └── text_block_styles_Gallery.json │ │ └── example_modal_window.json │ ├── ChameleonSketch │ │ ├── ChameleonSketch.json │ │ ├── ChameleonSketch.py │ │ └── __init__.py │ ├── Example │ │ ├── Example.py │ │ ├── MinimalAsyncTaskExample.json │ │ ├── MinimalAsyncTaskExample.py │ │ ├── MinimalExample.json │ │ ├── MinimalExample.py │ │ └── __init__.py │ ├── ImageCompareTools │ │ ├── ComparisonWidget.json │ │ ├── ImageCompare.json │ │ ├── ImageCompare.py │ │ └── __init__.py │ ├── QueryTools │ │ ├── ObjectDetailViewer.json │ │ ├── ObjectDetailViewer.py │ │ ├── Utils.py │ │ ├── __init__.py │ │ └── queryTools.py │ ├── ShelfTools │ │ ├── Images │ │ │ ├── DropHere.png │ │ │ ├── LitSphere_40x.png │ │ │ ├── Primitive_40x.png │ │ │ ├── PythonChameleonGreyIcon_40x.png │ │ │ ├── PythonTextGreyIcon_40x.png │ │ │ └── folderIcon.png │ │ ├── Shelf.json │ │ ├── Shelf.py │ │ └── __init__.py │ └── Utilities │ │ ├── ChameleonTaskExecutor.py │ │ ├── DisUnrealStub.py │ │ ├── Utils.py │ │ └── __init__.py │ └── UI │ ├── HotkeyConfig.json │ └── MenuConfig.json ├── Images ├── 001_tools_preview_small.png ├── 002_python_plugin_tiltle.png ├── 021_tapython_plugin_title.png └── G000_SketchEditing.gif ├── LICENSE └── README.md /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [] 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Config/config.ini: -------------------------------------------------------------------------------- 1 | [Settings] 2 | MenuConfigFilePath=TA/TAPython/UI/MenuConfig.json 3 | ChameleonDataFolder=/Game/TA/ChameleonTools 4 | PythonContentFolder=TA/TAPython/Python 5 | 6 | [Advanced] 7 | MainbarExtensionHookName=Play 8 | MenusOnToolbarEnabled=True 9 | SketchToolsEnabled=True 10 | MainMenuExtensionHookName=Instrumentation 11 | LogCreateWidget=False 12 | SButtonHorizontalPadding=0 13 | LogOnTickWarnings=False 14 | MaterialEditorMenuExtensionHookName=Instrumentation 15 | LogNumberLimit=10240 16 | DynamicDataLimit=1024 17 | 18 | -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ChameleonGallery/ChameleonGallery.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import os 3 | import sys 4 | import subprocess 5 | import unreal 6 | from Utilities.Utils import Singleton 7 | import random 8 | import re 9 | 10 | if sys.platform == "darwin": 11 | import webbrowser 12 | 13 | 14 | class ChameleonGallery(metaclass=Singleton): 15 | def __init__(self, jsonPath): 16 | self.jsonPath = jsonPath 17 | self.data = unreal.PythonBPLib.get_chameleon_data(self.jsonPath) 18 | self.ui_scrollbox = "ScrollBox" 19 | self.ui_crumbname = "SBreadcrumbTrailA" 20 | self.ui_image = "SImageA" 21 | self.ui_image_local = "SImage_ImageFromRelativePath" 22 | self.ui_imageB = "SImage_ImageFromPath" 23 | self.ui_progressBar = "ProgressBarA" 24 | self.ui_drop_target_text_box = "DropResultBox" 25 | self.ui_python_not_ready = "IsPythonReadyImg" 26 | self.ui_python_is_ready = "IsPythonReadyImgB" 27 | self.ui_is_python_ready_text = "IsPythonReadyText" 28 | self.ui_details_view = "DetailsView" 29 | self.ui_color_block = "ColorBlock" 30 | self.ui_button_expand_color_picker = "ButtonExpandColorPicker" 31 | self.ui_color_picker = "ColorPicker" 32 | self.ui_dpi_scaler = "DPIScaler" 33 | self.imageFlagA = 0 34 | self.imageFlagB = 0 35 | # set data in init 36 | self.set_random_image_data() 37 | self.data.set_combo_box_items('CombBoxA', ['1', '3', '5']) 38 | self.data.set_object(self.ui_details_view, self.data) 39 | self.is_color_picker_shown = self.data.get_visibility(self.ui_color_picker) == "Visible" 40 | self.linearColor_re = re.compile(r"\(R=([-\d.]+),G=([-\d.]+),B=([-\d.]+),A=([-\d.]+)\)") 41 | 42 | self.tapython_version = dict(unreal.PythonBPLib.get_ta_python_version()) 43 | 44 | print("ChameleonGallery.Init") 45 | 46 | def mark_python_ready(self): 47 | print("mark_python_ready call") 48 | self.data.set_visibility(self.ui_python_not_ready, "Collapsed") 49 | self.data.set_visibility(self.ui_python_is_ready, "Visible") 50 | self.data.set_text(self.ui_is_python_ready_text, "Python Path Ready.") 51 | 52 | 53 | def push_breadcrumb(self): 54 | count = self.data.get_breadcrumbs_count_string(self.ui_crumbname) 55 | strs = "is breadcrumb tail from alice in wonder world" 56 | label = strs.split()[count % len(strs.split())] 57 | self.data.push_breadcrumb_string(self.ui_crumbname, label, label) 58 | 59 | def set_random_image_data(self): 60 | width = 64 61 | height = 64 62 | colors = [unreal.LinearColor(1, 1, 1, 1) if random.randint(0, 1) else unreal.LinearColor(0, 0, 0, 1) for _ in range(width * height)] 63 | self.data.set_image_pixels(self.ui_image, colors, width, height) 64 | 65 | def set_random_progress_bar_value(self): 66 | self.data.set_progress_bar_percent(self.ui_progressBar,random.random()) 67 | 68 | 69 | def change_local_image(self): 70 | self.data.set_image_from(self.ui_image_local, ["Images/ChameleonLogo_c.png", "Images/ChameleonLogo_b.png"][self.imageFlagA]) 71 | self.imageFlagA = (self.imageFlagA + 1) % 2 72 | 73 | 74 | def change_image(self): 75 | self.data.set_image_from_path(self.ui_imageB, ["PythonChameleonIcon_128x.png", "Icon128.png"][self.imageFlagB]) 76 | self.imageFlagB = (self.imageFlagB + 1) % 2 77 | 78 | def change_comboBox_items(self): 79 | offset = random.randint(1, 10) 80 | items = [str(v+offset) for v in range(random.randint(1, 10))] 81 | 82 | self.data.set_combo_box_items("CombBoxA", items) 83 | 84 | 85 | 86 | 87 | def launch_other_galleries(self): 88 | if not os.path.exists(os.path.join(os.path.dirname(__file__), 'auto_gen/border_brushes_Gallery.json')): 89 | unreal.PythonBPLib.notification("auto-generated Galleries not exists", info_level=1) 90 | return 91 | 92 | gallery_paths = ['ChameleonGallery/auto_gen/border_brushes_Gallery.json', 93 | 'ChameleonGallery/auto_gen/image_brushes_Gallery.json', 94 | 'ChameleonGallery/auto_gen/box_brushes_Gallery.json', 95 | 'ChameleonGallery/auto_gen/button_style_Gallery.json', 96 | 'ChameleonGallery/auto_gen/fonts_Gallery.json', 97 | 'ChameleonGallery/auto_gen/text_block_styles_Gallery.json', 98 | 'ChameleonGallery/auto_gen/editable_text_box_style_Gallery.json', 99 | 'ChameleonGallery/auto_gen/link_Styles_Gallery.json', 100 | 'ChameleonGallery/auto_gen/slate_color_brushes_Gallery.json', 101 | 'ChameleonGallery/auto_gen/check_box_style_Gallery.json', 102 | 'ChameleonGallery/auto_gen/richtext_editor_style.json' 103 | ] 104 | 105 | bLaunch = unreal.PythonBPLib.confirm_dialog(f'Open Other {len(gallery_paths)} Galleries? You can close them with the "Close all Gallery" Button' , "Open Other Galleries", with_cancel_button=False) 106 | 107 | if bLaunch: 108 | with unreal.ScopedSlowTask(len(gallery_paths), "Spawn Actors") as slow_task: 109 | slow_task.make_dialog(True) 110 | for i, p in enumerate(gallery_paths): 111 | slow_task.enter_progress_frame(1, f"Launch Gallery: {p}") 112 | 113 | unreal.ChameleonData.launch_chameleon_tool(p) 114 | 115 | def request_close_other_galleries(self): 116 | if not os.path.exists(os.path.join(os.path.dirname(__file__), 'auto_gen/border_brushes_Gallery.json')): 117 | unreal.PythonBPLib.notification("auto-generated Galleries not exists", info_level=1) 118 | return 119 | gallery_paths = ['ChameleonGallery/auto_gen/border_brushes_Gallery.json', 120 | 'ChameleonGallery/auto_gen/image_brushes_Gallery.json', 121 | 'ChameleonGallery/auto_gen/box_brushes_Gallery.json', 122 | 'ChameleonGallery/auto_gen/button_style_Gallery.json', 123 | 'ChameleonGallery/auto_gen/fonts_Gallery.json', 124 | 'ChameleonGallery/auto_gen/text_block_styles_Gallery.json', 125 | 'ChameleonGallery/auto_gen/editable_text_box_style_Gallery.json', 126 | 'ChameleonGallery/auto_gen/link_Styles_Gallery.json', 127 | 'ChameleonGallery/auto_gen/slate_color_brushes_Gallery.json', 128 | 'ChameleonGallery/auto_gen/check_box_style_Gallery.json', 129 | 'ChameleonGallery/auto_gen/richtext_editor_style.json' 130 | ] 131 | 132 | for i, p in enumerate(gallery_paths): 133 | unreal.ChameleonData.request_close(p) 134 | # unreal.ChameleonData.request_close('/ChameleonGallery/auto_gen/border_brushes_Gallery.json') 135 | 136 | exists_tools_var = [globals()[x] for x in globals() if "Utilities.Utils.Singleton" in str(type(type(globals()[x])))] 137 | 138 | def on_drop(self, assets, assets_folders, actors): 139 | str_for_show = "" 140 | for items, name in zip([assets, assets_folders, actors], ["Assets:", "Assets Folders:", "Actors:"]): 141 | if items: 142 | str_for_show += f"{name}\n" 143 | for item in items: 144 | str_for_show += f"\t{item}\n" 145 | self.data.set_text(self.ui_drop_target_text_box, str_for_show) 146 | 147 | print(f"str_for_show: {str_for_show}") 148 | 149 | def on_drop_func(self, *args, **kwargs): 150 | print(f"args: {args}") 151 | print(f"kwargs: {kwargs}") 152 | str_for_show = "" 153 | for name, items in kwargs.items(): 154 | if items: 155 | str_for_show += f"{name}:\n" 156 | for item in items: 157 | str_for_show += f"\t{item}\n" 158 | self.data.set_text(self.ui_drop_target_text_box, str_for_show) 159 | 160 | def get_full_size_of_this_chameleon(self): 161 | current_size = unreal.ChameleonData.get_chameleon_window_size(self.jsonPath) 162 | scrollbox_offsets = self.data.get_scroll_box_offsets(self.ui_scrollbox) 163 | height_full = scrollbox_offsets["ScrollOffsetOfEnd"] / (1.0-scrollbox_offsets["viewFraction"]) 164 | height_full += 48 165 | print(f"delta: {height_full} - {round(height_full)}") 166 | return current_size.x, round(height_full) 167 | 168 | 169 | def on_button_ChangeTabSize_click(self, offset_pixel): 170 | current_size = unreal.ChameleonData.get_chameleon_window_size(self.jsonPath) 171 | print(f"currentSize: {current_size}") 172 | offsets = self.data.get_scroll_box_offsets(self.ui_scrollbox) 173 | print(offsets) 174 | if current_size: 175 | current_size.x += offset_pixel 176 | unreal.ChameleonData.set_chameleon_window_size("ChameleonGallery/ChameleonGallery.json", current_size) 177 | 178 | def on_button_FlashWindow_click(self): 179 | unreal.ChameleonData.flash_chameleon_window("ChameleonGallery/ChameleonGallery.json") 180 | 181 | def on_button_Snapshot_click(self): 182 | full_size = self.get_full_size_of_this_chameleon() 183 | print(f"try save snapshot @ {full_size}") 184 | saved_file_path = unreal.ChameleonData.snapshot_chameleon_window(self.jsonPath, unreal.Vector2D(*full_size)) 185 | if saved_file_path: 186 | unreal.PythonBPLib.notification(f"UI Snapshot Saved:", hyperlink_text = saved_file_path 187 | , on_hyperlink_click_command = f'chameleon_gallery.explorer("{saved_file_path}")') 188 | else: 189 | unreal.PythonBPLib.notification(f"Save UI snapshot failed.", info_level = 1) 190 | 191 | def explorer(self, file_path): 192 | if sys.platform == "darwin": 193 | webbrowser.open(os.path.dirname(file_path)) 194 | else: 195 | file_path = file_path.replace("/", "\\") 196 | subprocess.call('explorer "{}" '.format(os.path.dirname(file_path))) 197 | 198 | def set_selected_actor_to_details_view(self): 199 | selected = unreal.get_editor_subsystem(unreal.EditorActorSubsystem).get_selected_level_actors() 200 | if selected: 201 | self.data.set_object(self.ui_details_view, selected[0]) 202 | else: 203 | print("Selected None") 204 | 205 | def on_expand_color_picker_click(self): 206 | self.data.set_visibility(self.ui_color_picker, "Collapsed" if self.is_color_picker_shown else "Visible") 207 | self.data.set_text(self.ui_button_expand_color_picker, "Expand ColorPicker" if self.is_color_picker_shown else "Collapse ColorPicker") 208 | self.is_color_picker_shown = not self.is_color_picker_shown 209 | 210 | current_size = unreal.ChameleonData.get_chameleon_window_size(self.jsonPath) 211 | if current_size.x < 650: 212 | current_size.x = 650 213 | unreal.ChameleonData.set_chameleon_window_size("ChameleonGallery/ChameleonGallery.json", current_size) 214 | 215 | def on_color_picker_commit(self, color_str): 216 | v = [float(a) for a in self.linearColor_re.match(color_str).groups()] 217 | self.data.set_color(self.ui_color_block, unreal.LinearColor(*v)) 218 | 219 | def change_dpi_scaler_value(self, value): 220 | if self.tapython_version["Minor"] < 2 or( 221 | self.tapython_version["Minor"] == 2 and self.tapython_version["Patch"] < 1 222 | ): 223 | print("Need TAPython version >= 1.2.1") 224 | return 225 | self.data.set_dpi_scale(self.ui_dpi_scaler, value + 0.5) 226 | 227 | -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ChameleonGallery/Images/ChameleonLogo_b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgerchenhp/TAPython_DefaultResources/1d5a223dbdb73a1947f2586e6120c88113b083ad/DefaultPythonSource/TA/TAPython/Python/ChameleonGallery/Images/ChameleonLogo_b.png -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ChameleonGallery/Images/ChameleonLogo_c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgerchenhp/TAPython_DefaultResources/1d5a223dbdb73a1947f2586e6120c88113b083ad/DefaultPythonSource/TA/TAPython/Python/ChameleonGallery/Images/ChameleonLogo_c.png -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ChameleonGallery/Images/cartoon_game_map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgerchenhp/TAPython_DefaultResources/1d5a223dbdb73a1947f2586e6120c88113b083ad/DefaultPythonSource/TA/TAPython/Python/ChameleonGallery/Images/cartoon_game_map.png -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ChameleonGallery/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from . import ChameleonGallery 3 | 4 | import importlib 5 | importlib.reload(ChameleonGallery) -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ChameleonGallery/auto_gen/border_brushes_Gallery.json: -------------------------------------------------------------------------------- 1 | { 2 | "TabLabel": "Border Brushes Gallery", 3 | "InitTabSize": [530, 250], 4 | "InitTabPosition": [1260, 50], 5 | "InitPyCmd": "", 6 | "Root":{ 7 | "SBorder": 8 | { 9 | "BorderImage": 10 | { 11 | "Style": "FCoreStyle", 12 | "Brush": "ToolPanel.GroupBorder" 13 | }, 14 | "Content":{ 15 | "SScrollBox": { 16 | "Slots": 17 | [ 18 | { 19 | "Padding": 5, 20 | "SGridPanel": 21 | { 22 | "FillColumn": [[0,0.5],[1,0.5]], 23 | "Slots": 24 | [ 25 | {"Column_Row": [0, 0], "STextBlock": {"Text": "FEditorStyle.PlainBorder"}}, 26 | { "Padding": [0,4], "Column_Row": [1, 0], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "PlainBorder"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 27 | {"Column_Row": [0, 1], "STextBlock": {"Text": "FEditorStyle.MarqueeSelection"}}, 28 | { "Padding": [0,4], "Column_Row": [1, 1], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "MarqueeSelection"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 29 | {"Column_Row": [0, 2], "STextBlock": {"Text": "FEditorStyle.DashedBorder"}}, 30 | { "Padding": [0,4], "Column_Row": [1, 2], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "DashedBorder"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 31 | {"Column_Row": [0, 3], "STextBlock": {"Text": "FEditorStyle.UniformShadow"}}, 32 | { "Padding": [0,4], "Column_Row": [1, 3], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "UniformShadow"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 33 | {"Column_Row": [0, 4], "STextBlock": {"Text": "FEditorStyle.UniformShadow_Tint"}}, 34 | { "Padding": [0,4], "Column_Row": [1, 4], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "UniformShadow_Tint"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 35 | {"Column_Row": [0, 5], "STextBlock": {"Text": "FEditorStyle.Sequencer.Timeline.SubSequenceRangeHashL"}}, 36 | { "Padding": [0,4], "Column_Row": [1, 5], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "Sequencer.Timeline.SubSequenceRangeHashL"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 37 | {"Column_Row": [0, 6], "STextBlock": {"Text": "FEditorStyle.Sequencer.Timeline.SubSequenceRangeHashR"}}, 38 | { "Padding": [0,4], "Column_Row": [1, 6], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "Sequencer.Timeline.SubSequenceRangeHashR"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 39 | {"Column_Row": [0, 7], "STextBlock": {"Text": "FEditorStyle.Sequencer.Section.Background"}}, 40 | { "Padding": [0,4], "Column_Row": [1, 7], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "Sequencer.Section.Background"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 41 | {"Column_Row": [0, 8], "STextBlock": {"Text": "FEditorStyle.Sequencer.Section.SelectionBorder"}}, 42 | { "Padding": [0,4], "Column_Row": [1, 8], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "Sequencer.Section.SelectionBorder"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 43 | {"Column_Row": [0, 9], "STextBlock": {"Text": "FEditorStyle.Sequencer.Section.LockedBorder"}}, 44 | { "Padding": [0,4], "Column_Row": [1, 9], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "Sequencer.Section.LockedBorder"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 45 | {"Column_Row": [0, 10], "STextBlock": {"Text": "FEditorStyle.Sequencer.Section.PreRoll"}}, 46 | { "Padding": [0,4], "Column_Row": [1, 10], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "Sequencer.Section.PreRoll"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 47 | {"Column_Row": [0, 11], "STextBlock": {"Text": "FEditorStyle.Sequencer.Section.OverlapBorder"}}, 48 | { "Padding": [0,4], "Column_Row": [1, 11], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "Sequencer.Section.OverlapBorder"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 49 | {"Column_Row": [0, 12], "STextBlock": {"Text": "FEditorStyle.PropertyTable.ReadOnlyEditModeCellBorder"}}, 50 | { "Padding": [0,4], "Column_Row": [1, 12], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "PropertyTable.ReadOnlyEditModeCellBorder"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 51 | {"Column_Row": [0, 13], "STextBlock": {"Text": "FEditorStyle.PinnedCommandList.Button.SubMenuOpen"}}, 52 | { "Padding": [0,4], "Column_Row": [1, 13], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "PinnedCommandList.Button.SubMenuOpen"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 53 | {"Column_Row": [0, 14], "STextBlock": {"Text": "FEditorStyle.ViewportPinnedCommandList.Button.SubMenuOpen"}}, 54 | { "Padding": [0,4], "Column_Row": [1, 14], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "ViewportPinnedCommandList.Button.SubMenuOpen"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 55 | {"Column_Row": [0, 15], "STextBlock": {"Text": "FEditorStyle.PlainBorder"}}, 56 | { "Padding": [0,4], "Column_Row": [1, 15], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "PlainBorder"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 57 | {"Column_Row": [0, 16], "STextBlock": {"Text": "FEditorStyle.MarqueeSelection"}}, 58 | { "Padding": [0,4], "Column_Row": [1, 16], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "MarqueeSelection"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 59 | {"Column_Row": [0, 17], "STextBlock": {"Text": "FEditorStyle.DashedBorder"}}, 60 | { "Padding": [0,4], "Column_Row": [1, 17], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "DashedBorder"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 61 | {"Column_Row": [0, 18], "STextBlock": {"Text": "FEditorStyle.UniformShadow"}}, 62 | { "Padding": [0,4], "Column_Row": [1, 18], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "UniformShadow"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 63 | {"Column_Row": [0, 19], "STextBlock": {"Text": "FEditorStyle.UniformShadow_Tint"}}, 64 | { "Padding": [0,4], "Column_Row": [1, 19], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "UniformShadow_Tint"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 65 | {"Column_Row": [0, 20], "STextBlock": {"Text": "FEditorStyle.Sequencer.Timeline.SubSequenceRangeHashL"}}, 66 | { "Padding": [0,4], "Column_Row": [1, 20], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "Sequencer.Timeline.SubSequenceRangeHashL"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 67 | {"Column_Row": [0, 21], "STextBlock": {"Text": "FEditorStyle.Sequencer.Timeline.SubSequenceRangeHashR"}}, 68 | { "Padding": [0,4], "Column_Row": [1, 21], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "Sequencer.Timeline.SubSequenceRangeHashR"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 69 | {"Column_Row": [0, 22], "STextBlock": {"Text": "FEditorStyle.Sequencer.Section.Background"}}, 70 | { "Padding": [0,4], "Column_Row": [1, 22], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "Sequencer.Section.Background"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 71 | {"Column_Row": [0, 23], "STextBlock": {"Text": "FEditorStyle.Sequencer.Section.SelectionBorder"}}, 72 | { "Padding": [0,4], "Column_Row": [1, 23], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "Sequencer.Section.SelectionBorder"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 73 | {"Column_Row": [0, 24], "STextBlock": {"Text": "FEditorStyle.Sequencer.Section.LockedBorder"}}, 74 | { "Padding": [0,4], "Column_Row": [1, 24], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "Sequencer.Section.LockedBorder"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 75 | {"Column_Row": [0, 25], "STextBlock": {"Text": "FEditorStyle.Sequencer.Section.PreRoll"}}, 76 | { "Padding": [0,4], "Column_Row": [1, 25], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "Sequencer.Section.PreRoll"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 77 | {"Column_Row": [0, 26], "STextBlock": {"Text": "FEditorStyle.Sequencer.Section.OverlapBorder"}}, 78 | { "Padding": [0,4], "Column_Row": [1, 26], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "Sequencer.Section.OverlapBorder"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 79 | {"Column_Row": [0, 27], "STextBlock": {"Text": "FEditorStyle.PropertyTable.ReadOnlyEditModeCellBorder"}}, 80 | { "Padding": [0,4], "Column_Row": [1, 27], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "PropertyTable.ReadOnlyEditModeCellBorder"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 81 | {"Column_Row": [0, 28], "STextBlock": {"Text": "FEditorStyle.PinnedCommandList.Button.SubMenuOpen"}}, 82 | { "Padding": [0,4], "Column_Row": [1, 28], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "PinnedCommandList.Button.SubMenuOpen"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 83 | {"Column_Row": [0, 29], "STextBlock": {"Text": "FEditorStyle.ViewportPinnedCommandList.Button.SubMenuOpen"}}, 84 | { "Padding": [0,4], "Column_Row": [1, 29], "SBorder": {"BorderImage":{ "Style": "FEditorStyle", "Brush": "ViewportPinnedCommandList.Button.SubMenuOpen"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 85 | {"Column_Row": [0, 30], "STextBlock": {"Text": "FCoreStyle.EditableText.CompositionBackground"}}, 86 | { "Padding": [0,4], "Column_Row": [1, 30], "SBorder": {"BorderImage":{ "Style": "FCoreStyle", "Brush": "EditableText.CompositionBackground"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 87 | {"Column_Row": [0, 31], "STextBlock": {"Text": "FCoreStyle.Border"}}, 88 | { "Padding": [0,4], "Column_Row": [1, 31], "SBorder": {"BorderImage":{ "Style": "FCoreStyle", "Brush": "Border"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 89 | {"Column_Row": [0, 32], "STextBlock": {"Text": "FCoreStyle.Menu.Button.SubMenuOpen"}}, 90 | { "Padding": [0,4], "Column_Row": [1, 32], "SBorder": {"BorderImage":{ "Style": "FCoreStyle", "Brush": "Menu.Button.SubMenuOpen"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 91 | {"Column_Row": [0, 33], "STextBlock": {"Text": "FCoreStyle.WindowMenuBar.Button.SubMenuOpen"}}, 92 | { "Padding": [0,4], "Column_Row": [1, 33], "SBorder": {"BorderImage":{ "Style": "FCoreStyle", "Brush": "WindowMenuBar.Button.SubMenuOpen"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 93 | {"Column_Row": [0, 34], "STextBlock": {"Text": "FCoreStyle.EditableText.CompositionBackground"}}, 94 | { "Padding": [0,4], "Column_Row": [1, 34], "SBorder": {"BorderImage":{ "Style": "FCoreStyle", "Brush": "EditableText.CompositionBackground"}, "Content":{"SSpacer":{"Size": [50, 50]}}}}, 95 | {"Column_Row": [0, 35], "STextBlock": {"Text": "FCoreStyle.Menu.Button.SubMenuOpen"}}, 96 | { "Padding": [0,4], "Column_Row": [1, 35], "SBorder": {"BorderImage":{ "Style": "FCoreStyle", "Brush": "Menu.Button.SubMenuOpen"}, "Content":{"SSpacer":{"Size": [50, 50]}}}} ] 97 | } 98 | } 99 | ] 100 | } 101 | } 102 | } 103 | } 104 | } -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ChameleonGallery/auto_gen/button_style_Gallery.json: -------------------------------------------------------------------------------- 1 | { 2 | "TabLabel": "Button Style Gallery", 3 | "InitTabSize": [530, 250], 4 | "InitTabPosition": [200, 50], 5 | "InitPyCmd": "", 6 | "Root":{ 7 | "SBorder": 8 | { 9 | "BorderImage": 10 | { 11 | "Style": "FCoreStyle", 12 | "Brush": "ToolPanel.GroupBorder" 13 | }, 14 | "Content":{ 15 | "SScrollBox": { 16 | "Slots": 17 | [ 18 | { 19 | "Padding": 5, 20 | "SGridPanel": 21 | { 22 | "FillColumn": [[0,0.5],[1,0.5]], 23 | "Slots": 24 | [ 25 | {"Column_Row": [0, 0], "STextBlock": {"Text": "FEditorStyle.NoBorder"}}, 26 | {"Padding": [0,4], "Column_Row": [1, 0], "SButton": { "Text": "NoBorder", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "NoBorder"}, "OnClick": "print(\"Click: FEditorStyle.NoBorder\")"}}, 27 | {"Column_Row": [0, 1], "STextBlock": {"Text": "FEditorStyle.NoBorder"}}, 28 | {"Padding": [0,4], "Column_Row": [1, 1], "SButton": { "Text": "NoBorder", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "NoBorder"}, "OnClick": "print(\"Click: FEditorStyle.NoBorder\")"}}, 29 | {"Column_Row": [0, 2], "STextBlock": {"Text": "FEditorStyle.HoverHintOnly"}}, 30 | {"Padding": [0,4], "Column_Row": [1, 2], "SButton": { "Text": "HoverHintOnly", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "HoverHintOnly"}, "OnClick": "print(\"Click: FEditorStyle.HoverHintOnly\")"}}, 31 | {"Column_Row": [0, 3], "STextBlock": {"Text": "FEditorStyle.SimpleSharpButton"}}, 32 | {"Padding": [0,4], "Column_Row": [1, 3], "SButton": { "Text": "SimpleSharpButton", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "SimpleSharpButton"}, "OnClick": "print(\"Click: FEditorStyle.SimpleSharpButton\")"}}, 33 | {"Column_Row": [0, 4], "STextBlock": {"Text": "FEditorStyle.SimpleRoundButton"}}, 34 | {"Padding": [0,4], "Column_Row": [1, 4], "SButton": { "Text": "SimpleRoundButton", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "SimpleRoundButton"}, "OnClick": "print(\"Click: FEditorStyle.SimpleRoundButton\")"}}, 35 | {"Column_Row": [0, 5], "STextBlock": {"Text": "FEditorStyle.Button"}}, 36 | {"Padding": [0,4], "Column_Row": [1, 5], "SButton": { "Text": "Button", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "Button"}, "OnClick": "print(\"Click: FEditorStyle.Button\")"}}, 37 | {"Column_Row": [0, 6], "STextBlock": {"Text": "FEditorStyle.FlatButton.Default"}}, 38 | {"Padding": [0,4], "Column_Row": [1, 6], "SButton": { "Text": "FlatButton.Default", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "FlatButton.Default"}, "OnClick": "print(\"Click: FEditorStyle.FlatButton.Default\")"}}, 39 | {"Column_Row": [0, 7], "STextBlock": {"Text": "FEditorStyle.HoverOnlyHyperlinkButton"}}, 40 | {"Padding": [0,4], "Column_Row": [1, 7], "SButton": { "Text": "HoverOnlyHyperlinkButton", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "HoverOnlyHyperlinkButton"}, "OnClick": "print(\"Click: FEditorStyle.HoverOnlyHyperlinkButton\")"}}, 41 | {"Column_Row": [0, 8], "STextBlock": {"Text": "FEditorStyle.Documentation.SDocumentationTooltipHyperlinkButton"}}, 42 | {"Padding": [0,4], "Column_Row": [1, 8], "SButton": { "Text": "Documentation.SDocumentationTooltipHyperlinkButton", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "Documentation.SDocumentationTooltipHyperlinkButton"}, "OnClick": "print(\"Click: FEditorStyle.Documentation.SDocumentationTooltipHyperlinkButton\")"}}, 43 | {"Column_Row": [0, 9], "STextBlock": {"Text": "FEditorStyle.Documentation.Hyperlink.Button"}}, 44 | {"Padding": [0,4], "Column_Row": [1, 9], "SButton": { "Text": "Documentation.Hyperlink.Button", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "Documentation.Hyperlink.Button"}, "OnClick": "print(\"Click: FEditorStyle.Documentation.Hyperlink.Button\")"}}, 45 | {"Column_Row": [0, 10], "STextBlock": {"Text": "FEditorStyle.TutorialEditableText.Toolbar.Button"}}, 46 | {"Padding": [0,4], "Column_Row": [1, 10], "SButton": { "Text": "TutorialEditableText.Toolbar.Button", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "TutorialEditableText.Toolbar.Button"}, "OnClick": "print(\"Click: FEditorStyle.TutorialEditableText.Toolbar.Button\")"}}, 47 | {"Column_Row": [0, 11], "STextBlock": {"Text": "FEditorStyle.PropertyEditor.AssetComboStyle"}}, 48 | {"Padding": [0,4], "Column_Row": [1, 11], "SButton": { "Text": "PropertyEditor.AssetComboStyle", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "PropertyEditor.AssetComboStyle"}, "OnClick": "print(\"Click: FEditorStyle.PropertyEditor.AssetComboStyle\")"}}, 49 | {"Column_Row": [0, 12], "STextBlock": {"Text": "FEditorStyle.EditorViewportToolBar.Button"}}, 50 | {"Padding": [0,4], "Column_Row": [1, 12], "SButton": { "Text": "EditorViewportToolBar.Button", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "EditorViewportToolBar.Button"}, "OnClick": "print(\"Click: FEditorStyle.EditorViewportToolBar.Button\")"}}, 51 | {"Column_Row": [0, 13], "STextBlock": {"Text": "FEditorStyle.BlueprintEditor.ContextMenu.TargetsButton"}}, 52 | {"Padding": [0,4], "Column_Row": [1, 13], "SButton": { "Text": "BlueprintEditor.ContextMenu.TargetsButton", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "BlueprintEditor.ContextMenu.TargetsButton"}, "OnClick": "print(\"Click: FEditorStyle.BlueprintEditor.ContextMenu.TargetsButton\")"}}, 53 | {"Column_Row": [0, 14], "STextBlock": {"Text": "FEditorStyle.HoverHintOnly"}}, 54 | {"Padding": [0,4], "Column_Row": [1, 14], "SButton": { "Text": "HoverHintOnly", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "HoverHintOnly"}, "OnClick": "print(\"Click: FEditorStyle.HoverHintOnly\")"}}, 55 | {"Column_Row": [0, 15], "STextBlock": {"Text": "FEditorStyle.SimpleSharpButton"}}, 56 | {"Padding": [0,4], "Column_Row": [1, 15], "SButton": { "Text": "SimpleSharpButton", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "SimpleSharpButton"}, "OnClick": "print(\"Click: FEditorStyle.SimpleSharpButton\")"}}, 57 | {"Column_Row": [0, 16], "STextBlock": {"Text": "FEditorStyle.SimpleRoundButton"}}, 58 | {"Padding": [0,4], "Column_Row": [1, 16], "SButton": { "Text": "SimpleRoundButton", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "SimpleRoundButton"}, "OnClick": "print(\"Click: FEditorStyle.SimpleRoundButton\")"}}, 59 | {"Column_Row": [0, 17], "STextBlock": {"Text": "FEditorStyle.FlatButton.Default"}}, 60 | {"Padding": [0,4], "Column_Row": [1, 17], "SButton": { "Text": "FlatButton.Default", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "FlatButton.Default"}, "OnClick": "print(\"Click: FEditorStyle.FlatButton.Default\")"}}, 61 | {"Column_Row": [0, 18], "STextBlock": {"Text": "FEditorStyle.HoverOnlyHyperlinkButton"}}, 62 | {"Padding": [0,4], "Column_Row": [1, 18], "SButton": { "Text": "HoverOnlyHyperlinkButton", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "HoverOnlyHyperlinkButton"}, "OnClick": "print(\"Click: FEditorStyle.HoverOnlyHyperlinkButton\")"}}, 63 | {"Column_Row": [0, 19], "STextBlock": {"Text": "FEditorStyle.RoundedButton"}}, 64 | {"Padding": [0,4], "Column_Row": [1, 19], "SButton": { "Text": "RoundedButton", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "RoundedButton"}, "OnClick": "print(\"Click: FEditorStyle.RoundedButton\")"}}, 65 | {"Column_Row": [0, 20], "STextBlock": {"Text": "FEditorStyle.EditorViewportToolBar.Button"}}, 66 | {"Padding": [0,4], "Column_Row": [1, 20], "SButton": { "Text": "EditorViewportToolBar.Button", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "EditorViewportToolBar.Button"}, "OnClick": "print(\"Click: FEditorStyle.EditorViewportToolBar.Button\")"}}, 67 | {"Column_Row": [0, 21], "STextBlock": {"Text": "FEditorStyle.EditorViewportToolBar.ComboMenu.ButtonStyle"}}, 68 | {"Padding": [0,4], "Column_Row": [1, 21], "SButton": { "Text": "EditorViewportToolBar.ComboMenu.ButtonStyle", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "EditorViewportToolBar.ComboMenu.ButtonStyle"}, "OnClick": "print(\"Click: FEditorStyle.EditorViewportToolBar.ComboMenu.ButtonStyle\")"}}, 69 | {"Column_Row": [0, 22], "STextBlock": {"Text": "FEditorStyle.EditorViewportToolBar.WarningButton"}}, 70 | {"Padding": [0,4], "Column_Row": [1, 22], "SButton": { "Text": "EditorViewportToolBar.WarningButton", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "EditorViewportToolBar.WarningButton"}, "OnClick": "print(\"Click: FEditorStyle.EditorViewportToolBar.WarningButton\")"}}, 71 | {"Column_Row": [0, 23], "STextBlock": {"Text": "FEditorStyle.Documentation.SDocumentationTooltipHyperlinkButton"}}, 72 | {"Padding": [0,4], "Column_Row": [1, 23], "SButton": { "Text": "Documentation.SDocumentationTooltipHyperlinkButton", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "Documentation.SDocumentationTooltipHyperlinkButton"}, "OnClick": "print(\"Click: FEditorStyle.Documentation.SDocumentationTooltipHyperlinkButton\")"}}, 73 | {"Column_Row": [0, 24], "STextBlock": {"Text": "FEditorStyle.Documentation.Hyperlink.Button"}}, 74 | {"Padding": [0,4], "Column_Row": [1, 24], "SButton": { "Text": "Documentation.Hyperlink.Button", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "Documentation.Hyperlink.Button"}, "OnClick": "print(\"Click: FEditorStyle.Documentation.Hyperlink.Button\")"}}, 75 | {"Column_Row": [0, 25], "STextBlock": {"Text": "FEditorStyle.TutorialEditableText.Toolbar.Button"}}, 76 | {"Padding": [0,4], "Column_Row": [1, 25], "SButton": { "Text": "TutorialEditableText.Toolbar.Button", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "TutorialEditableText.Toolbar.Button"}, "OnClick": "print(\"Click: FEditorStyle.TutorialEditableText.Toolbar.Button\")"}}, 77 | {"Column_Row": [0, 26], "STextBlock": {"Text": "FEditorStyle.PropertyEditor.AssetComboStyle"}}, 78 | {"Padding": [0,4], "Column_Row": [1, 26], "SButton": { "Text": "PropertyEditor.AssetComboStyle", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "PropertyEditor.AssetComboStyle"}, "OnClick": "print(\"Click: FEditorStyle.PropertyEditor.AssetComboStyle\")"}}, 79 | {"Column_Row": [0, 27], "STextBlock": {"Text": "FEditorStyle.DetailsView.ExtensionToolBar.Button"}}, 80 | {"Padding": [0,4], "Column_Row": [1, 27], "SButton": { "Text": "DetailsView.ExtensionToolBar.Button", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "DetailsView.ExtensionToolBar.Button"}, "OnClick": "print(\"Click: FEditorStyle.DetailsView.ExtensionToolBar.Button\")"}}, 81 | {"Column_Row": [0, 28], "STextBlock": {"Text": "FEditorStyle.BlueprintEditor.ContextMenu.TargetsButton"}}, 82 | {"Padding": [0,4], "Column_Row": [1, 28], "SButton": { "Text": "BlueprintEditor.ContextMenu.TargetsButton", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "BlueprintEditor.ContextMenu.TargetsButton"}, "OnClick": "print(\"Click: FEditorStyle.BlueprintEditor.ContextMenu.TargetsButton\")"}}, 83 | {"Column_Row": [0, 29], "STextBlock": {"Text": "FEditorStyle.TextureEditor.MipmapButtonStyle"}}, 84 | {"Padding": [0,4], "Column_Row": [1, 29], "SButton": { "Text": "TextureEditor.MipmapButtonStyle", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FEditorStyle", "StyleName": "TextureEditor.MipmapButtonStyle"}, "OnClick": "print(\"Click: FEditorStyle.TextureEditor.MipmapButtonStyle\")"}}, 85 | {"Column_Row": [0, 30], "STextBlock": {"Text": "FCoreStyle.NoBorder"}}, 86 | {"Padding": [0,4], "Column_Row": [1, 30], "SButton": { "Text": "NoBorder", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FCoreStyle", "StyleName": "NoBorder"}, "OnClick": "print(\"Click: FCoreStyle.NoBorder\")"}}, 87 | {"Column_Row": [0, 31], "STextBlock": {"Text": "FCoreStyle.NoBorder"}}, 88 | {"Padding": [0,4], "Column_Row": [1, 31], "SButton": { "Text": "NoBorder", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FCoreStyle", "StyleName": "NoBorder"}, "OnClick": "print(\"Click: FCoreStyle.NoBorder\")"}}, 89 | {"Column_Row": [0, 32], "STextBlock": {"Text": "FCoreStyle.Button"}}, 90 | {"Padding": [0,4], "Column_Row": [1, 32], "SButton": { "Text": "Button", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FCoreStyle", "StyleName": "Button"}, "OnClick": "print(\"Click: FCoreStyle.Button\")"}}, 91 | {"Column_Row": [0, 33], "STextBlock": {"Text": "FCoreStyle.Menu.Button"}}, 92 | {"Padding": [0,4], "Column_Row": [1, 33], "SButton": { "Text": "Menu.Button", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FCoreStyle", "StyleName": "Menu.Button"}, "OnClick": "print(\"Click: FCoreStyle.Menu.Button\")"}}, 93 | {"Column_Row": [0, 34], "STextBlock": {"Text": "FCoreStyle.WindowMenuBar.Button"}}, 94 | {"Padding": [0,4], "Column_Row": [1, 34], "SButton": { "Text": "WindowMenuBar.Button", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FCoreStyle", "StyleName": "WindowMenuBar.Button"}, "OnClick": "print(\"Click: FCoreStyle.WindowMenuBar.Button\")"}}, 95 | {"Column_Row": [0, 35], "STextBlock": {"Text": "FCoreStyle.NoBorder"}}, 96 | {"Padding": [0,4], "Column_Row": [1, 35], "SButton": { "Text": "NoBorder", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FCoreStyle", "StyleName": "NoBorder"}, "OnClick": "print(\"Click: FCoreStyle.NoBorder\")"}}, 97 | {"Column_Row": [0, 36], "STextBlock": {"Text": "FCoreStyle.NoBorder"}}, 98 | {"Padding": [0,4], "Column_Row": [1, 36], "SButton": { "Text": "NoBorder", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FCoreStyle", "StyleName": "NoBorder"}, "OnClick": "print(\"Click: FCoreStyle.NoBorder\")"}}, 99 | {"Column_Row": [0, 37], "STextBlock": {"Text": "FCoreStyle.PrimaryButton"}}, 100 | {"Padding": [0,4], "Column_Row": [1, 37], "SButton": { "Text": "PrimaryButton", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FCoreStyle", "StyleName": "PrimaryButton"}, "OnClick": "print(\"Click: FCoreStyle.PrimaryButton\")"}}, 101 | {"Column_Row": [0, 38], "STextBlock": {"Text": "FCoreStyle.Button"}}, 102 | {"Padding": [0,4], "Column_Row": [1, 38], "SButton": { "Text": "Button", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FCoreStyle", "StyleName": "Button"}, "OnClick": "print(\"Click: FCoreStyle.Button\")"}}, 103 | {"Column_Row": [0, 39], "STextBlock": {"Text": "FCoreStyle.SimpleButton"}}, 104 | {"Padding": [0,4], "Column_Row": [1, 39], "SButton": { "Text": "SimpleButton", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FCoreStyle", "StyleName": "SimpleButton"}, "OnClick": "print(\"Click: FCoreStyle.SimpleButton\")"}}, 105 | {"Column_Row": [0, 40], "STextBlock": {"Text": "FCoreStyle.SecondaryButton"}}, 106 | {"Padding": [0,4], "Column_Row": [1, 40], "SButton": { "Text": "SecondaryButton", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FCoreStyle", "StyleName": "SecondaryButton"}, "OnClick": "print(\"Click: FCoreStyle.SecondaryButton\")"}}, 107 | {"Column_Row": [0, 41], "STextBlock": {"Text": "FCoreStyle.InvisibleButton"}}, 108 | {"Padding": [0,4], "Column_Row": [1, 41], "SButton": { "Text": "InvisibleButton", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FCoreStyle", "StyleName": "InvisibleButton"}, "OnClick": "print(\"Click: FCoreStyle.InvisibleButton\")"}}, 109 | {"Column_Row": [0, 42], "STextBlock": {"Text": "FCoreStyle.Docking.SidebarButton.Closed"}}, 110 | {"Padding": [0,4], "Column_Row": [1, 42], "SButton": { "Text": "Docking.SidebarButton.Closed", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FCoreStyle", "StyleName": "Docking.SidebarButton.Closed"}, "OnClick": "print(\"Click: FCoreStyle.Docking.SidebarButton.Closed\")"}}, 111 | {"Column_Row": [0, 43], "STextBlock": {"Text": "FCoreStyle.Docking.SidebarButton.Opened"}}, 112 | {"Padding": [0,4], "Column_Row": [1, 43], "SButton": { "Text": "Docking.SidebarButton.Opened", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FCoreStyle", "StyleName": "Docking.SidebarButton.Opened"}, "OnClick": "print(\"Click: FCoreStyle.Docking.SidebarButton.Opened\")"}}, 113 | {"Column_Row": [0, 44], "STextBlock": {"Text": "FCoreStyle.Menu.Button"}}, 114 | {"Padding": [0,4], "Column_Row": [1, 44], "SButton": { "Text": "Menu.Button", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FCoreStyle", "StyleName": "Menu.Button"}, "OnClick": "print(\"Click: FCoreStyle.Menu.Button\")"}}, 115 | {"Column_Row": [0, 45], "STextBlock": {"Text": "FCoreStyle.WindowMenuBar.Button"}}, 116 | {"Padding": [0,4], "Column_Row": [1, 45], "SButton": { "Text": "WindowMenuBar.Button", "Halign": "Center", "ContentPadding": 6, "ButtonStyle": {"Style": "FCoreStyle", "StyleName": "WindowMenuBar.Button"}, "OnClick": "print(\"Click: FCoreStyle.WindowMenuBar.Button\")"}} ] 117 | } 118 | } 119 | ] 120 | } 121 | } 122 | } 123 | } 124 | } -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ChameleonGallery/auto_gen/check_box_style_Gallery.json: -------------------------------------------------------------------------------- 1 | { 2 | "TabLabel": "Check Box Style Gallery", 3 | "InitTabSize": [530, 250], 4 | "InitTabPosition": [730, 550], 5 | "InitPyCmd": "", 6 | "Root":{ 7 | "SBorder": 8 | { 9 | "BorderImage": 10 | { 11 | "Style": "FCoreStyle", 12 | "Brush": "ToolPanel.GroupBorder" 13 | }, 14 | "Content":{ 15 | "SScrollBox": { 16 | "Slots": 17 | [ 18 | { 19 | "Padding": 5, 20 | "SGridPanel": 21 | { 22 | "FillColumn": [[0,0.5],[1,0.5]], 23 | "Slots": 24 | [ 25 | {"Column_Row": [0, 0], "STextBlock": {"Text": "FEditorStyle.ToggleButtonCheckbox"}}, 26 | { "Padding": [0,4], "Column_Row": [1, 0], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "ToggleButtonCheckbox"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 27 | {"Column_Row": [0, 1], "STextBlock": {"Text": "FEditorStyle.CheckboxLookToggleButtonCheckbox"}}, 28 | { "Padding": [0,4], "Column_Row": [1, 1], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "CheckboxLookToggleButtonCheckbox"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 29 | {"Column_Row": [0, 2], "STextBlock": {"Text": "FEditorStyle.Checkbox"}}, 30 | { "Padding": [0,4], "Column_Row": [1, 2], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "Checkbox"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 31 | {"Column_Row": [0, 3], "STextBlock": {"Text": "FEditorStyle.TransparentCheckBox"}}, 32 | { "Padding": [0,4], "Column_Row": [1, 3], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "TransparentCheckBox"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 33 | {"Column_Row": [0, 4], "STextBlock": {"Text": "FEditorStyle.RadioButton"}}, 34 | { "Padding": [0,4], "Column_Row": [1, 4], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "RadioButton"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 35 | {"Column_Row": [0, 5], "STextBlock": {"Text": "FEditorStyle.CommentTitleButton"}}, 36 | { "Padding": [0,4], "Column_Row": [1, 5], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "CommentTitleButton"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 37 | {"Column_Row": [0, 6], "STextBlock": {"Text": "FEditorStyle.CommentBubbleButton"}}, 38 | { "Padding": [0,4], "Column_Row": [1, 6], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "CommentBubbleButton"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 39 | {"Column_Row": [0, 7], "STextBlock": {"Text": "FEditorStyle.CommentBubblePin"}}, 40 | { "Padding": [0,4], "Column_Row": [1, 7], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "CommentBubblePin"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 41 | {"Column_Row": [0, 8], "STextBlock": {"Text": "FEditorStyle.Graph.Node.AdvancedView"}}, 42 | { "Padding": [0,4], "Column_Row": [1, 8], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "Graph.Node.AdvancedView"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 43 | {"Column_Row": [0, 9], "STextBlock": {"Text": "FEditorStyle.Graph.Checkbox"}}, 44 | { "Padding": [0,4], "Column_Row": [1, 9], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "Graph.Checkbox"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 45 | {"Column_Row": [0, 10], "STextBlock": {"Text": "FEditorStyle.Kismet.Palette.FavoriteToggleStyle"}}, 46 | { "Padding": [0,4], "Column_Row": [1, 10], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "Kismet.Palette.FavoriteToggleStyle"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 47 | {"Column_Row": [0, 11], "STextBlock": {"Text": "FEditorStyle.PinnedCommandList.CheckBox"}}, 48 | { "Padding": [0,4], "Column_Row": [1, 11], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "PinnedCommandList.CheckBox"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 49 | {"Column_Row": [0, 12], "STextBlock": {"Text": "FEditorStyle.PinnedCommandList.Check"}}, 50 | { "Padding": [0,4], "Column_Row": [1, 12], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "PinnedCommandList.Check"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 51 | {"Column_Row": [0, 13], "STextBlock": {"Text": "FEditorStyle.PinnedCommandList.RadioButton"}}, 52 | { "Padding": [0,4], "Column_Row": [1, 13], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "PinnedCommandList.RadioButton"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 53 | {"Column_Row": [0, 14], "STextBlock": {"Text": "FEditorStyle.PinnedCommandList.ToggleButton"}}, 54 | { "Padding": [0,4], "Column_Row": [1, 14], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "PinnedCommandList.ToggleButton"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 55 | {"Column_Row": [0, 15], "STextBlock": {"Text": "FEditorStyle.ViewportPinnedCommandList.CheckBox"}}, 56 | { "Padding": [0,4], "Column_Row": [1, 15], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "ViewportPinnedCommandList.CheckBox"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 57 | {"Column_Row": [0, 16], "STextBlock": {"Text": "FEditorStyle.ViewportPinnedCommandList.Check"}}, 58 | { "Padding": [0,4], "Column_Row": [1, 16], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "ViewportPinnedCommandList.Check"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 59 | {"Column_Row": [0, 17], "STextBlock": {"Text": "FEditorStyle.ViewportPinnedCommandList.RadioButton"}}, 60 | { "Padding": [0,4], "Column_Row": [1, 17], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "ViewportPinnedCommandList.RadioButton"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 61 | {"Column_Row": [0, 18], "STextBlock": {"Text": "FEditorStyle.ViewportPinnedCommandList.ToggleButton"}}, 62 | { "Padding": [0,4], "Column_Row": [1, 18], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "ViewportPinnedCommandList.ToggleButton"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 63 | {"Column_Row": [0, 19], "STextBlock": {"Text": "FEditorStyle.ContentBrowser.FilterButton"}}, 64 | { "Padding": [0,4], "Column_Row": [1, 19], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "ContentBrowser.FilterButton"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 65 | {"Column_Row": [0, 20], "STextBlock": {"Text": "FEditorStyle.PhysicsAssetEditor.RadioButtons.Red"}}, 66 | { "Padding": [0,4], "Column_Row": [1, 20], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "PhysicsAssetEditor.RadioButtons.Red"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 67 | {"Column_Row": [0, 21], "STextBlock": {"Text": "FEditorStyle.PhysicsAssetEditor.RadioButtons.Green"}}, 68 | { "Padding": [0,4], "Column_Row": [1, 21], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "PhysicsAssetEditor.RadioButtons.Green"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 69 | {"Column_Row": [0, 22], "STextBlock": {"Text": "FEditorStyle.PhysicsAssetEditor.RadioButtons.Blue"}}, 70 | { "Padding": [0,4], "Column_Row": [1, 22], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "PhysicsAssetEditor.RadioButtons.Blue"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 71 | {"Column_Row": [0, 23], "STextBlock": {"Text": "FEditorStyle.UMGEditor.Palette.FavoriteToggleStyle"}}, 72 | { "Padding": [0,4], "Column_Row": [1, 23], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "UMGEditor.Palette.FavoriteToggleStyle"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 73 | {"Column_Row": [0, 24], "STextBlock": {"Text": "FEditorStyle.CheckboxLookToggleButtonCheckbox"}}, 74 | { "Padding": [0,4], "Column_Row": [1, 24], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "CheckboxLookToggleButtonCheckbox"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 75 | {"Column_Row": [0, 25], "STextBlock": {"Text": "FEditorStyle.EditorViewportToolBar.ToggleButton.Start"}}, 76 | { "Padding": [0,4], "Column_Row": [1, 25], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "EditorViewportToolBar.ToggleButton.Start"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 77 | {"Column_Row": [0, 26], "STextBlock": {"Text": "FEditorStyle.EditorViewportToolBar.ToggleButton.Middle"}}, 78 | { "Padding": [0,4], "Column_Row": [1, 26], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "EditorViewportToolBar.ToggleButton.Middle"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 79 | {"Column_Row": [0, 27], "STextBlock": {"Text": "FEditorStyle.EditorViewportToolBar.ToggleButton.End"}}, 80 | { "Padding": [0,4], "Column_Row": [1, 27], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "EditorViewportToolBar.ToggleButton.End"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 81 | {"Column_Row": [0, 28], "STextBlock": {"Text": "FEditorStyle.EditorViewportToolBar.ComboMenu.ToggleButton"}}, 82 | { "Padding": [0,4], "Column_Row": [1, 28], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "EditorViewportToolBar.ComboMenu.ToggleButton"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 83 | {"Column_Row": [0, 29], "STextBlock": {"Text": "FEditorStyle.EditorViewportToolBar.MaximizeRestoreButton"}}, 84 | { "Padding": [0,4], "Column_Row": [1, 29], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "EditorViewportToolBar.MaximizeRestoreButton"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 85 | {"Column_Row": [0, 30], "STextBlock": {"Text": "FEditorStyle.LegacyViewportMenu.ToggleButton.Start"}}, 86 | { "Padding": [0,4], "Column_Row": [1, 30], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "LegacyViewportMenu.ToggleButton.Start"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 87 | {"Column_Row": [0, 31], "STextBlock": {"Text": "FEditorStyle.LegacyViewportMenu.ToggleButton.Middle"}}, 88 | { "Padding": [0,4], "Column_Row": [1, 31], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "LegacyViewportMenu.ToggleButton.Middle"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 89 | {"Column_Row": [0, 32], "STextBlock": {"Text": "FEditorStyle.LegacyViewportMenu.ToggleButton.End"}}, 90 | { "Padding": [0,4], "Column_Row": [1, 32], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "LegacyViewportMenu.ToggleButton.End"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 91 | {"Column_Row": [0, 33], "STextBlock": {"Text": "FEditorStyle.CommentTitleButton"}}, 92 | { "Padding": [0,4], "Column_Row": [1, 33], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "CommentTitleButton"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 93 | {"Column_Row": [0, 34], "STextBlock": {"Text": "FEditorStyle.CommentBubbleButton"}}, 94 | { "Padding": [0,4], "Column_Row": [1, 34], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "CommentBubbleButton"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 95 | {"Column_Row": [0, 35], "STextBlock": {"Text": "FEditorStyle.CommentBubblePin"}}, 96 | { "Padding": [0,4], "Column_Row": [1, 35], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "CommentBubblePin"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 97 | {"Column_Row": [0, 36], "STextBlock": {"Text": "FEditorStyle.Graph.Node.AdvancedView"}}, 98 | { "Padding": [0,4], "Column_Row": [1, 36], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "Graph.Node.AdvancedView"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 99 | {"Column_Row": [0, 37], "STextBlock": {"Text": "FEditorStyle.Graph.Checkbox"}}, 100 | { "Padding": [0,4], "Column_Row": [1, 37], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "Graph.Checkbox"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 101 | {"Column_Row": [0, 38], "STextBlock": {"Text": "FEditorStyle.Kismet.Palette.FavoriteToggleStyle"}}, 102 | { "Padding": [0,4], "Column_Row": [1, 38], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "Kismet.Palette.FavoriteToggleStyle"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 103 | {"Column_Row": [0, 39], "STextBlock": {"Text": "FEditorStyle.PinnedCommandList.CheckBox"}}, 104 | { "Padding": [0,4], "Column_Row": [1, 39], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "PinnedCommandList.CheckBox"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 105 | {"Column_Row": [0, 40], "STextBlock": {"Text": "FEditorStyle.PinnedCommandList.Check"}}, 106 | { "Padding": [0,4], "Column_Row": [1, 40], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "PinnedCommandList.Check"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 107 | {"Column_Row": [0, 41], "STextBlock": {"Text": "FEditorStyle.PinnedCommandList.RadioButton"}}, 108 | { "Padding": [0,4], "Column_Row": [1, 41], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "PinnedCommandList.RadioButton"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 109 | {"Column_Row": [0, 42], "STextBlock": {"Text": "FEditorStyle.PinnedCommandList.ToggleButton"}}, 110 | { "Padding": [0,4], "Column_Row": [1, 42], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "PinnedCommandList.ToggleButton"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 111 | {"Column_Row": [0, 43], "STextBlock": {"Text": "FEditorStyle.ViewportPinnedCommandList.CheckBox"}}, 112 | { "Padding": [0,4], "Column_Row": [1, 43], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "ViewportPinnedCommandList.CheckBox"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 113 | {"Column_Row": [0, 44], "STextBlock": {"Text": "FEditorStyle.ViewportPinnedCommandList.Check"}}, 114 | { "Padding": [0,4], "Column_Row": [1, 44], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "ViewportPinnedCommandList.Check"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 115 | {"Column_Row": [0, 45], "STextBlock": {"Text": "FEditorStyle.ViewportPinnedCommandList.RadioButton"}}, 116 | { "Padding": [0,4], "Column_Row": [1, 45], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "ViewportPinnedCommandList.RadioButton"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 117 | {"Column_Row": [0, 46], "STextBlock": {"Text": "FEditorStyle.ViewportPinnedCommandList.ToggleButton"}}, 118 | { "Padding": [0,4], "Column_Row": [1, 46], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "ViewportPinnedCommandList.ToggleButton"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 119 | {"Column_Row": [0, 47], "STextBlock": {"Text": "FEditorStyle.ContentBrowser.FilterButton"}}, 120 | { "Padding": [0,4], "Column_Row": [1, 47], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "ContentBrowser.FilterButton"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 121 | {"Column_Row": [0, 48], "STextBlock": {"Text": "FEditorStyle.TextureEditor.ChannelButtonStyle"}}, 122 | { "Padding": [0,4], "Column_Row": [1, 48], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "TextureEditor.ChannelButtonStyle"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 123 | {"Column_Row": [0, 49], "STextBlock": {"Text": "FEditorStyle.PhysicsAssetEditor.RadioButtons.Red"}}, 124 | { "Padding": [0,4], "Column_Row": [1, 49], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "PhysicsAssetEditor.RadioButtons.Red"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 125 | {"Column_Row": [0, 50], "STextBlock": {"Text": "FEditorStyle.PhysicsAssetEditor.RadioButtons.Green"}}, 126 | { "Padding": [0,4], "Column_Row": [1, 50], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "PhysicsAssetEditor.RadioButtons.Green"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 127 | {"Column_Row": [0, 51], "STextBlock": {"Text": "FEditorStyle.PhysicsAssetEditor.RadioButtons.Blue"}}, 128 | { "Padding": [0,4], "Column_Row": [1, 51], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "PhysicsAssetEditor.RadioButtons.Blue"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 129 | {"Column_Row": [0, 52], "STextBlock": {"Text": "FEditorStyle.UMGEditor.Palette.FavoriteToggleStyle"}}, 130 | { "Padding": [0,4], "Column_Row": [1, 52], "SCheckBox": {"CheckBoxStyle":{ "Style": "FEditorStyle", "StyleName": "UMGEditor.Palette.FavoriteToggleStyle"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 131 | {"Column_Row": [0, 53], "STextBlock": {"Text": "FCoreStyle.Checkbox"}}, 132 | { "Padding": [0,4], "Column_Row": [1, 53], "SCheckBox": {"CheckBoxStyle":{ "Style": "FCoreStyle", "StyleName": "Checkbox"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 133 | {"Column_Row": [0, 54], "STextBlock": {"Text": "FCoreStyle.TransparentCheckBox"}}, 134 | { "Padding": [0,4], "Column_Row": [1, 54], "SCheckBox": {"CheckBoxStyle":{ "Style": "FCoreStyle", "StyleName": "TransparentCheckBox"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 135 | {"Column_Row": [0, 55], "STextBlock": {"Text": "FCoreStyle.ToggleButtonCheckbox"}}, 136 | { "Padding": [0,4], "Column_Row": [1, 55], "SCheckBox": {"CheckBoxStyle":{ "Style": "FCoreStyle", "StyleName": "ToggleButtonCheckbox"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 137 | {"Column_Row": [0, 56], "STextBlock": {"Text": "FCoreStyle.RadioButton"}}, 138 | { "Padding": [0,4], "Column_Row": [1, 56], "SCheckBox": {"CheckBoxStyle":{ "Style": "FCoreStyle", "StyleName": "RadioButton"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 139 | {"Column_Row": [0, 57], "STextBlock": {"Text": "FCoreStyle.Menu.CheckBox"}}, 140 | { "Padding": [0,4], "Column_Row": [1, 57], "SCheckBox": {"CheckBoxStyle":{ "Style": "FCoreStyle", "StyleName": "Menu.CheckBox"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 141 | {"Column_Row": [0, 58], "STextBlock": {"Text": "FCoreStyle.Menu.Check"}}, 142 | { "Padding": [0,4], "Column_Row": [1, 58], "SCheckBox": {"CheckBoxStyle":{ "Style": "FCoreStyle", "StyleName": "Menu.Check"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 143 | {"Column_Row": [0, 59], "STextBlock": {"Text": "FCoreStyle.Menu.RadioButton"}}, 144 | { "Padding": [0,4], "Column_Row": [1, 59], "SCheckBox": {"CheckBoxStyle":{ "Style": "FCoreStyle", "StyleName": "Menu.RadioButton"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 145 | {"Column_Row": [0, 60], "STextBlock": {"Text": "FCoreStyle.Menu.ToggleButton"}}, 146 | { "Padding": [0,4], "Column_Row": [1, 60], "SCheckBox": {"CheckBoxStyle":{ "Style": "FCoreStyle", "StyleName": "Menu.ToggleButton"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 147 | {"Column_Row": [0, 61], "STextBlock": {"Text": "FCoreStyle.Checkbox"}}, 148 | { "Padding": [0,4], "Column_Row": [1, 61], "SCheckBox": {"CheckBoxStyle":{ "Style": "FCoreStyle", "StyleName": "Checkbox"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 149 | {"Column_Row": [0, 62], "STextBlock": {"Text": "FCoreStyle.SimplifiedCheckbox"}}, 150 | { "Padding": [0,4], "Column_Row": [1, 62], "SCheckBox": {"CheckBoxStyle":{ "Style": "FCoreStyle", "StyleName": "SimplifiedCheckbox"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 151 | {"Column_Row": [0, 63], "STextBlock": {"Text": "FCoreStyle.TransparentCheckBox"}}, 152 | { "Padding": [0,4], "Column_Row": [1, 63], "SCheckBox": {"CheckBoxStyle":{ "Style": "FCoreStyle", "StyleName": "TransparentCheckBox"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 153 | {"Column_Row": [0, 64], "STextBlock": {"Text": "FCoreStyle.ToggleButtonCheckbox"}}, 154 | { "Padding": [0,4], "Column_Row": [1, 64], "SCheckBox": {"CheckBoxStyle":{ "Style": "FCoreStyle", "StyleName": "ToggleButtonCheckbox"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 155 | {"Column_Row": [0, 65], "STextBlock": {"Text": "FCoreStyle.ToggleButtonCheckboxAlt"}}, 156 | { "Padding": [0,4], "Column_Row": [1, 65], "SCheckBox": {"CheckBoxStyle":{ "Style": "FCoreStyle", "StyleName": "ToggleButtonCheckboxAlt"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 157 | {"Column_Row": [0, 66], "STextBlock": {"Text": "FCoreStyle.SegmentedCombo.Left"}}, 158 | { "Padding": [0,4], "Column_Row": [1, 66], "SCheckBox": {"CheckBoxStyle":{ "Style": "FCoreStyle", "StyleName": "SegmentedCombo.Left"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 159 | {"Column_Row": [0, 67], "STextBlock": {"Text": "FCoreStyle.SegmentedCombo.ButtonOnly"}}, 160 | { "Padding": [0,4], "Column_Row": [1, 67], "SCheckBox": {"CheckBoxStyle":{ "Style": "FCoreStyle", "StyleName": "SegmentedCombo.ButtonOnly"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 161 | {"Column_Row": [0, 68], "STextBlock": {"Text": "FCoreStyle.RadioButton"}}, 162 | { "Padding": [0,4], "Column_Row": [1, 68], "SCheckBox": {"CheckBoxStyle":{ "Style": "FCoreStyle", "StyleName": "RadioButton"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 163 | {"Column_Row": [0, 69], "STextBlock": {"Text": "FCoreStyle.Menu.CheckBox"}}, 164 | { "Padding": [0,4], "Column_Row": [1, 69], "SCheckBox": {"CheckBoxStyle":{ "Style": "FCoreStyle", "StyleName": "Menu.CheckBox"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 165 | {"Column_Row": [0, 70], "STextBlock": {"Text": "FCoreStyle.Menu.Check"}}, 166 | { "Padding": [0,4], "Column_Row": [1, 70], "SCheckBox": {"CheckBoxStyle":{ "Style": "FCoreStyle", "StyleName": "Menu.Check"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 167 | {"Column_Row": [0, 71], "STextBlock": {"Text": "FCoreStyle.Menu.RadioButton"}}, 168 | { "Padding": [0,4], "Column_Row": [1, 71], "SCheckBox": {"CheckBoxStyle":{ "Style": "FCoreStyle", "StyleName": "Menu.RadioButton"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}}, 169 | {"Column_Row": [0, 72], "STextBlock": {"Text": "FCoreStyle.Menu.ToggleButton"}}, 170 | { "Padding": [0,4], "Column_Row": [1, 72], "SCheckBox": {"CheckBoxStyle":{ "Style": "FCoreStyle", "StyleName": "Menu.ToggleButton"}, "Content": { "STextBlock": {"Text": "This is a Checkbox"}}}} ] 171 | } 172 | } 173 | ] 174 | } 175 | } 176 | } 177 | } 178 | } -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ChameleonGallery/auto_gen/editable_text_box_style_Gallery.json: -------------------------------------------------------------------------------- 1 | { 2 | "TabLabel": "Editable Text Box Style Gallery", 3 | "InitTabSize": [530, 250], 4 | "InitTabPosition": [730, 800], 5 | "InitPyCmd": "", 6 | "Root":{ 7 | "SBorder": 8 | { 9 | "BorderImage": 10 | { 11 | "Style": "FCoreStyle", 12 | "Brush": "ToolPanel.GroupBorder" 13 | }, 14 | "Content":{ 15 | "SScrollBox": { 16 | "Slots": 17 | [ 18 | { 19 | "Padding": 5, 20 | "SGridPanel": 21 | { 22 | "FillColumn": [[0,0.5],[1,0.5]], 23 | "Slots": 24 | [ 25 | {"Column_Row": [0, 0], "STextBlock": {"Text": "FEditorStyle.SpecialEditableTextBox"}}, 26 | { "Padding": [0,4], "Column_Row": [1, 0], "SEditableTextBox": {"Style":{ "Style": "FEditorStyle", "StyleName": "SpecialEditableTextBox"}, "Text": "This is a SEditableTextBox"}}, 27 | {"Column_Row": [0, 1], "STextBlock": {"Text": "FEditorStyle.Sequencer.ExposedNamePill.Input"}}, 28 | { "Padding": [0,4], "Column_Row": [1, 1], "SEditableTextBox": {"Style":{ "Style": "FEditorStyle", "StyleName": "Sequencer.ExposedNamePill.Input"}, "Text": "This is a SEditableTextBox"}}, 29 | {"Column_Row": [0, 2], "STextBlock": {"Text": "FEditorStyle.Sequencer.HyperlinkTextBox"}}, 30 | { "Padding": [0,4], "Column_Row": [1, 2], "SEditableTextBox": {"Style":{ "Style": "FEditorStyle", "StyleName": "Sequencer.HyperlinkTextBox"}, "Text": "This is a SEditableTextBox"}}, 31 | {"Column_Row": [0, 3], "STextBlock": {"Text": "FEditorStyle.Graph.StateNode.NodeTitleEditableText"}}, 32 | { "Padding": [0,4], "Column_Row": [1, 3], "SEditableTextBox": {"Style":{ "Style": "FEditorStyle", "StyleName": "Graph.StateNode.NodeTitleEditableText"}, "Text": "This is a SEditableTextBox"}}, 33 | {"Column_Row": [0, 4], "STextBlock": {"Text": "FEditorStyle.Graph.Node.NodeTitleEditableText"}}, 34 | { "Padding": [0,4], "Column_Row": [1, 4], "SEditableTextBox": {"Style":{ "Style": "FEditorStyle", "StyleName": "Graph.Node.NodeTitleEditableText"}, "Text": "This is a SEditableTextBox"}}, 35 | {"Column_Row": [0, 5], "STextBlock": {"Text": "FEditorStyle.Graph.CommentBlock.TitleEditableText"}}, 36 | { "Padding": [0,4], "Column_Row": [1, 5], "SEditableTextBox": {"Style":{ "Style": "FEditorStyle", "StyleName": "Graph.CommentBlock.TitleEditableText"}, "Text": "This is a SEditableTextBox"}}, 37 | {"Column_Row": [0, 6], "STextBlock": {"Text": "FEditorStyle.PinnedCommandList.EditableText"}}, 38 | { "Padding": [0,4], "Column_Row": [1, 6], "SEditableTextBox": {"Style":{ "Style": "FEditorStyle", "StyleName": "PinnedCommandList.EditableText"}, "Text": "This is a SEditableTextBox"}}, 39 | {"Column_Row": [0, 7], "STextBlock": {"Text": "FEditorStyle.ViewportPinnedCommandList.EditableText"}}, 40 | { "Padding": [0,4], "Column_Row": [1, 7], "SEditableTextBox": {"Style":{ "Style": "FEditorStyle", "StyleName": "ViewportPinnedCommandList.EditableText"}, "Text": "This is a SEditableTextBox"}}, 41 | {"Column_Row": [0, 8], "STextBlock": {"Text": "FEditorStyle.ReferenceViewer.PathText"}}, 42 | { "Padding": [0,4], "Column_Row": [1, 8], "SEditableTextBox": {"Style":{ "Style": "FEditorStyle", "StyleName": "ReferenceViewer.PathText"}, "Text": "This is a SEditableTextBox"}}, 43 | {"Column_Row": [0, 9], "STextBlock": {"Text": "FEditorStyle.PhysicsAssetEditor.Profiles.EditableTextBoxStyle"}}, 44 | { "Padding": [0,4], "Column_Row": [1, 9], "SEditableTextBox": {"Style":{ "Style": "FEditorStyle", "StyleName": "PhysicsAssetEditor.Profiles.EditableTextBoxStyle"}, "Text": "This is a SEditableTextBox"}}, 45 | {"Column_Row": [0, 10], "STextBlock": {"Text": "FEditorStyle.SpecialEditableTextBox"}}, 46 | { "Padding": [0,4], "Column_Row": [1, 10], "SEditableTextBox": {"Style":{ "Style": "FEditorStyle", "StyleName": "SpecialEditableTextBox"}, "Text": "This is a SEditableTextBox"}}, 47 | {"Column_Row": [0, 11], "STextBlock": {"Text": "FEditorStyle.Sequencer.ExposedNamePill.Input"}}, 48 | { "Padding": [0,4], "Column_Row": [1, 11], "SEditableTextBox": {"Style":{ "Style": "FEditorStyle", "StyleName": "Sequencer.ExposedNamePill.Input"}, "Text": "This is a SEditableTextBox"}}, 49 | {"Column_Row": [0, 12], "STextBlock": {"Text": "FEditorStyle.Sequencer.HyperlinkTextBox"}}, 50 | { "Padding": [0,4], "Column_Row": [1, 12], "SEditableTextBox": {"Style":{ "Style": "FEditorStyle", "StyleName": "Sequencer.HyperlinkTextBox"}, "Text": "This is a SEditableTextBox"}}, 51 | {"Column_Row": [0, 13], "STextBlock": {"Text": "FEditorStyle.Graph.StateNode.NodeTitleEditableText"}}, 52 | { "Padding": [0,4], "Column_Row": [1, 13], "SEditableTextBox": {"Style":{ "Style": "FEditorStyle", "StyleName": "Graph.StateNode.NodeTitleEditableText"}, "Text": "This is a SEditableTextBox"}}, 53 | {"Column_Row": [0, 14], "STextBlock": {"Text": "FEditorStyle.Graph.Node.NodeTitleEditableText"}}, 54 | { "Padding": [0,4], "Column_Row": [1, 14], "SEditableTextBox": {"Style":{ "Style": "FEditorStyle", "StyleName": "Graph.Node.NodeTitleEditableText"}, "Text": "This is a SEditableTextBox"}}, 55 | {"Column_Row": [0, 15], "STextBlock": {"Text": "FEditorStyle.Graph.CommentBlock.TitleEditableText"}}, 56 | { "Padding": [0,4], "Column_Row": [1, 15], "SEditableTextBox": {"Style":{ "Style": "FEditorStyle", "StyleName": "Graph.CommentBlock.TitleEditableText"}, "Text": "This is a SEditableTextBox"}}, 57 | {"Column_Row": [0, 16], "STextBlock": {"Text": "FEditorStyle.PinnedCommandList.EditableText"}}, 58 | { "Padding": [0,4], "Column_Row": [1, 16], "SEditableTextBox": {"Style":{ "Style": "FEditorStyle", "StyleName": "PinnedCommandList.EditableText"}, "Text": "This is a SEditableTextBox"}}, 59 | {"Column_Row": [0, 17], "STextBlock": {"Text": "FEditorStyle.ViewportPinnedCommandList.EditableText"}}, 60 | { "Padding": [0,4], "Column_Row": [1, 17], "SEditableTextBox": {"Style":{ "Style": "FEditorStyle", "StyleName": "ViewportPinnedCommandList.EditableText"}, "Text": "This is a SEditableTextBox"}}, 61 | {"Column_Row": [0, 18], "STextBlock": {"Text": "FEditorStyle.ReferenceViewer.PathText"}}, 62 | { "Padding": [0,4], "Column_Row": [1, 18], "SEditableTextBox": {"Style":{ "Style": "FEditorStyle", "StyleName": "ReferenceViewer.PathText"}, "Text": "This is a SEditableTextBox"}}, 63 | {"Column_Row": [0, 19], "STextBlock": {"Text": "FEditorStyle.PhysicsAssetEditor.Profiles.EditableTextBoxStyle"}}, 64 | { "Padding": [0,4], "Column_Row": [1, 19], "SEditableTextBox": {"Style":{ "Style": "FEditorStyle", "StyleName": "PhysicsAssetEditor.Profiles.EditableTextBoxStyle"}, "Text": "This is a SEditableTextBox"}}, 65 | {"Column_Row": [0, 20], "STextBlock": {"Text": "FCoreStyle.NormalEditableTextBox"}}, 66 | { "Padding": [0,4], "Column_Row": [1, 20], "SEditableTextBox": {"Style":{ "Style": "FCoreStyle", "StyleName": "NormalEditableTextBox"}, "Text": "This is a SEditableTextBox"}}, 67 | {"Column_Row": [0, 21], "STextBlock": {"Text": "FCoreStyle.DarkEditableTextBox"}}, 68 | { "Padding": [0,4], "Column_Row": [1, 21], "SEditableTextBox": {"Style":{ "Style": "FCoreStyle", "StyleName": "DarkEditableTextBox"}, "Text": "This is a SEditableTextBox"}}, 69 | {"Column_Row": [0, 22], "STextBlock": {"Text": "FCoreStyle.Menu.EditableText"}}, 70 | { "Padding": [0,4], "Column_Row": [1, 22], "SEditableTextBox": {"Style":{ "Style": "FCoreStyle", "StyleName": "Menu.EditableText"}, "Text": "This is a SEditableTextBox"}}, 71 | {"Column_Row": [0, 23], "STextBlock": {"Text": "FCoreStyle.DarkEditableTextBox"}}, 72 | { "Padding": [0,4], "Column_Row": [1, 23], "SEditableTextBox": {"Style":{ "Style": "FCoreStyle", "StyleName": "DarkEditableTextBox"}, "Text": "This is a SEditableTextBox"}}, 73 | {"Column_Row": [0, 24], "STextBlock": {"Text": "FCoreStyle.NormalEditableTextBox"}}, 74 | { "Padding": [0,4], "Column_Row": [1, 24], "SEditableTextBox": {"Style":{ "Style": "FCoreStyle", "StyleName": "NormalEditableTextBox"}, "Text": "This is a SEditableTextBox"}}, 75 | {"Column_Row": [0, 25], "STextBlock": {"Text": "FCoreStyle.Menu.EditableText"}}, 76 | { "Padding": [0,4], "Column_Row": [1, 25], "SEditableTextBox": {"Style":{ "Style": "FCoreStyle", "StyleName": "Menu.EditableText"}, "Text": "This is a SEditableTextBox"}} ] 77 | } 78 | } 79 | ] 80 | } 81 | } 82 | } 83 | } 84 | } -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ChameleonGallery/auto_gen/link_Styles_Gallery.json: -------------------------------------------------------------------------------- 1 | { 2 | "TabLabel": "Link Styles Gallery", 3 | "InitTabSize": [530, 250], 4 | "InitTabPosition": [1260, 300], 5 | "InitPyCmd": "", 6 | "Root":{ 7 | "SBorder": 8 | { 9 | "BorderImage": 10 | { 11 | "Style": "FCoreStyle", 12 | "Brush": "ToolPanel.GroupBorder" 13 | }, 14 | "Content":{ 15 | "SScrollBox": { 16 | "Slots": 17 | [ 18 | { 19 | "Padding": 5, 20 | "SGridPanel": 21 | { 22 | "FillColumn": [[0,0.5],[1,0.5]], 23 | "Slots": 24 | [ 25 | {"Column_Row": [0, 0], "STextBlock": {"Text": "FEditorStyle.DarkHyperlink"}}, 26 | { "Padding": [0,4], "Column_Row": [1, 0], "SHyperlink": {"Style":{ "Style": "FEditorStyle", "StyleName": "DarkHyperlink"}, "Text": "www.link_to_some_where"}}, 27 | {"Column_Row": [0, 1], "STextBlock": {"Text": "FEditorStyle.HoverOnlyHyperlink"}}, 28 | { "Padding": [0,4], "Column_Row": [1, 1], "SHyperlink": {"Style":{ "Style": "FEditorStyle", "StyleName": "HoverOnlyHyperlink"}, "Text": "www.link_to_some_where"}}, 29 | {"Column_Row": [0, 2], "STextBlock": {"Text": "FEditorStyle.Credits.Hyperlink"}}, 30 | { "Padding": [0,4], "Column_Row": [1, 2], "SHyperlink": {"Style":{ "Style": "FEditorStyle", "StyleName": "Credits.Hyperlink"}, "Text": "www.link_to_some_where"}}, 31 | {"Column_Row": [0, 3], "STextBlock": {"Text": "FEditorStyle.Common.GotoNativeCodeHyperlink"}}, 32 | { "Padding": [0,4], "Column_Row": [1, 3], "SHyperlink": {"Style":{ "Style": "FEditorStyle", "StyleName": "Common.GotoNativeCodeHyperlink"}, "Text": "www.link_to_some_where"}}, 33 | {"Column_Row": [0, 4], "STextBlock": {"Text": "FEditorStyle.Common.GotoBlueprintHyperlink"}}, 34 | { "Padding": [0,4], "Column_Row": [1, 4], "SHyperlink": {"Style":{ "Style": "FEditorStyle", "StyleName": "Common.GotoBlueprintHyperlink"}, "Text": "www.link_to_some_where"}}, 35 | {"Column_Row": [0, 5], "STextBlock": {"Text": "FEditorStyle.Documentation.Hyperlink"}}, 36 | { "Padding": [0,4], "Column_Row": [1, 5], "SHyperlink": {"Style":{ "Style": "FEditorStyle", "StyleName": "Documentation.Hyperlink"}, "Text": "www.link_to_some_where"}}, 37 | {"Column_Row": [0, 6], "STextBlock": {"Text": "FEditorStyle.Tutorials.Content.Hyperlink"}}, 38 | { "Padding": [0,4], "Column_Row": [1, 6], "SHyperlink": {"Style":{ "Style": "FEditorStyle", "StyleName": "Tutorials.Content.Hyperlink"}, "Text": "www.link_to_some_where"}}, 39 | {"Column_Row": [0, 7], "STextBlock": {"Text": "FEditorStyle.TutorialEditableText.Editor.Hyperlink"}}, 40 | { "Padding": [0,4], "Column_Row": [1, 7], "SHyperlink": {"Style":{ "Style": "FEditorStyle", "StyleName": "TutorialEditableText.Editor.Hyperlink"}, "Text": "www.link_to_some_where"}}, 41 | {"Column_Row": [0, 8], "STextBlock": {"Text": "FEditorStyle.DetailsView.BPMessageHyperlinkStyle"}}, 42 | { "Padding": [0,4], "Column_Row": [1, 8], "SHyperlink": {"Style":{ "Style": "FEditorStyle", "StyleName": "DetailsView.BPMessageHyperlinkStyle"}, "Text": "www.link_to_some_where"}}, 43 | {"Column_Row": [0, 9], "STextBlock": {"Text": "FEditorStyle.NavigationHyperlink"}}, 44 | { "Padding": [0,4], "Column_Row": [1, 9], "SHyperlink": {"Style":{ "Style": "FEditorStyle", "StyleName": "NavigationHyperlink"}, "Text": "www.link_to_some_where"}}, 45 | {"Column_Row": [0, 10], "STextBlock": {"Text": "FEditorStyle.DarkHyperlink"}}, 46 | { "Padding": [0,4], "Column_Row": [1, 10], "SHyperlink": {"Style":{ "Style": "FEditorStyle", "StyleName": "DarkHyperlink"}, "Text": "www.link_to_some_where"}}, 47 | {"Column_Row": [0, 11], "STextBlock": {"Text": "FEditorStyle.HoverOnlyHyperlink"}}, 48 | { "Padding": [0,4], "Column_Row": [1, 11], "SHyperlink": {"Style":{ "Style": "FEditorStyle", "StyleName": "HoverOnlyHyperlink"}, "Text": "www.link_to_some_where"}}, 49 | {"Column_Row": [0, 12], "STextBlock": {"Text": "FEditorStyle.Credits.Hyperlink"}}, 50 | { "Padding": [0,4], "Column_Row": [1, 12], "SHyperlink": {"Style":{ "Style": "FEditorStyle", "StyleName": "Credits.Hyperlink"}, "Text": "www.link_to_some_where"}}, 51 | {"Column_Row": [0, 13], "STextBlock": {"Text": "FEditorStyle.Common.GotoNativeCodeHyperlink"}}, 52 | { "Padding": [0,4], "Column_Row": [1, 13], "SHyperlink": {"Style":{ "Style": "FEditorStyle", "StyleName": "Common.GotoNativeCodeHyperlink"}, "Text": "www.link_to_some_where"}}, 53 | {"Column_Row": [0, 14], "STextBlock": {"Text": "FEditorStyle.Common.GotoBlueprintHyperlink"}}, 54 | { "Padding": [0,4], "Column_Row": [1, 14], "SHyperlink": {"Style":{ "Style": "FEditorStyle", "StyleName": "Common.GotoBlueprintHyperlink"}, "Text": "www.link_to_some_where"}}, 55 | {"Column_Row": [0, 15], "STextBlock": {"Text": "FEditorStyle.Documentation.Hyperlink"}}, 56 | { "Padding": [0,4], "Column_Row": [1, 15], "SHyperlink": {"Style":{ "Style": "FEditorStyle", "StyleName": "Documentation.Hyperlink"}, "Text": "www.link_to_some_where"}}, 57 | {"Column_Row": [0, 16], "STextBlock": {"Text": "FEditorStyle.Tutorials.Content.Hyperlink"}}, 58 | { "Padding": [0,4], "Column_Row": [1, 16], "SHyperlink": {"Style":{ "Style": "FEditorStyle", "StyleName": "Tutorials.Content.Hyperlink"}, "Text": "www.link_to_some_where"}}, 59 | {"Column_Row": [0, 17], "STextBlock": {"Text": "FEditorStyle.TutorialEditableText.Editor.Hyperlink"}}, 60 | { "Padding": [0,4], "Column_Row": [1, 17], "SHyperlink": {"Style":{ "Style": "FEditorStyle", "StyleName": "TutorialEditableText.Editor.Hyperlink"}, "Text": "www.link_to_some_where"}}, 61 | {"Column_Row": [0, 18], "STextBlock": {"Text": "FEditorStyle.DetailsView.BPMessageHyperlinkStyle"}}, 62 | { "Padding": [0,4], "Column_Row": [1, 18], "SHyperlink": {"Style":{ "Style": "FEditorStyle", "StyleName": "DetailsView.BPMessageHyperlinkStyle"}, "Text": "www.link_to_some_where"}}, 63 | {"Column_Row": [0, 19], "STextBlock": {"Text": "FEditorStyle.NavigationHyperlink"}}, 64 | { "Padding": [0,4], "Column_Row": [1, 19], "SHyperlink": {"Style":{ "Style": "FEditorStyle", "StyleName": "NavigationHyperlink"}, "Text": "www.link_to_some_where"}}, 65 | {"Column_Row": [0, 20], "STextBlock": {"Text": "FCoreStyle.Hyperlink"}}, 66 | { "Padding": [0,4], "Column_Row": [1, 20], "SHyperlink": {"Style":{ "Style": "FCoreStyle", "StyleName": "Hyperlink"}, "Text": "www.link_to_some_where"}}, 67 | {"Column_Row": [0, 21], "STextBlock": {"Text": "FCoreStyle.Hyperlink"}}, 68 | { "Padding": [0,4], "Column_Row": [1, 21], "SHyperlink": {"Style":{ "Style": "FCoreStyle", "StyleName": "Hyperlink"}, "Text": "www.link_to_some_where"}} ] 69 | } 70 | } 71 | ] 72 | } 73 | } 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ChameleonGallery/example_modal_window.json: -------------------------------------------------------------------------------- 1 | { 2 | "TabLabel": "A Modal Window", 3 | "InitTabSize": [400, 200], 4 | "InitTabPosition": [50, 200], 5 | "IsModalWindow": true, 6 | "Root": 7 | { 8 | "SVerticalBox": 9 | { 10 | "Slots": [ 11 | { 12 | "VAlign": "Center", 13 | "HAlign": "Center", 14 | "AutoHeight": true, 15 | "Padding": [0, 10], 16 | "SRichTextBlock": 17 | { 18 | "Text": "Some Title Text" 19 | } 20 | }, 21 | { 22 | "AutoHeight": true, 23 | "Padding": [20, 10], 24 | "SHorizontalBox": 25 | { 26 | "Slots": [ 27 | { 28 | "AutoWidth": true, 29 | "VAlign": "center", 30 | "Padding": [10, 0], 31 | "STextBlock": 32 | { 33 | "Text": "API Key:" 34 | } 35 | }, 36 | { 37 | "SEditableTextBox": 38 | { 39 | "Padding": 5, 40 | "Text": "", 41 | "HintText": "Input your API key" 42 | } 43 | } 44 | ] 45 | } 46 | }, 47 | { 48 | "HAlign": "Right", 49 | "AutoHeight": true, 50 | "Padding": [20, 10], 51 | "SButton": 52 | { 53 | "Text": "Submit", 54 | "HAlign": "Center", 55 | "VAlign": "Center", 56 | "ContentPadding": 10, 57 | "ToolTipText": "Submit", 58 | "OnClick": "unreal.ChameleonData.request_close_modal_window('./ChameleonGallery/example_modal_window.json')" 59 | } 60 | } 61 | ] 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ChameleonSketch/ChameleonSketch.json: -------------------------------------------------------------------------------- 1 | { 2 | "TabLabel": "Chameleon Sketch", 3 | "InitTabSize": [540, 300], 4 | "InitTabPosition": [420, 200], 5 | "InitPyCmd": "import ChameleonSketch, importlib; importlib.reload(ChameleonSketch); sketch = ChameleonSketch.ChameleonSketch.ChameleonSketch(%JsonPath); sketch.mark_python_ready()", 6 | "Root":{ 7 | "SBorder": 8 | { 9 | "BorderImage": 10 | { 11 | "Style": "FCoreStyle", 12 | "Brush": "ToolPanel.GroupBorder" 13 | }, 14 | "ColorAndOpacity":[1,1,1,1], 15 | "Content":{ 16 | "SVerticalBox": 17 | { 18 | "Slots": [ 19 | { 20 | "AutoHeight": true, 21 | "SHorizontalBox": { 22 | "Slots": 23 | [ 24 | { 25 | "AutoWidth": true, 26 | "SImage": { 27 | "Aka": "IsPythonReadyImg", 28 | "Image": { 29 | "Style": "FCoreStyle", 30 | "Brush": "Icons.ErrorWithColor" 31 | }, 32 | "DesiredSizeOverride": [80, 80] 33 | } 34 | }, 35 | { 36 | "AutoWidth": true, 37 | "SImage": { 38 | "Aka": "IsPythonReadyImgB", 39 | "Image": { 40 | "Style": "FCoreStyle", 41 | "Brush": "Icons.SuccessWithColor" 42 | }, 43 | "Visibility": "Collapsed", 44 | "DesiredSizeOverride": [80, 80] 45 | } 46 | }, 47 | { 48 | "SMultiLineEditableTextBox": { 49 | "Text": "Need Add Python Path\nAdd \"your_project/TA/TAPython/Python\" to\nProject Settings: Plugins Python \/ Additional Paths", 50 | "Marshaller": "ChameleonRichText", 51 | "HintText": "This is a SMultiLineEditableTextBox", 52 | "Aka": "IsPythonReadyText", 53 | "ToolTipText": "Read only", 54 | "Margin": 10, 55 | "IsReadOnly": true, 56 | "AutoWrapText": true 57 | } 58 | } 59 | ] 60 | } 61 | }, 62 | 63 | { 64 | "Padding": [0, 5], 65 | 66 | "SMultiLineEditableTextBox": 67 | { 68 | "Margin": 4, 69 | "Text": "This Sketch tool will update all widgets automatically when ChameleonSketch.json changed.", 70 | "OnTextChanged": "print(%)", 71 | "OnTextCommitted": "print('input text: {}'.format(%))", 72 | "AutoWrapText": true 73 | } 74 | }, 75 | { 76 | "SHorizontalBox": { 77 | "Slots": [ 78 | { 79 | "FillWidth": 0.618, 80 | "SMultiLineEditableTextBox": { 81 | "Margin": 4, 82 | "Text": "Modify and try it. Create your UI window in a easy way.", 83 | "OnTextChanged": "print(%)", 84 | "OnTextCommitted": "print('input text: {}'.format(%))", 85 | "AutoWrapText": true 86 | } 87 | }, 88 | { 89 | "FillWidth": 0.382, 90 | "SMultiLineEditableTextBox": { 91 | "Text": "Swidget ", 92 | "Marshaller": "ChameleonRichText", 93 | "HintText": "This is a SMultiLineEditableTextBox", 94 | "ToolTipText": "", 95 | "Margin": 2, 96 | "IsReadOnly": true, 97 | "AutoWrapText": true 98 | } 99 | } 100 | ] 101 | } 102 | }, 103 | { 104 | "SUniformWrapPanel": 105 | { 106 | "EvenRowDistribution": false, 107 | "Slots": [ 108 | {"SImage": { "DesiredSizeOverride": [32, 32], "Image":{ "Style": "FEditorStyle", "Brush": "TreeArrow_Collapsed"}}} 109 | ,{"SImage": { "DesiredSizeOverride": [32, 32], "Image":{ "Style": "FEditorStyle", "Brush": "TreeArrow_Collapsed"}}} 110 | ,{"SImage": { "DesiredSizeOverride": [32, 32], "Image":{ "Style": "FEditorStyle", "Brush": "TreeArrow_Collapsed"}}} 111 | ,{"SImage": { "DesiredSizeOverride": [32, 32], "Image":{ "Style": "FEditorStyle", "Brush": "TreeArrow_Collapsed"}}} 112 | ,{"SImage": { "DesiredSizeOverride": [32, 32], "Image":{ "Style": "FEditorStyle", "Brush": "TreeArrow_Collapsed"}}} 113 | ,{"SImage": { "DesiredSizeOverride": [32, 32], "Image":{ "Style": "FEditorStyle", "Brush": "TreeArrow_Collapsed"}}} 114 | ,{"SImage": { "DesiredSizeOverride": [32, 32], "Image":{ "Style": "FEditorStyle", "Brush": "TreeArrow_Collapsed"}}} 115 | ,{"SImage": { "DesiredSizeOverride": [32, 32], "Image":{ "Style": "FEditorStyle", "Brush": "TreeArrow_Collapsed"}}} 116 | ,{"SImage": { "DesiredSizeOverride": [32, 32], "Image":{ "Style": "FEditorStyle", "Brush": "TreeArrow_Collapsed"}}} 117 | ,{"SImage": { "DesiredSizeOverride": [32, 32], "Image":{ "Style": "FEditorStyle", "Brush": "TreeArrow_Collapsed"}}} 118 | ,{"SImage": { "DesiredSizeOverride": [32, 32], "Image":{ "Style": "FEditorStyle", "Brush": "TreeArrow_Collapsed"}}} 119 | ,{"SImage": { "DesiredSizeOverride": [32, 32], "Image":{ "Style": "FEditorStyle", "Brush": "TreeArrow_Collapsed"}}} 120 | ,{"SImage": { "DesiredSizeOverride": [32, 32], "Image":{ "Style": "FEditorStyle", "Brush": "TreeArrow_Collapsed"}}} 121 | ,{"SImage": { "DesiredSizeOverride": [32, 32], "Image":{ "Style": "FEditorStyle", "Brush": "TreeArrow_Collapsed"}}} 122 | ,{"SImage": { "DesiredSizeOverride": [32, 32], "Image":{ "Style": "FEditorStyle", "Brush": "TreeArrow_Collapsed"}}} 123 | ,{"SImage": { "DesiredSizeOverride": [32, 32], "Image":{ "Style": "FEditorStyle", "Brush": "TreeArrow_Collapsed"}}} 124 | ,{"SImage": { "DesiredSizeOverride": [32, 32], "Image":{ "Style": "FEditorStyle", "Brush": "TreeArrow_Collapsed"}}} 125 | ,{"SImage": { "DesiredSizeOverride": [32, 32], "Image":{ "Style": "FEditorStyle", "Brush": "TreeArrow_Collapsed"}}} 126 | ,{"SImage": { "DesiredSizeOverride": [32, 32], "Image":{ "Style": "FEditorStyle", "Brush": "TreeArrow_Collapsed"}}} 127 | ,{"SImage": { "DesiredSizeOverride": [32, 32], "Image":{ "Style": "FEditorStyle", "Brush": "TreeArrow_Collapsed"}}} 128 | ,{"SImage": { "DesiredSizeOverride": [32, 32], "Image":{ "Style": "FEditorStyle", "Brush": "TreeArrow_Collapsed"}}} 129 | ,{"SImage": { "DesiredSizeOverride": [32, 32], "Image":{ "Style": "FEditorStyle", "Brush": "TreeArrow_Collapsed"}}} 130 | 131 | ] 132 | } 133 | } 134 | ] 135 | } 136 | } 137 | } 138 | } 139 | } 140 | 141 | -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ChameleonSketch/ChameleonSketch.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import time 3 | 4 | import unreal 5 | from Utilities.Utils import Singleton 6 | import random 7 | import os 8 | 9 | class ChameleonSketch(metaclass=Singleton): 10 | def __init__(self, jsonPath): 11 | self.jsonPath = jsonPath 12 | self.data = unreal.PythonBPLib.get_chameleon_data(self.jsonPath) 13 | self.ui_names = ["SMultiLineEditableTextBox", "SMultiLineEditableTextBox_2"] 14 | self.debug_index = 1 15 | self.ui_python_not_ready = "IsPythonReadyImg" 16 | self.ui_python_is_ready = "IsPythonReadyImgB" 17 | self.ui_is_python_ready_text = "IsPythonReadyText" 18 | 19 | print ("ChameleonSketch.Init") 20 | 21 | def mark_python_ready(self): 22 | print("set_python_ready call") 23 | self.data.set_visibility(self.ui_python_not_ready, "Collapsed") 24 | self.data.set_visibility(self.ui_python_is_ready, "Visible") 25 | self.data.set_text(self.ui_is_python_ready_text, "Python Path Ready.") 26 | 27 | def get_texts(self): 28 | for name in self.ui_names: 29 | n = self.data.get_text(name) 30 | print(f"name: {n}") 31 | 32 | def set_texts(self): 33 | for name in self.ui_names: 34 | self.data.set_text(name, ["AAA", "BBB", "CCC", "DDD", "EEE", "FFF"][random.randint(0, 5)]) 35 | 36 | def set_text_one(self): 37 | self.data.set_text(self.ui_names[self.debug_index], ["AAA", "BBB", "CCC", "DDD", "EEE", "FFF"][random.randint(0, 5)] ) 38 | 39 | def get_text_one(self): 40 | print(f"name: {self.data.get_text(self.ui_names[self.debug_index])}") 41 | 42 | def tree(self): 43 | print(time.time()) 44 | names = [] 45 | parent_indices = [] 46 | name_to_index = dict() 47 | for root, folders, files in os.walk(r"D:\UnrealProjects\5_0\RDZ\Content"): 48 | root_name = os.path.basename(root) 49 | if root not in name_to_index: 50 | name_to_index[root] = len(names) 51 | parent_indices.append(-1 if not names else name_to_index[os.path.dirname(root)]) 52 | names.append(root_name) 53 | parent_id = name_to_index[root] 54 | for items in [folders, files]: 55 | for item in items: 56 | names.append(item) 57 | parent_indices.append(parent_id) 58 | print(len(names)) 59 | self.data.set_tree_view_items("TreeViewA", names, parent_indices) 60 | print(time.time()) -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ChameleonSketch/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from . import ChameleonSketch 3 | import importlib 4 | importlib.reload(ChameleonSketch) 5 | -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/Example/Example.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import unreal 3 | 4 | def do_some_things(*args, **kwargs): 5 | unreal.log("do_some_things start:") 6 | for arg in args: 7 | unreal.log(arg) 8 | unreal.log("do_some_things end.") -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/Example/MinimalAsyncTaskExample.json: -------------------------------------------------------------------------------- 1 | { 2 | "TabLabel": "Chameleon Async Example", 3 | "InitTabSize": [350, 186], 4 | "InitTabPosition": [800, 100], 5 | "InitPyCmd": "import Example, importlib; importlib.reload(Example); chameleon_mini_async_example = Example.MinimalAsyncTaskExample.MinimalAsyncTaskExample(%JsonPath); chameleon_mini_async_example.some_slow_tasks()", 6 | "Root":{ 7 | "SBorder": 8 | { 9 | "BorderImage": 10 | { 11 | "Style": "FCoreStyle", 12 | "Brush": "ToolPanel.GroupBorder" 13 | }, 14 | "Content":{ 15 | "SVerticalBox": 16 | { 17 | "Slots": [ 18 | { 19 | "AutoHeight": true, 20 | "SHorizontalBox": 21 | { 22 | "Slots": [ 23 | { 24 | "STextBlock": 25 | { 26 | "Text": "", 27 | "Aka": "TextBlock", 28 | "TextStyle": {"Style": "FEditorStyle", "StyleName": "Credits.H3"}, 29 | "Justification": "Left" 30 | } 31 | }, 32 | { 33 | "AutoWidth": true, 34 | "SThrobber": 35 | { 36 | "NumPieces": 3, 37 | "Aka": "Throbber", 38 | "Animate": "Horizontal" 39 | } 40 | } 41 | ] 42 | } 43 | }, 44 | { 45 | "SHorizontalBox": 46 | { 47 | "Slots": [ 48 | { 49 | "SButton": { 50 | "Text": "Add a 2 seconds 'slow task'", 51 | "HAlign": "Center", 52 | "VAlign": "Center", 53 | "OnClick": "chameleon_mini_async_example.add_slow_task(seconds=2)" 54 | } 55 | } 56 | ] 57 | } 58 | }, 59 | { 60 | "VAlign": "Bottom", 61 | "SEditableTextBox": 62 | { 63 | "IsReadOnly": true, 64 | "Text": "Some readonly text." 65 | } 66 | } 67 | ] 68 | } 69 | } 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/Example/MinimalAsyncTaskExample.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | import unreal 4 | 5 | from Utilities.Utils import Singleton 6 | from Utilities.ChameleonTaskExecutor import ChameleonTaskExecutor 7 | 8 | 9 | class MinimalAsyncTaskExample(metaclass=Singleton): 10 | def __init__(self, json_path:str): 11 | self.json_path = json_path 12 | self.data:unreal.ChameleonData = unreal.PythonBPLib.get_chameleon_data(self.json_path) 13 | 14 | self.executor = ChameleonTaskExecutor(self) 15 | 16 | self.ui_text_block = "TextBlock" 17 | self.ui_throbber = "Throbber" 18 | 19 | 20 | def slow_async_task(self, seconds:float) -> float: 21 | # This slow asynchronous task may involve operations such as file I/O, web requests, or other time-consuming activities. 22 | # Operations involving Unreal Engine assets must be executed on the main thread, NOT within this function. Use unreal.ScopedSlowTask(seconds) and we can have a progress bar. 23 | # 24 | # DON'T modify any Slate widget in this function, as it's running in a different thread. 25 | # The Unreal Engine enforces restrictions on accessing Slate widgets from threads other than the main game thread. 26 | # Refer to SlateGlobals.h: #define SLATE_CROSS_THREAD_CHECK() checkf(IsInGameThread() || IsInSlateThread(), TEXT("Access to Slate is restricted to the GameThread or the SlateLoadingThread!")); 27 | 28 | print(f"instance_fake_task started, it will cost {seconds} second(s).") 29 | time.sleep(seconds) 30 | print(f"instance_fake_task finished., {seconds}s") 31 | 32 | return seconds 33 | 34 | 35 | def show_busy_icon(self, b_busy:bool): 36 | if b_busy: 37 | self.data.set_text(self.ui_text_block, f"Running Task.") 38 | self.data.set_visibility(self.ui_throbber, "Visible") 39 | else: 40 | self.data.set_text(self.ui_text_block, f"All tasks finished.") 41 | self.data.set_visibility(self.ui_throbber, "Collapsed") 42 | 43 | 44 | def add_slow_task(self, seconds:float): 45 | # modify Slate widget in this function, as it's running in the main thread. 46 | self.show_busy_icon(True) 47 | self.executor.submit_task(self.slow_async_task, args=[seconds], on_finish_callback=self.on_task_finish) 48 | 49 | 50 | def on_task_finish(self, future_id:int): 51 | # This function will be called in the main thread. so it's safe to modify Slate widget here. 52 | future = self.executor.get_future(future_id) 53 | if future is None: 54 | unreal.log_warning(f"Can't find future: {future_id}") 55 | else: 56 | self.data.set_text(self.ui_text_block, f"Task done, result: {future.result()}") 57 | if not self.executor.is_any_task_running(): 58 | self.show_busy_icon(False) 59 | 60 | print(f"on_task_finish. Future: {future_id}, result: {future.result()}") 61 | 62 | 63 | def some_slow_tasks(self): 64 | self.show_busy_icon(True) 65 | self.executor.submit_task(self.slow_async_task, args=[2], on_finish_callback=self.on_task_finish) 66 | self.executor.submit_task(self.slow_async_task, args=[3], on_finish_callback=self.on_task_finish) 67 | 68 | -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/Example/MinimalExample.json: -------------------------------------------------------------------------------- 1 | { 2 | "TabLabel": "Example", 3 | "InitTabSize": [200, 123], 4 | "InitTabPosition": [180, 200], 5 | "InitPyCmd": "import Example, importlib; importlib.reload(Example); chameleon_example = Example.MinimalExample.MinimalExample(%JsonPath)", 6 | "Root": 7 | { 8 | "SVerticalBox": 9 | { 10 | "Slots": [ 11 | { 12 | "SButton": { 13 | "Text": "Click Me", 14 | "HAlign": "Center", 15 | "VAlign": "Center", 16 | "OnClick": "chameleon_example.on_button_click()" 17 | } 18 | }, 19 | { 20 | "SEditableTextBox": 21 | { 22 | "IsReadOnly": true, 23 | "Aka": "InfoOutput", 24 | "Text": "" 25 | } 26 | } 27 | ] 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/Example/MinimalExample.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import unreal 3 | from Utilities.Utils import Singleton 4 | 5 | 6 | class MinimalExample(metaclass=Singleton): 7 | def __init__(self, json_path:str): 8 | self.json_path = json_path 9 | self.data:unreal.ChameleonData = unreal.PythonBPLib.get_chameleon_data(self.json_path) 10 | self.ui_output = "InfoOutput" 11 | self.click_count = 0 12 | 13 | def on_button_click(self): 14 | self.click_count += 1 15 | self.data.set_text(self.ui_output, "Clicked {} time(s)".format(self.click_count)) 16 | 17 | -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/Example/__init__.py: -------------------------------------------------------------------------------- 1 | import importlib 2 | 3 | from . import MinimalExample 4 | from . import MinimalAsyncTaskExample 5 | 6 | 7 | importlib.reload(MinimalExample) 8 | importlib.reload(MinimalAsyncTaskExample) 9 | 10 | 11 | -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ImageCompareTools/ComparisonWidget.json: -------------------------------------------------------------------------------- 1 | 2 | "SOverlay": { 3 | "Slots": 4 | [ 5 | { 6 | "SHorizontalBox": 7 | { 8 | "Slots": [ 9 | { 10 | "AutoWidth": true, 11 | "SOverlay": { 12 | 13 | "Slots": 14 | [ 15 | { 16 | "SImage": { 17 | "Aka": "ImageRightBG", 18 | "Tile": "Both", 19 | "BrushSize": [16, 16], 20 | "ImagePathInPlugin": "Resources/BackgroundGrid.png" 21 | } 22 | }, 23 | { 24 | "SImage": { 25 | "Aka": "ImageRight", 26 | "Tile": "NoTile", 27 | "BrushSize": [128, 128], 28 | "ImagePathInPlugin": "Resources/PythonGreyIcon_128.png" 29 | } 30 | } 31 | ] 32 | } 33 | } 34 | 35 | ] 36 | } 37 | }, 38 | { 39 | 40 | "SSplitter": { 41 | "Orientation": "Horizontal", 42 | "PhysicalSplitterHandleSize": 2, 43 | "Slots": [ 44 | { 45 | "SDropTarget": { 46 | "Aka": "DropTargetLeft", 47 | "OverrideBackgroundImagePadding": 0, 48 | "OnDrop": "chameleon_image_compare.on_drop(bLeft=True, %**kwargs)", 49 | "Content":{ 50 | "SHorizontalBox": 51 | { 52 | "Slots": [ 53 | { 54 | "AutoWidth": true, 55 | "SOverlay": { 56 | "Slots": 57 | [ 58 | { 59 | "SImage": { 60 | "Aka": "ImageLeftBG", 61 | "Tile": "Both", 62 | "BrushSize": [16, 16], 63 | "ImagePathInPlugin": "Resources/BackgroundGridRed.png" 64 | } 65 | }, 66 | { 67 | "SImage": { 68 | "Aka": "ImageLeft", 69 | "Tile": "Horizontal", 70 | "BrushSize": [128, 128], 71 | "ImagePathInPlugin": "Resources/Icon128.png" 72 | } 73 | } 74 | ] 75 | } 76 | 77 | } 78 | ] 79 | } 80 | } 81 | } 82 | }, 83 | { 84 | "Value": 0.6, 85 | "SDropTarget": { 86 | "Aka": "DropTargetRight", 87 | "OverrideBackgroundImagePadding": 0, 88 | "OnDrop": "chameleon_image_compare.on_drop(bLeft=False, %**kwargs)" 89 | } 90 | } 91 | ] 92 | } 93 | } 94 | ] 95 | } 96 | 97 | -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ImageCompareTools/ImageCompare.json: -------------------------------------------------------------------------------- 1 | { 2 | "TabLabel": "Image Compare", 3 | "InitTabSize": [400, 250], 4 | "InitTabPosition": [300, 100], 5 | "MenuEntries": ["Tools/Image Compare"], 6 | "Icon": {"style": "ChameleonStyle", "name": "Picture" }, 7 | "InitPyCmd": "import ImageCompareTools, importlib; importlib.reload(ImageCompareTools); chameleon_image_compare = ImageCompareTools.ImageCompare.ImageCompare(%JsonPath)", 8 | "Root": { 9 | "SVerticalBox": 10 | { 11 | "Slots": [ 12 | { 13 | "SScrollBox": { 14 | "Orientation": "Vertical", 15 | "Slots": 16 | [ 17 | { 18 | "SHorizontalBox": 19 | { 20 | "Slots": [ 21 | { 22 | "AutoWidth": true, 23 | "Padding": 4, 24 | "SDPIScaler": { 25 | "Aka": "Scaler", 26 | "DPIScaler": 1, 27 | "Content": { 28 | "ExternalJson": "ComparisonWidget.json" 29 | } 30 | } 31 | } 32 | ] 33 | } 34 | } 35 | ] 36 | } 37 | }, 38 | { 39 | "AutoHeight": true, 40 | "VAlign": "Bottom", 41 | "SHorizontalBox": 42 | { 43 | "Slots": [ 44 | { 45 | "AutoWidth": true, 46 | "SButton": { "Text": "Lit vs Wireframe", "HAlign": "Center", "OnClick": "chameleon_image_compare.set_images_from_viewport()" } 47 | }, 48 | { 49 | "SButton": { "Text": "Viewport -> Left.", "HAlign": "Center", "OnClick": "chameleon_image_compare.set_image_from_viewport(bLeft=True)"} 50 | }, 51 | { 52 | "SButton": { "Text": "Viewport -> Right.", "HAlign": "Center", "OnClick": "chameleon_image_compare.set_image_from_viewport(bLeft=False)"} 53 | } 54 | ] 55 | } 56 | }, 57 | { 58 | "AutoHeight": true, 59 | "VAlign": "Bottom", 60 | "SHorizontalBox": 61 | { 62 | "Slots": [ 63 | { 64 | "VAlign": "Center", 65 | "AutoWidth": true, 66 | "Padding": [0, 0, 10, 0], 67 | "STextBlock": 68 | { 69 | "ColorAndOpacity": [1, 1, 1, 1], 70 | "Text": "Image Scale" 71 | } 72 | }, 73 | { 74 | "SComboBox": { 75 | "Aka": "ScaleComboBox", 76 | "InitiallySelectedItem": "1", 77 | "OptionsSource": [ "0.25", "0.5", "1", "2", "4"], 78 | "OnSelectionChanged": "chameleon_image_compare.on_ui_change_scale(%)" 79 | } 80 | }, 81 | { 82 | "HAlign": "Right", 83 | "SCheckBox": 84 | { 85 | "Content": { 86 | "STextBlock": 87 | { 88 | "Text": "Ignore Texture Alpha" 89 | } 90 | }, 91 | "Padding": 6, 92 | "IsChecked": false, 93 | "Aka": "AlphaCheckBox" 94 | } 95 | } 96 | ] 97 | } 98 | }, 99 | { 100 | "AutoHeight": true, 101 | "VAlign": "Bottom", 102 | "SEditableTextBox": 103 | { 104 | "Aka": "StatusBar", 105 | "Text": "", 106 | "IsReadOnly": true 107 | } 108 | } 109 | ] 110 | } 111 | } 112 | } -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ImageCompareTools/ImageCompare.py: -------------------------------------------------------------------------------- 1 | import unreal 2 | from Utilities.Utils import Singleton 3 | 4 | import math 5 | 6 | try: 7 | import numpy as np 8 | b_use_numpy = True 9 | except: 10 | b_use_numpy = False 11 | 12 | class ImageCompare(metaclass=Singleton): 13 | def __init__(self, json_path:str): 14 | self.json_path = json_path 15 | self.data:unreal.ChameleonData = unreal.PythonBPLib.get_chameleon_data(self.json_path) 16 | self.left_texture_size = (128, 128) 17 | self.right_texture_size = (128, 128) 18 | self.dpi_scale = 1 19 | 20 | self.ui_img_left = "ImageLeft" 21 | self.ui_img_right = "ImageRight" 22 | self.ui_img_right_bg = "ImageRightBG" 23 | self.ui_comparison_widget = "ComparisonWidget" 24 | self.ui_dpi_scaler = "Scaler" 25 | self.ui_status_bar = "StatusBar" 26 | self.ui_ignore_alpha = "AlphaCheckBox" 27 | self.ui_scaler_combobox = "ScaleComboBox" 28 | self.combobox_items = self.data.get_combo_box_items(self.ui_scaler_combobox) 29 | 30 | self.update_status_bar() 31 | 32 | def set_image_from_viewport(self, bLeft): 33 | data, width_height = unreal.PythonBPLib.get_viewport_pixels_as_data() 34 | w, h = width_height.x, width_height.y 35 | 36 | channel_num = int(len(data) / w / h) 37 | 38 | if b_use_numpy: 39 | im = np.fromiter(data, dtype=np.uint8).reshape(w, h, channel_num) 40 | 41 | self.data.set_image_data_from_memory(self.ui_img_left if bLeft else self.ui_img_right, im.ctypes.data, len(data) 42 | , w, h, channel_num=channel_num, bgr=False 43 | , tiling=unreal.SlateBrushTileType.HORIZONTAL if bLeft else unreal.SlateBrushTileType.NO_TILE) 44 | else: 45 | texture = unreal.PythonBPLib.get_viewport_pixels_as_texture() 46 | self.data.set_image_data_from_texture2d(self.ui_img_left if bLeft else self.ui_img_right, texture 47 | , tiling=unreal.SlateBrushTileType.HORIZONTAL if bLeft else unreal.SlateBrushTileType.NO_TILE) 48 | 49 | if bLeft: 50 | self.left_texture_size = (w, h) 51 | else: 52 | self.right_texture_size = (w, h) 53 | 54 | self.update_dpi_by_texture_size() 55 | self.fit_window_size() 56 | 57 | def fit_window_size1(self): 58 | size = unreal.ChameleonData.get_chameleon_desired_size(self.json_path) 59 | 60 | def set_images_from_viewport(self): 61 | unreal.AutomationLibrary.set_editor_viewport_view_mode(unreal.ViewModeIndex.VMI_LIT) 62 | self.set_image_from_viewport(bLeft=True) 63 | unreal.AutomationLibrary.set_editor_viewport_view_mode(unreal.ViewModeIndex.VMI_WIREFRAME) 64 | self.set_image_from_viewport(bLeft=False) 65 | unreal.AutomationLibrary.set_editor_viewport_view_mode(unreal.ViewModeIndex.VMI_LIT) 66 | self.fit_window_size() 67 | self.update_status_bar() 68 | 69 | def update_dpi_by_texture_size(self): 70 | max_size = max(self.left_texture_size[1], self.right_texture_size[1]) 71 | if max_size >= 64: 72 | self.dpi_scale = 1 / math.ceil(max_size / 512) 73 | else: 74 | self.dpi_scale = 4 if max_size <= 16 else 2 75 | 76 | print(f"Set dpi -> {self.dpi_scale }") 77 | self.data.set_dpi_scale(self.ui_dpi_scaler, self.dpi_scale) 78 | 79 | for index, value_str in enumerate(self.combobox_items): 80 | if float(value_str) == self.dpi_scale: 81 | self.data.set_combo_box_selected_item(self.ui_scaler_combobox, index) 82 | break 83 | 84 | def on_ui_change_scale(self, value_str): 85 | self.dpi_scale = float(value_str) 86 | self.data.set_dpi_scale(self.ui_dpi_scaler, self.dpi_scale) 87 | self.fit_window_size() 88 | 89 | def update_status_bar(self): 90 | self.data.set_text(self.ui_status_bar, f"Left: {self.left_texture_size}, Right: {self.right_texture_size} ") 91 | if self.left_texture_size != self.right_texture_size: 92 | self.data.set_color_and_opacity(self.ui_status_bar, unreal.LinearColor(2, 0, 0, 1)) 93 | else: 94 | self.data.set_color_and_opacity(self.ui_status_bar, unreal.LinearColor.WHITE) 95 | def fit_window_size(self): 96 | max_x = max(self.left_texture_size[0], self.right_texture_size[0]) 97 | max_y = max(self.left_texture_size[1], self.right_texture_size[1]) 98 | MIN_WIDTH = 400 99 | MAX_HEIGHT = 900 100 | 101 | self.data.set_chameleon_window_size(self.json_path 102 | , unreal.Vector2D(max(MIN_WIDTH, max_x * self.dpi_scale + 18) 103 | , min(MAX_HEIGHT, max_y * self.dpi_scale + 125)) 104 | ) 105 | 106 | 107 | def on_drop(self, bLeft, **kwargs): 108 | for asset_path in kwargs["assets"]: 109 | asset = unreal.load_asset(asset_path) 110 | if isinstance(asset, unreal.Texture2D): 111 | width = asset.blueprint_get_size_x() 112 | height = asset.blueprint_get_size_y() 113 | 114 | ignore_alpha = self.data.get_is_checked(self.ui_ignore_alpha) 115 | if self.data.set_image_data_from_texture2d(self.ui_img_left if bLeft else self.ui_img_right, asset, ignore_alpha=ignore_alpha): 116 | if bLeft: 117 | self.left_texture_size = (width, height) 118 | else: 119 | self.right_texture_size = (width, height) 120 | self.update_dpi_by_texture_size() 121 | self.fit_window_size() 122 | self.update_status_bar() 123 | break 124 | 125 | 126 | -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ImageCompareTools/__init__.py: -------------------------------------------------------------------------------- 1 | from . import ImageCompare 2 | 3 | import importlib 4 | 5 | importlib.reload(ImageCompare) -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/QueryTools/ObjectDetailViewer.json: -------------------------------------------------------------------------------- 1 | { 2 | "TabLabel": "Object Detail Viewer", 3 | "InitTabSize": [800, 600], 4 | "InitTabPosition": [180, 400], 5 | "InitPyCmd": "import QueryTools; chameleon_objectDetailViewer = QueryTools.ObjectDetailViewer.ObjectDetailViewer(%JsonPath);", 6 | "OnClosePyCmd": "chameleon_objectDetailViewer.on_close()", 7 | "OnMapChangedCmd": "chameleon_objectDetailViewer.on_map_changed(%map_change_type)", 8 | "Root":{ 9 | "SBorder": 10 | { 11 | "BorderImage": 12 | { 13 | "Style": "FCoreStyle", 14 | "Brush": "ToolPanel.GroupBorder" 15 | }, 16 | "ColorAndOpacity":[1,1,1,1], 17 | "Content":{ 18 | "SVerticalBox": 19 | { 20 | "Slots": [ 21 | { 22 | "AutoHeight": true, 23 | "SHorizontalBox": { 24 | "Slots": [ 25 | { 26 | "SSpacer":{} 27 | }, 28 | { 29 | "AutoWidth": true, 30 | "SCheckBox": 31 | { 32 | "Aka": "CheckBoxSingleMode", 33 | "Content": { 34 | "STextBlock": 35 | { 36 | "MinDesiredWidth": 100, 37 | "Justification": "Center", 38 | "Text": "Single Mode" 39 | } 40 | }, 41 | "CheckBoxStyle": { 42 | "Style": "FCoreStyle", 43 | "StyleName": "Menu.ToggleButton" 44 | }, 45 | "IsChecked": true, 46 | "Padding": 6, 47 | "OnCheckStateChanged": "chameleon_objectDetailViewer.on_checkbox_SingleMode_Click(%)" 48 | } 49 | }, 50 | { 51 | "AutoWidth": true, 52 | "SCheckBox": 53 | { 54 | "Aka": "CheckBoxCompareMode", 55 | "Content": { 56 | "STextBlock": 57 | { 58 | "MinDesiredWidth": 100, 59 | "Justification": "Center", 60 | "Text": "Compare Mode" 61 | } 62 | }, 63 | "CheckBoxStyle": { 64 | "Style": "FCoreStyle", 65 | "StyleName": "Menu.ToggleButton" 66 | }, 67 | "Padding": 6, 68 | "OnCheckStateChanged": "chameleon_objectDetailViewer.on_checkbox_CompareMode_Click(%)" 69 | } 70 | }, 71 | { 72 | "SHorizontalBox": { 73 | "Slots": [ 74 | { 75 | "HAlign": "Right", 76 | "SButton": { 77 | "Text": "R", 78 | "ContentPadding": [5, 0], 79 | "Aka": "RefreshCompareButton", 80 | "Visibility": "Collapsed", 81 | "HAlign": "Center", 82 | "VAlign": "Center", 83 | "OnClick": "chameleon_objectDetailViewer.apply_compare_if_needed()" 84 | } 85 | } 86 | ] 87 | } 88 | } 89 | ] 90 | } 91 | }, 92 | { 93 | "AutoHeight": true, 94 | "SHorizontalBox": { 95 | "Slots": [ 96 | { 97 | "SHorizontalBox": { 98 | "Aka": "LeftButtonsGroup", 99 | "Slots": [ 100 | { 101 | "Padding": 2, 102 | "SButton": { 103 | "ContentPadding": 6, 104 | "Text": "Query Asset", 105 | "OnClick": "chameleon_objectDetailViewer.on_button_SelectAsset_click(bRightSide=False)" 106 | } 107 | }, 108 | { 109 | "Padding": 2, 110 | "SButton": { 111 | "ContentPadding": 6, 112 | "Text": "Query Selected", 113 | "OnClick": "chameleon_objectDetailViewer.on_button_QuerySelected_click(bRightSide=False)" 114 | } 115 | }, 116 | { 117 | "Padding": 2, 118 | "SButton": { 119 | "ContentPadding": 6, 120 | "Text": "Query Variable _r", 121 | "OnClick": "if '_r' in globals():\n\tchameleon_objectDetailViewer.on_button_Query_R_click(_r, bRightSide=False)\nelse:\n\tchameleon_objectDetailViewer.log_r_warning()" 122 | } 123 | } 124 | ] 125 | } 126 | }, 127 | { 128 | "SHorizontalBox": { 129 | "Aka": "RightButtonsGroup", 130 | "Visibility": "Collapsed", 131 | "Slots": [ 132 | { 133 | "Padding": 2, 134 | "SButton": { 135 | "ContentPadding": 6, 136 | "Text": "Query Asset Right", 137 | "OnClick": "chameleon_objectDetailViewer.on_button_SelectAsset_click(bRightSide=True)" 138 | } 139 | }, 140 | { 141 | "Padding": 2, 142 | "SButton": { 143 | "ContentPadding": 6, 144 | "Text": "Query Selected Right", 145 | "OnClick": "chameleon_objectDetailViewer.on_button_QuerySelected_click(bRightSide=True)" 146 | } 147 | }, 148 | { 149 | "Padding": 2, 150 | "SButton": { 151 | "ContentPadding": 6, 152 | "Text": "Query Variable _r", 153 | "OnClick": "if '_r' in globals():\n\tchameleon_objectDetailViewer.on_button_Query_R_click(_r, bRightSide=True)\nelse:\n\tchameleon_objectDetailViewer.log_r_warning()" 154 | } 155 | } 156 | ] 157 | } 158 | } 159 | ] 160 | } 161 | }, 162 | { 163 | "AutoHeight": true, 164 | "SHorizontalBox": { 165 | "Slots": [ 166 | { 167 | "Padding": 2, 168 | 169 | "SCheckBox":{ 170 | "Content": 171 | { 172 | "STextBlock": { 173 | "Text": "Show built-in" 174 | } 175 | }, 176 | "ColorAndOpacity": [0, 0.807843, 0.819608, 1], 177 | "OnCheckStateChanged": "chameleon_objectDetailViewer.ui_on_checkbox_ShowBuiltin_state_changed(%)", 178 | "IsChecked": true 179 | } 180 | }, 181 | { 182 | "Padding": 2, 183 | "SCheckBox":{ 184 | "Content": 185 | { 186 | "STextBlock": { 187 | "Text": "Show other callable" 188 | } 189 | }, 190 | "ColorAndOpacity": [0.05, 0.15, 0.8, 1], 191 | "OnCheckStateChanged": "chameleon_objectDetailViewer.ui_on_checkbox_ShowOther_state_changed(%)", 192 | "IsChecked": true 193 | } 194 | }, 195 | { 196 | "Padding": 2, 197 | "SCheckBox":{ 198 | "Content": 199 | { 200 | "STextBlock": { 201 | "Text": "Function With Params" 202 | } 203 | }, 204 | "ColorAndOpacity": [0.5, 0.5, 0.5, 1], 205 | "OnCheckStateChanged": "chameleon_objectDetailViewer.ui_on_checkbox_ShowParamFunction_state_changed(%)", 206 | "IsChecked": true 207 | } 208 | }, 209 | { 210 | "AutoWidth": true, 211 | "Padding": 2, 212 | "SSeparator": { 213 | "Orientation": "Vertical", 214 | "Thickness": 2 215 | } 216 | }, 217 | { 218 | "Padding": 2, 219 | "AutoWidth": true, 220 | "SCheckBox":{ 221 | "Content": 222 | { 223 | "STextBlock": { 224 | "Text": "Show Properties" 225 | } 226 | }, 227 | "ColorAndOpacity": [1, 1, 0, 1], 228 | "OnCheckStateChanged": "chameleon_objectDetailViewer.ui_on_checkbox_ShowProperties_state_changed(%)", 229 | "IsChecked": true 230 | } 231 | }, 232 | { 233 | "Padding": 2, 234 | "AutoWidth": true, 235 | "SCheckBox":{ 236 | "Content": 237 | { 238 | "STextBlock": { 239 | "Text": "Show Editor Properties" 240 | } 241 | }, 242 | "ColorAndOpacity": [0, 0.5, 0, 1], 243 | "OnCheckStateChanged": "chameleon_objectDetailViewer.ui_on_checkbox_ShowEditorProperties_state_changed(%)", 244 | "IsChecked": true 245 | } 246 | } 247 | ] 248 | } 249 | }, 250 | { 251 | "SHorizontalBox": { 252 | "Slots": [ 253 | { 254 | "SVerticalBox": { 255 | "Aka": "LeftDetailGroup", 256 | "Slots": [ 257 | 258 | { 259 | "AutoHeight": true, 260 | "SScrollBox": { 261 | "Orientation": "Horizontal", 262 | "Slots": [ 263 | { 264 | "SBreadcrumbTrail": 265 | { 266 | "Aka": "ObjectHisBreadcrumbLeft", 267 | "type": "string", 268 | "ButtonContentPadding": 1, 269 | "OnCrumbClick": "chameleon_objectDetailViewer.on_breadcrumbtrail_ObjectHisLeft_crumb_click(%)" 270 | } 271 | } 272 | ] 273 | } 274 | }, 275 | { 276 | "AutoHeight": true, 277 | "SEditableTextBox": 278 | { 279 | "Aka": "LabelLeft", 280 | "Text": "", 281 | "IsReadOnly": true 282 | } 283 | }, 284 | { 285 | "AutoHeight": true, 286 | "padding": [1,0], 287 | "SSearchBox": { 288 | "HintText": "Filter Text", 289 | "ToolTipText": "Tool Tip", 290 | "OnTextChanged": "chameleon_objectDetailViewer.on_searchbox_FilterLeft_text_changed(%)", 291 | "OnTextCommitted": "chameleon_objectDetailViewer.on_searchbox_FilterLeft_text_committed(%)", 292 | "SelectAllTextWhenFocused": false, 293 | "DelayChangeNotificationWhiteTyping": false 294 | } 295 | }, 296 | { 297 | "SDropTarget": { 298 | "OnDrop": "chameleon_objectDetailViewer.on_drop(bRightSide=False, %**kwargs)", 299 | "Content": { 300 | "SListView": { 301 | "ItemHeight": 6, 302 | "Aka": "ListViewLeft", 303 | "RichText": true, 304 | "EnableAnimatedScrolling": false, 305 | "SHeaderRow": { 306 | "Columns": [ 307 | { 308 | "DefaultLabel": "Property", 309 | "FillWidth": 0.4 310 | }, 311 | { 312 | "DefaultLabel": "Value", 313 | "FillWidth": 0.6 314 | } 315 | ] 316 | }, 317 | "ListItemsSource": [ 318 | ], 319 | "OnMouseButtonDoubleClick": "chameleon_objectDetailViewer.on_listview_DetailListLeft_mouse_button_double_click(%Index)", 320 | "OnSelectionChanged": "chameleon_objectDetailViewer.ui_on_listview_DetailList_selection_changed(bRight=False)" 321 | } 322 | } 323 | } 324 | } 325 | ] 326 | } 327 | }, 328 | { 329 | "SVerticalBox": { 330 | "Aka": "RightDetailGroup", 331 | "Visibility": "Collapsed", 332 | "Slots": [ 333 | { 334 | "AutoHeight": true, 335 | "SScrollBox": { 336 | "Orientation": "Horizontal", 337 | "Slots": [ 338 | { 339 | "SBreadcrumbTrail": 340 | { 341 | "Aka": "ObjectHisBreadcrumbRight", 342 | "type": "string", 343 | "ButtonContentPadding": 1, 344 | "OnCrumbClick": "chameleon_objectDetailViewer.on_breadcrumbtrail_ObjectHisRight_crumb_click(%)" 345 | } 346 | } 347 | ] 348 | } 349 | }, 350 | { 351 | "AutoHeight": true, 352 | "SEditableTextBox": 353 | { 354 | "Aka": "LabelRight", 355 | "Text": "", 356 | "IsReadOnly": true 357 | } 358 | }, 359 | { 360 | "AutoHeight": true, 361 | "padding": [1,0], 362 | "SSearchBox": { 363 | "HintText": "Filter Text", 364 | "ToolTipText": "Tool Tip", 365 | "OnTextChanged": "chameleon_objectDetailViewer.on_searchbox_FilterRight_text_changed(%)", 366 | "OnTextCommitted": "chameleon_objectDetailViewer.on_searchbox_FilterRight_text_committed(%)", 367 | "SelectAllTextWhenFocused": false, 368 | "DelayChangeNotificationWhiteTyping": false 369 | } 370 | }, 371 | { 372 | "SDropTarget": { 373 | "OnDrop": "chameleon_objectDetailViewer.on_drop(bRightSide=True, %**kwargs)", 374 | "Content": { 375 | "SListView": { 376 | "ItemHeight": 6, 377 | "Aka": "ListViewRight", 378 | "RichText": true, 379 | "EnableAnimatedScrolling": true, 380 | "SHeaderRow": { 381 | "Columns": [ 382 | { 383 | "DefaultLabel": "Property", 384 | "FillWidth": 0.4 385 | }, 386 | { 387 | "DefaultLabel": "Value", 388 | "FillWidth": 0.6 389 | } 390 | ] 391 | }, 392 | "ListItemsSource": [ 393 | ], 394 | "OnMouseButtonDoubleClick": "chameleon_objectDetailViewer.on_listview_DetailListRight_mouse_button_double_click(%Index)", 395 | "OnSelectionChanged": "chameleon_objectDetailViewer.ui_on_listview_DetailList_selection_changed(bRight=True)" 396 | } 397 | } 398 | } 399 | } 400 | ] 401 | } 402 | } 403 | ] 404 | } 405 | }, 406 | { 407 | "AutoHeight": true, 408 | "SMultiLineEditableTextBox": { 409 | "IsReadOnly": true, 410 | "Margin": 4, 411 | "Aka": "InfoOutput", 412 | "Text": " " 413 | } 414 | } 415 | ] 416 | } 417 | } 418 | } 419 | } 420 | } -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/QueryTools/ObjectDetailViewer.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import unreal 3 | import os 4 | from Utilities.Utils import Singleton 5 | from Utilities.Utils import cast 6 | import Utilities 7 | import QueryTools 8 | import re 9 | 10 | import collections 11 | try: 12 | # For Python 3.10 and later 13 | from collections.abc import Iterable 14 | except ImportError: 15 | from collections import Iterable 16 | 17 | import types 18 | 19 | from .import Utils 20 | 21 | global _r 22 | 23 | 24 | COLUMN_COUNT = 2 25 | class DetailData(object): 26 | def __init__(self): 27 | self.filter_str = "" 28 | self.filteredIndexToIndex = [] 29 | self.hisCrumbObjsAndNames = [] #list[(obj, propertyName)] 30 | 31 | self.attributes = None 32 | self.filtered_attributes = None 33 | 34 | self.plains = [] 35 | self.riches = [] 36 | self.selected = set() 37 | 38 | 39 | 40 | 41 | def check_line_id(self, line_id, column_count): 42 | from_line = line_id * column_count 43 | to_line = (line_id + 1) * column_count 44 | assert len(self.plains) == len(self.riches), "len(self.plains) != len(self.riches)" 45 | if 0 <= from_line < len(self.plains) and 0 <= to_line <= len(self.plains): 46 | return True 47 | else: 48 | unreal.log_error(f"Check Line Id Failed: {line_id}, plains: {len(self.plains)}, rich: {len(self.riches)}") 49 | return False 50 | 51 | def get_plain(self, line_id, column_count): 52 | assert self.check_line_id(line_id, column_count), "check line id failed." 53 | return self.plains[line_id * 2 : line_id * 2 + 2] 54 | 55 | def get_rich(self, line_id, column_count): 56 | assert self.check_line_id(line_id, column_count), "check line id failed." 57 | return self.riches[line_id * 2: line_id * 2 + 2] 58 | 59 | 60 | 61 | 62 | class ObjectDetailViewer(metaclass=Singleton): 63 | 64 | def __init__(self, jsonPath): 65 | self.jsonPath = jsonPath 66 | self.data = unreal.PythonBPLib.get_chameleon_data(self.jsonPath) 67 | self.ui_checkbox_single_mode = "CheckBoxSingleMode" 68 | self.ui_checkbox_compare_mode = "CheckBoxCompareMode" 69 | self.ui_left_group = "LeftDetailGroup" 70 | self.ui_right_group = "RightDetailGroup" 71 | self.ui_button_refresh = "RefreshCompareButton" 72 | 73 | self.ui_detailListLeft = "ListViewLeft" 74 | self.ui_detailListRight = "ListViewRight" 75 | self.ui_hisObjsBreadcrumbLeft = 'ObjectHisBreadcrumbLeft' 76 | self.ui_hisObjsBreadcrumbRight = 'ObjectHisBreadcrumbRight' 77 | # self.ui_headRowLeft = "HeaderRowLeft" 78 | # self.ui_headRowRight = "HeaderRowRight" 79 | self.ui_labelLeft = "LabelLeft" 80 | self.ui_labelRight = "LabelRight" 81 | 82 | self.ui_info_output = "InfoOutput" 83 | self.ui_rightButtonsGroup = "RightButtonsGroup" # used for compare mode 84 | self.ui_rightListGroup = "RightListGroup" 85 | self.ui_refreshButtonGroup = "RefreshButtonGroup" 86 | 87 | self.reset() 88 | 89 | def on_close(self): 90 | self.reset() 91 | 92 | def on_map_changed(self, map_change_type_str): 93 | # remove the reference, avoid memory leaking when load another map. 94 | if map_change_type_str == "TearDownWorld": 95 | self.reset(bResetParameter=False) 96 | else: 97 | pass # skip: LoadMap, SaveMap, NewMap 98 | 99 | def reset(self, bResetParameter=True): 100 | if bResetParameter: 101 | self.showBuiltin = True 102 | self.showOther = True 103 | self.showProperties = True 104 | self.showEditorProperties = True 105 | self.showParamFunction = True 106 | 107 | self.compareMode = False 108 | self.left = None 109 | self.right = None 110 | self.leftSearchText = "" 111 | self.rightSearchText = "" 112 | 113 | self.left_rich = None 114 | self.left_plain = None 115 | self.var = None 116 | self.diff_count = 0 117 | self.clear_ui_info() 118 | 119 | 120 | def clear_ui_info(self): 121 | for text_ui in [self.ui_info_output, self.ui_labelLeft, self.ui_labelRight]: 122 | self.data.set_text(text_ui, "") 123 | 124 | self.data.set_list_view_multi_column_items(self.ui_detailListLeft, [], 2) 125 | self.data.set_list_view_multi_column_items(self.ui_detailListRight, [], 2) 126 | 127 | for ui_breadcrumb in [self.ui_hisObjsBreadcrumbRight, self.ui_hisObjsBreadcrumbLeft]: 128 | crumbCount = self.data.get_breadcrumbs_count_string(ui_breadcrumb) 129 | for i in range(crumbCount): 130 | self.data.pop_breadcrumb_string(ui_breadcrumb) 131 | 132 | 133 | def update_log_text(self, bRight): 134 | bShowRight = self.compareMode 135 | result = "" 136 | for side_str in ["left", "right"] if bShowRight else ["left"]: 137 | bRight = side_str != "left" 138 | ui_breadcrumb = self.ui_hisObjsBreadcrumbRight if bRight else self.ui_hisObjsBreadcrumbLeft 139 | breadcrumbs = self.right.hisCrumbObjsAndNames if bRight else self.left.hisCrumbObjsAndNames 140 | crumbCount = self.data.get_breadcrumbs_count_string(ui_breadcrumb) 141 | if bRight: 142 | result += "\t\t\t" 143 | result += "{} crumb: {} hisObj: {}".format(side_str, crumbCount, len(breadcrumbs)) 144 | if self.compareMode: 145 | result = f"{result}\t\t\tdiff count: {self.diff_count}" 146 | self.data.set_text(self.ui_info_output, result) 147 | 148 | def get_color_by(self, attr : Utils.attr_detail): 149 | if attr.bCallable_builtin: 150 | return "DarkTurquoise".lower() 151 | if attr.bCallable_other: 152 | return "RoyalBlue".lower() 153 | if attr.bEditorProperty: 154 | return "LimeGreen".lower() 155 | if attr.bOtherProperty: 156 | return "yellow" 157 | 158 | def get_color(self, typeStr): 159 | if typeStr == "property": 160 | return 'white' 161 | if typeStr == "return_type": 162 | return 'gray' 163 | if typeStr == "param": 164 | return 'gray' 165 | 166 | def get_name_with_rich_text(self, attr:Utils.attr_detail): 167 | name_color = self.get_color_by(attr) 168 | param_color = self.get_color("param") 169 | return_type_color = self.get_color("return_type") 170 | if attr.bProperty: 171 | return "\t{}".format(name_color, attr.name) 172 | else: 173 | if attr.param_str: 174 | return "\t{}({})".format(name_color, attr.name 175 | , param_color, attr.param_str 176 | , name_color) 177 | else: 178 | if attr.bCallable_other: 179 | return "\t{}".format(name_color, attr.name) 180 | else: 181 | return "\t{}() {}".format(name_color, attr.name 182 | , return_type_color, attr.return_type_str) 183 | 184 | def get_name_with_plain_text(self, attr:Utils.attr_detail): 185 | if attr.bProperty: 186 | return "\t{}".format(attr.name) 187 | else: 188 | if attr.param_str: 189 | return "\t{}({})".format( attr.name, attr.param_str) 190 | else: 191 | if attr.bCallable_other: 192 | return "\t{}".format( attr.name) 193 | else: 194 | return "\t{}() {}".format(attr.name,attr.return_type_str) 195 | 196 | def filter(self, data:DetailData): 197 | result = [] 198 | indices = [] 199 | for i, attr in enumerate(data.attributes): 200 | if not self.showEditorProperties and attr.bEditorProperty: 201 | continue 202 | if not self.showProperties and attr.bOtherProperty: 203 | continue 204 | if not self.showParamFunction and attr.bHasParamFunction: 205 | continue 206 | if not self.showBuiltin and attr.bCallable_builtin: 207 | continue 208 | if not self.showOther and attr.bCallable_other: 209 | continue 210 | if data.filter_str: 211 | if data.filter_str.lower() not in attr.display_result.lower() and data.filter_str not in attr.display_name.lower() : 212 | continue 213 | result.append(attr) 214 | indices.append(i) 215 | return result, indices 216 | 217 | def show_data(self, data:DetailData, ui_listView): 218 | flatten_list_items = [] 219 | flatten_list_items_plain = [] 220 | for i, attr in enumerate(data.filtered_attributes): 221 | # print(f"{i}: {attr.name} {attr.display_name}, {attr.display_result} ") 222 | attr.check() 223 | assert attr.display_name, f"display name null {attr.display_name}" 224 | assert isinstance(attr.display_result, str), f"display result null {attr.display_result}" 225 | 226 | result_str = attr.display_result 227 | if len(result_str) > 200: 228 | result_str = result_str[:200] + "......" 229 | flatten_list_items.extend([self.get_name_with_rich_text(attr), result_str]) 230 | flatten_list_items_plain.extend([self.get_name_with_plain_text(attr), result_str]) 231 | 232 | data.riches = flatten_list_items 233 | data.plains = flatten_list_items_plain 234 | data.selected.clear() 235 | 236 | self.data.set_list_view_multi_column_items(ui_listView, flatten_list_items, 2) 237 | 238 | 239 | 240 | def query_and_push(self, obj, propertyName, bPush, bRight): #bPush: whether add Breadcrumb nor not, call by property 241 | if bRight: 242 | ui_Label = self.ui_labelRight 243 | ui_listView = self.ui_detailListRight 244 | ui_breadcrumb = self.ui_hisObjsBreadcrumbRight 245 | else: 246 | ui_Label = self.ui_labelLeft 247 | ui_listView = self.ui_detailListLeft 248 | ui_breadcrumb = self.ui_hisObjsBreadcrumbLeft 249 | 250 | data = self.right if bRight else self.left 251 | 252 | data.attributes = Utils.ll(obj) 253 | 254 | data.filtered_attributes, data.filteredIndexToIndex = self.filter(data) 255 | self.show_data(data, ui_listView) 256 | 257 | # set breadcrumb 258 | if propertyName and len(propertyName) > 0: 259 | label = propertyName 260 | else: 261 | if isinstance(obj, unreal.Object): 262 | label = obj.get_name() 263 | else: 264 | try: 265 | label = obj.__str__() 266 | except TypeError: 267 | label = f"{obj}" 268 | 269 | if bPush: # push 270 | # print(f"%%% push: {propertyName}, label {label}") 271 | data.hisCrumbObjsAndNames.append((obj, propertyName)) 272 | self.data.push_breadcrumb_string(ui_breadcrumb, label, label) 273 | 274 | self.data.set_text(ui_Label, "{} type: {}".format(label, type(obj)) ) 275 | 276 | crumbCount = self.data.get_breadcrumbs_count_string(ui_breadcrumb) 277 | if bRight: 278 | assert len(self.right.hisCrumbObjsAndNames) == crumbCount, "hisCrumbObjsAndNames count not match {} {}".format(len(self.right.hisCrumbObjsAndNames), crumbCount) 279 | else: 280 | assert len(self.left.hisCrumbObjsAndNames) == crumbCount, "hisCrumbObjsAndNames count not match {} {}".format(len(self.left.hisCrumbObjsAndNames), crumbCount) 281 | 282 | self.update_log_text(bRight) 283 | 284 | def clear_and_query(self, obj, bRight): 285 | # first time query 286 | self.data.clear_breadcrumbs_string(self.ui_hisObjsBreadcrumbRight if bRight else self.ui_hisObjsBreadcrumbLeft) 287 | if not self.right: 288 | self.right = DetailData() 289 | if not self.left: 290 | self.left = DetailData() 291 | 292 | data = self.right if bRight else self.left 293 | data.hisCrumbObjsAndNames = [] #clear his-Object at first time query 294 | if bRight: 295 | assert len(self.right.hisCrumbObjsAndNames) == 0, "len(self.right.hisCrumbObjsAndNames) != 0" 296 | else: 297 | assert len(self.left.hisCrumbObjsAndNames) == 0, "len(self.left.hisCrumbObjsAndNames) != 0" 298 | 299 | self.query_and_push(obj, "", bPush=True, bRight= bRight) 300 | self.apply_compare_if_needed() 301 | self.update_log_text(bRight) 302 | 303 | 304 | def update_ui_by_mode(self): 305 | self.data.set_is_checked(self.ui_checkbox_compare_mode, self.compareMode) 306 | self.data.set_is_checked(self.ui_checkbox_single_mode, not self.compareMode) 307 | 308 | bCollapsed = not self.compareMode 309 | self.data.set_collapsed(self.ui_rightButtonsGroup, bCollapsed) 310 | self.data.set_collapsed(self.ui_right_group, bCollapsed) 311 | self.data.set_collapsed(self.ui_button_refresh, bCollapsed) 312 | 313 | 314 | def on_checkbox_SingleMode_Click(self, state): 315 | self.compareMode = False 316 | self.update_ui_by_mode() 317 | 318 | def on_checkbox_CompareMode_Click(self, state): 319 | self.compareMode = True 320 | self.update_ui_by_mode() 321 | 322 | def on_button_Refresh_click(self): 323 | self.apply_compare_if_needed() 324 | 325 | 326 | def on_button_SelectAsset_click(self, bRightSide): 327 | selectedAssets = Utilities.Utils.get_selected_assets() 328 | if len(selectedAssets) == 0: 329 | return 330 | self.clear_and_query(selectedAssets[0], bRightSide) 331 | 332 | def on_button_QuerySelected_click(self, bRightSide): 333 | # query component when any component was selected, otherwise actor 334 | obj = Utilities.Utils.get_selected_comp() 335 | if not obj: 336 | obj = Utilities.Utils.get_selected_actor() 337 | if obj: 338 | self.clear_and_query(obj, bRightSide) 339 | 340 | def on_drop(self, bRightSide, *args, **kwargs): 341 | if "assets" in kwargs and kwargs["assets"]: 342 | asset = unreal.load_asset(kwargs["assets"][0]) 343 | if asset: 344 | self.clear_and_query(asset, bRightSide) 345 | return 346 | if "actors" in kwargs and kwargs["actors"]: 347 | actor = unreal.PythonBPLib.find_actor_by_name(kwargs["actors"][0], unreal.EditorLevelLibrary.get_editor_world()) 348 | if actor: 349 | print(actor) 350 | self.clear_and_query(actor, bRightSide) 351 | return 352 | item_count = 0 353 | for k, v in kwargs.items(): 354 | item_count += len(v) 355 | if item_count == 0: 356 | selected_comp = Utilities.Utils.get_selected_comp() 357 | if selected_comp: 358 | self.clear_and_query(selected_comp, bRightSide) 359 | 360 | def log_r_warning(self): 361 | unreal.log_warning("Assign the global var: '_r' with the MenuItem: 'select X --> _r' on Python Icon menu") 362 | 363 | 364 | def on_button_Query_R_click(self, r_obj, bRightSide=False): 365 | print("on_button_Query_R_click call") 366 | if not r_obj: 367 | return 368 | self.clear_and_query(r_obj, bRightSide) 369 | 370 | 371 | 372 | 373 | def on_list_double_click_do(self, index, bRight): 374 | # print ("on_listview_DetailList_mouse_button_double_click {} bRight: {}".format(index, bRight)) 375 | data = self.right if bRight else self.left 376 | typeBlacklist = [int, float, str, bool] #, types.NotImplementedType] 377 | 378 | real_index = data.filteredIndexToIndex[index] if data.filteredIndexToIndex else index 379 | assert 0 <= real_index < len(data.attributes) 380 | 381 | currentObj, _ = data.hisCrumbObjsAndNames[len(data.hisCrumbObjsAndNames) - 1] 382 | attr_name = data.attributes[real_index].name 383 | 384 | objResult, propertyName = self.try_get_object(data, currentObj, attr_name) 385 | if objResult == NotImplemented: 386 | return 387 | if not objResult or objResult is currentObj: # equal 388 | return 389 | if isinstance(objResult, str) and "skip call" in objResult.lower(): 390 | return 391 | if type(objResult) in typeBlacklist: 392 | return 393 | if isinstance(objResult, Iterable): 394 | if type(objResult[0]) in typeBlacklist: 395 | return 396 | nextObj = objResult[0] 397 | nextPropertyName = str(propertyName) + "[0]" 398 | else: 399 | nextObj = objResult 400 | nextPropertyName = str(propertyName) 401 | self.query_and_push(nextObj, nextPropertyName, bPush=True, bRight=bRight) 402 | 403 | self.apply_compare_if_needed() 404 | self.update_log_text(bRight) 405 | 406 | def on_listview_DetailListRight_mouse_button_double_click(self, index): 407 | self.on_list_double_click_do(index, bRight=True) 408 | 409 | def on_listview_DetailListLeft_mouse_button_double_click(self, index): 410 | self.on_list_double_click_do(index, bRight=False) 411 | 412 | def on_breadcrumbtrail_click_do(self, item, bRight): 413 | ui_hisObjsBreadcrumb = self.ui_hisObjsBreadcrumbRight if bRight else self.ui_hisObjsBreadcrumbLeft 414 | data = self.right if bRight else self.left 415 | count = self.data.get_breadcrumbs_count_string(ui_hisObjsBreadcrumb) 416 | print ("on_breadcrumbtrail_ObjectHis_crumb_click: {} count: {} len(data.hisCrumbObjsAndNames): {}".format(item, count, len(data.hisCrumbObjsAndNames))) 417 | while len(data.hisCrumbObjsAndNames) > count: 418 | data.hisCrumbObjsAndNames.pop() 419 | nextObj, name = data.hisCrumbObjsAndNames[len(data.hisCrumbObjsAndNames) - 1] 420 | if not bRight: 421 | assert self.left.hisCrumbObjsAndNames == data.hisCrumbObjsAndNames, "self.left.hisCrumbObjsAndNames = data.hisCrumbObjsAndNames" 422 | 423 | self.query_and_push(nextObj, name, bPush=False, bRight=False) 424 | self.apply_compare_if_needed() 425 | self.update_log_text(bRight=False) 426 | 427 | def on_breadcrumbtrail_ObjectHisLeft_crumb_click(self, item): 428 | self.on_breadcrumbtrail_click_do(item, bRight=False) 429 | 430 | def on_breadcrumbtrail_ObjectHisRight_crumb_click(self, item): 431 | self.on_breadcrumbtrail_click_do(item, bRight=True) 432 | 433 | def remove_address_str(self, strIn): 434 | return re.sub(r'\(0x[0-9,A-F]{16}\)', '', strIn) 435 | 436 | def apply_compare_if_needed(self): 437 | if not self.compareMode: 438 | return 439 | 440 | lefts = self.left.filtered_attributes if self.left.filtered_attributes else self.left.attributes 441 | rights = self.right.filtered_attributes if self.right.filtered_attributes else self.right.attributes 442 | if not lefts: 443 | lefts = [] 444 | if not rights: 445 | rights = [] 446 | 447 | leftIDs = [] 448 | rightIDs = [] 449 | for i, left_attr in enumerate(lefts): 450 | for j, right_attr in enumerate(rights): 451 | if right_attr.name == left_attr.name: 452 | if right_attr.result != left_attr.result: 453 | if isinstance(right_attr.result, unreal.Transform): 454 | if right_attr.result.is_near_equal(left_attr.result, location_tolerance=1e-20, rotation_tolerance=1e-20, scale3d_tolerance=1e-20): 455 | continue 456 | leftIDs.append(i) 457 | rightIDs.append(j) 458 | break 459 | 460 | self.data.set_list_view_multi_column_selections(self.ui_detailListLeft, leftIDs) 461 | self.data.set_list_view_multi_column_selections(self.ui_detailListRight, rightIDs) 462 | self.diff_count = len(leftIDs) 463 | 464 | 465 | def apply_search_filter(self, text, bRight): 466 | _data = self.right if bRight else self.left 467 | _data.filter_str = text if len(text) else "" 468 | _data.filtered_attributes, _data.filteredIndexToIndex = self.filter(_data) 469 | ui_listView = self.ui_detailListRight if bRight else self.ui_detailListLeft 470 | self.show_data(_data, ui_listView) 471 | self.apply_compare_if_needed() 472 | 473 | 474 | def on_searchbox_FilterLeft_text_changed(self, text): 475 | self.apply_search_filter(text if text is not None else "", bRight=False) 476 | def on_searchbox_FilterLeft_text_committed(self, text): 477 | self.apply_search_filter(text if text is not None else "", bRight=False) 478 | 479 | def on_searchbox_FilterRight_text_changed(self, text): 480 | self.apply_search_filter(text if text is not None else "", bRight=True) 481 | def on_searchbox_FilterRight_text_committed(self, text): 482 | self.apply_search_filter(text if text is not None else "", bRight=True) 483 | 484 | 485 | def apply_filter(self): 486 | _datas = [self.left, self.right] 487 | _isRight = [False, True] 488 | for data, bRight in zip(_datas, _isRight): 489 | if len(data.hisCrumbObjsAndNames) > 0: 490 | nextObj, name = data.hisCrumbObjsAndNames[len(data.hisCrumbObjsAndNames)-1] 491 | self.query_and_push(nextObj, name, bPush=False, bRight=bRight) 492 | self.apply_compare_if_needed() 493 | self.update_log_text(bRight=False) # 494 | 495 | 496 | def try_get_object(self, data, obj, name:str): 497 | index = -1 498 | attribute = None 499 | for i, attr in enumerate(data.attributes): 500 | if attr.name == name: 501 | index = i 502 | attribute = attr 503 | assert index >= 0 504 | return attribute.result, name 505 | 506 | 507 | def ui_on_checkbox_ShowBuiltin_state_changed(self, bEnabled): 508 | self.showBuiltin = bEnabled 509 | self.apply_filter() 510 | def ui_on_checkbox_ShowOther_state_changed(self, bEnabled): 511 | self.showOther = bEnabled 512 | self.apply_filter() 513 | def ui_on_checkbox_ShowProperties_state_changed(self, bEnabled): 514 | self.showProperties = bEnabled 515 | self.apply_filter() 516 | def ui_on_checkbox_ShowEditorProperties_state_changed(self, bEnabled): 517 | self.showEditorProperties = bEnabled 518 | self.apply_filter() 519 | def ui_on_checkbox_ShowParamFunction_state_changed(self, bEnabled): 520 | self.showParamFunction = bEnabled 521 | self.apply_filter() 522 | 523 | def ui_on_listview_DetailList_selection_changed(self, bRight): 524 | data = [self.left, self.right][bRight] 525 | list_view = [self.ui_detailListLeft, self.ui_detailListRight][bRight] 526 | 527 | selected_indices = set(self.data.get_list_view_multi_column_selection(list_view)) 528 | added = selected_indices - data.selected 529 | de_selected = data.selected - selected_indices 530 | 531 | for i, lineId in enumerate(added): 532 | self.data.set_list_view_multi_column_line(list_view, lineId, data.get_plain(lineId, column_count=COLUMN_COUNT) 533 | , rebuild_list=True if i == len(added)-1 and len(de_selected) == 0 else False) 534 | 535 | for i, lineId in enumerate(de_selected): 536 | self.data.set_list_view_multi_column_line(list_view, lineId, data.get_rich(lineId, column_count=COLUMN_COUNT) 537 | , rebuild_list=True if i == len(de_selected)-1 else False) 538 | 539 | data.selected = selected_indices 540 | 541 | -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/QueryTools/Utils.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import logging 3 | 4 | import unreal 5 | import inspect 6 | import types 7 | import Utilities 8 | from collections import Counter 9 | 10 | 11 | class attr_detail(object): 12 | def __init__(self, obj, name:str): 13 | self.name = name 14 | 15 | attr = None 16 | self.bCallable = None 17 | self.bCallable_builtin = None 18 | 19 | try: 20 | if hasattr(obj, name): 21 | attr = getattr(obj, name) 22 | self.bCallable = callable(attr) 23 | self.bCallable_builtin = inspect.isbuiltin(attr) 24 | except Exception as e: 25 | unreal.log(str(e)) 26 | 27 | 28 | 29 | self.bProperty = not self.bCallable 30 | self.result = None 31 | self.param_str = None 32 | self.bEditorProperty = None 33 | self.return_type_str = None 34 | self.doc_str = None 35 | self.property_rw = None 36 | 37 | if self.bCallable: 38 | self.return_type_str = "" 39 | 40 | if self.bCallable_builtin: 41 | if hasattr(attr, '__doc__'): 42 | docForDisplay, paramStr = _simplifyDoc(attr.__doc__) 43 | # print(f"~~~~~ attr: {self.name} docForDisplay: {docForDisplay} paramStr: {paramStr}") 44 | # print(attr.__doc__) 45 | 46 | try: 47 | callable_attr = getattr(obj, self.name) 48 | if callable(callable_attr): 49 | sig = inspect.signature(callable_attr) 50 | args = list(sig.parameters.keys()) 51 | argCount = len(args) 52 | if "self" in args: 53 | argCount -= 1 54 | else: 55 | argCount = -1 56 | except (TypeError, ValueError) as e: 57 | argCount = -1 58 | 59 | if "-> " in docForDisplay: 60 | self.return_type_str = docForDisplay[docForDisplay.find(')') + 1:] 61 | else: 62 | self.doc_str = docForDisplay[docForDisplay.find(')') + 1:] 63 | 64 | if argCount == 0 or (argCount == -1 and (paramStr == '' or paramStr == 'self')): 65 | # Method with No params 66 | 67 | if '-> None' not in docForDisplay or self.name in ["__reduce__", "_post_init"]: 68 | try: 69 | if name == "get_actor_time_dilation" and isinstance(obj, unreal.Object): 70 | # call get_actor_time_dilation will crash engine if actor is get from CDO and has no world. 71 | if obj.get_world(): 72 | # self.result = "{}".format(attr.__call__()) 73 | self.result = attr.__call__() 74 | else: 75 | self.result = "skip call, world == None." 76 | else: 77 | # self.result = "{}".format(attr.__call__()) 78 | self.result = attr.__call__() 79 | except: 80 | self.result = "skip call.." 81 | else: 82 | print(f"docForDisplay: {docForDisplay}, self.name: {self.name}") 83 | self.result = "skip call." 84 | else: 85 | self.param_str = paramStr 86 | self.result = "" 87 | else: 88 | logging.error(f"Can't find p: {self.name} {callable_attr}") 89 | elif self.bCallable_other: 90 | if hasattr(attr, '__doc__'): 91 | if isinstance(attr.__doc__, str): 92 | docForDisplay, paramStr = _simplifyDoc(attr.__doc__) 93 | 94 | if name in ["__str__", "__hash__", "__repr__", "__len__"]: 95 | try: 96 | self.result = "{}".format(attr.__call__()) 97 | except: 98 | self.result = "skip call." 99 | else: 100 | # self.result = "{}".format(getattr(obj, name)) 101 | self.result = getattr(obj, name) 102 | 103 | def post(self, obj): 104 | if self.bOtherProperty and not self.result: 105 | try: 106 | self.result = getattr(obj, self.name) 107 | except: 108 | self.result = "skip call..." 109 | 110 | 111 | 112 | def apply_editor_property(self, obj, type_, rws, descript): 113 | self.bEditorProperty = True 114 | self.property_rw = "[{}]".format(rws) 115 | 116 | try: 117 | self.result = eval('obj.get_editor_property("{}")'.format(self.name)) 118 | except: 119 | self.result = "Invalid" 120 | 121 | 122 | 123 | def __str__(self): 124 | s = f"Attr: {self.name} paramStr: {self.param_str} desc: {self.return_type_str} result: {self.result}" 125 | if self.bProperty: 126 | s += ", Property" 127 | if self.bEditorProperty: 128 | s += ", Eidtor Property" 129 | if self.bOtherProperty: 130 | s += ", Other Property " 131 | if self.bCallable: 132 | s += ", Callable" 133 | if self.bCallable_builtin: 134 | s += ", Callable_builtin" 135 | if self.bCallable_other: 136 | s += ", bCallable_other" 137 | if self.bHasParamFunction: 138 | s+= ", bHasParamFunction" 139 | return s 140 | 141 | 142 | def check(self): 143 | counter = Counter([self.bOtherProperty, self.bEditorProperty, self.bCallable_other, self.bCallable_builtin]) 144 | # print("counter: {}".format(counter)) 145 | if counter[True] == 2: 146 | unreal.log_error(f"{self.name}: {self.bEditorProperty}, {self.bOtherProperty} {self.bCallable_builtin} {self.bCallable_other}") 147 | 148 | 149 | @property 150 | def bOtherProperty(self): 151 | if self.bProperty and not self.bEditorProperty: 152 | return True 153 | return False 154 | 155 | @property 156 | def bCallable_other(self): 157 | if self.bCallable and not self.bCallable_builtin: 158 | return True 159 | return False 160 | 161 | @property 162 | def display_name(self, bRichText=True): 163 | if self.bProperty: 164 | return f"\t{self.name}" 165 | else: 166 | # callable 167 | if self.param_str: 168 | return f"\t{self.name}({self.param_str}) {self.return_type_str}" 169 | else: 170 | if self.bCallable_other: 171 | return f"\t{self.name}" # __hash__, __class__, __eq__ 等 172 | else: 173 | return f"\t{self.name}() {self.return_type_str}" 174 | 175 | @property 176 | def display_result(self) -> str: 177 | if self.bEditorProperty: 178 | return "{} {}".format(self.result, self.property_rw) 179 | else: 180 | return "{}".format(self.result) 181 | 182 | @property 183 | def bHasParamFunction(self): 184 | return self.param_str and len(self.param_str) != 0 185 | 186 | 187 | 188 | 189 | 190 | def ll(obj): 191 | 192 | if obj == NotImplemented or not obj: 193 | return None 194 | if inspect.ismodule(obj): 195 | return None 196 | 197 | result = [] 198 | for x in dir(obj): 199 | attr = attr_detail(obj, x) 200 | result.append(attr) 201 | 202 | 203 | if hasattr(obj, '__doc__') and isinstance(obj, unreal.Object): 204 | editorPropertiesInfos = _getEditorProperties(obj.__doc__, obj) 205 | for name, type_, rws, descript in editorPropertiesInfos: 206 | # print(f"~~ {name} {type} {rws}, {descript}") 207 | 208 | index = -1 209 | for i, v in enumerate(result): 210 | if v.name == name: 211 | index = i 212 | break 213 | if index != -1: 214 | this_attr = result[index] 215 | else: 216 | this_attr = attr_detail(obj, name) 217 | result.append(this_attr) 218 | # unreal.log_warning(f"Can't find editor property: {name}") 219 | 220 | this_attr.apply_editor_property(obj, type_, rws, descript) 221 | 222 | for i, attr in enumerate(result): 223 | attr.post(obj) 224 | 225 | return result 226 | 227 | 228 | def _simplifyDoc(content): 229 | def next_balanced(content, s="(", e = ")" ): 230 | s_pos = -1 231 | e_pos = -1 232 | balance = 0 233 | for index, c in enumerate(content): 234 | match = c == s or c == e 235 | if not match: 236 | continue 237 | balance += 1 if c == s else -1 238 | if c == s and balance == 1 and s_pos == -1: 239 | s_pos = index 240 | if c == e and balance == 0 and s_pos != -1 and e_pos == -1: 241 | e_pos = index 242 | return s_pos, e_pos 243 | return -1, -1 244 | 245 | # bracketS, bracketE = content.find('('), content.find(')') 246 | if not content: 247 | return "", "" 248 | bracketS, bracketE = next_balanced(content, s='(', e = ')') 249 | arrow = content.find('->') 250 | funcDocPos = len(content) 251 | endSign = ['--', '\n', '\r'] 252 | for s in endSign: 253 | p = content.find(s) 254 | if p != -1 and p < funcDocPos: 255 | funcDocPos = p 256 | funcDoc = content[:funcDocPos] 257 | if bracketS != -1 and bracketE != -1: 258 | param = content[bracketS + 1: bracketE].strip() 259 | else: 260 | param = "" 261 | return funcDoc, param 262 | 263 | 264 | def _getEditorProperties(content, obj): 265 | # print("Content: {}".format(content)) 266 | 267 | lines = content.split('\r') 268 | signFound = False 269 | allInfoFound = False 270 | result = [] 271 | for line in lines: 272 | if not signFound and '**Editor Properties:**' in line: 273 | signFound = True 274 | if signFound: 275 | #todo re 276 | # nameS, nameE = line.find('``') + 2, line.find('`` ') 277 | nameS, nameE = line.find('- ``') + 4, line.find('`` ') 278 | if nameS == -1 or nameE == -1: 279 | continue 280 | typeS, typeE = line.find('(') + 1, line.find(')') 281 | if typeS == -1 or typeE == -1: 282 | continue 283 | rwS, rwE = line.find('[') + 1, line.find(']') 284 | if rwS == -1 or rwE == -1: 285 | continue 286 | name = line[nameS: nameE] 287 | type_str = line[typeS: typeE] 288 | rws = line[rwS: rwE] 289 | descript = line[rwE + 2:] 290 | allInfoFound = True 291 | result.append((name, type_str, rws, descript)) 292 | # print(name, type, rws) 293 | if signFound: 294 | if not allInfoFound: 295 | unreal.log_warning("not all info found {}".format(obj)) 296 | else: 297 | unreal.log_warning("can't find editor properties in {}".format(obj)) 298 | return result 299 | 300 | 301 | def log_classes(obj): 302 | print(obj) 303 | print("\ttype: {}".format(type(obj))) 304 | print("\tget_class: {}".format(obj.get_class())) 305 | if type(obj.get_class()) is unreal.BlueprintGeneratedClass: 306 | generatedClass = obj.get_class() 307 | else: 308 | generatedClass = unreal.PythonBPLib.get_blueprint_generated_class(obj) 309 | print("\tgeneratedClass: {}".format(generatedClass)) 310 | print("\tbp_class_hierarchy_package: {}".format(unreal.PythonBPLib.get_bp_class_hierarchy_package(generatedClass))) 311 | 312 | def is_selected_asset_type(types): 313 | selectedAssets = Utilities.Utils.get_selected_assets() 314 | for asset in selectedAssets: 315 | if type(asset) in types: 316 | return True; 317 | return False 318 | 319 | 320 | 321 | -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/QueryTools/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from . import queryTools 3 | from . import ObjectDetailViewer 4 | 5 | -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/QueryTools/queryTools.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import unreal 3 | import Utilities.Utils 4 | 5 | 6 | 7 | def print_refs(packagePath): 8 | print("-" * 70) 9 | results, parentsIndex = unreal.PythonBPLib.get_all_refs(packagePath, True) 10 | print ("resultsCount: {}".format(len(results))) 11 | assert len(results) == len(parentsIndex), "results count not equal parentIndex count" 12 | print("{} Referencers Count: {}".format(packagePath, len(results))) 13 | 14 | def _print_self_and_children(results, parentsIndex, index, gen): 15 | if parentsIndex[index] < -1: 16 | return 17 | print ("{}{}".format("\t" * (gen +1), results[index])) 18 | parentsIndex[index] = -2 19 | for j in range(index + 1, len(parentsIndex), 1): 20 | if parentsIndex[j] == index: 21 | _print_self_and_children(results, parentsIndex, j, gen + 1) 22 | 23 | for i in range(len(results)): 24 | if parentsIndex[i] >= -1: 25 | _print_self_and_children(results, parentsIndex, i, 0) 26 | 27 | 28 | def print_deps(packagePath): 29 | print("-" * 70) 30 | results, parentsIndex = unreal.PythonBPLib.get_all_deps(packagePath, True) 31 | print ("resultsCount: {}".format(len(results))) 32 | assert len(results) == len(parentsIndex), "results count not equal parentIndex count" 33 | print("{} Dependencies Count: {}".format(packagePath, len(results))) 34 | 35 | def _print_self_and_children(results, parentsIndex, index, gen): 36 | if parentsIndex[index] < -1: 37 | return 38 | print ("{}{}".format("\t" * (gen +1), results[index])) 39 | parentsIndex[index] = -2 40 | for j in range(index + 1, len(parentsIndex), 1): 41 | if parentsIndex[j] == index: 42 | _print_self_and_children(results, parentsIndex, j, gen + 1) 43 | 44 | for i in range(len(results)): 45 | if parentsIndex[i] >= -1: 46 | _print_self_and_children(results, parentsIndex, i, 0) 47 | 48 | 49 | def print_related(packagePath): 50 | print_deps(packagePath) 51 | print_refs(packagePath) 52 | 53 | 54 | def print_selected_assets_refs(): 55 | assets = Utilities.Utils.get_selected_assets() 56 | for asset in assets: 57 | print_refs(asset.get_outermost().get_path_name()) 58 | 59 | def print_selected_assets_deps(): 60 | assets = Utilities.Utils.get_selected_assets() 61 | for asset in assets: 62 | print_deps(asset.get_outermost().get_path_name()) 63 | 64 | def print_selected_assets_related(): 65 | assets = Utilities.Utils.get_selected_assets() 66 | for asset in assets: 67 | print_related(asset.get_outermost().get_path_name()) 68 | 69 | 70 | def print_who_used_custom_depth(): 71 | world = unreal.EditorLevelLibrary.get_editor_world() 72 | allActors = unreal.GameplayStatics.get_all_actors_of_class(world, unreal.Actor) 73 | print(len(allActors)) 74 | errorCount = 0 75 | for actor in allActors: 76 | comps = actor.get_components_by_class(unreal.PrimitiveComponent) 77 | for comp in comps: 78 | if comp.render_custom_depth: 79 | errorCount += 1 80 | # v = comp.get_editor_property("custom_depth_stencil_value") 81 | # m = comp.get_editor_property("custom_depth_stencil_write_mask") 82 | print("actor: {} comp: {} enabled Custom depth ".format(actor.get_name(), comp.get_name())) 83 | # errorCount += 1 84 | 85 | print("Custom Depth comps: {}".format(errorCount)) -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ShelfTools/Images/DropHere.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgerchenhp/TAPython_DefaultResources/1d5a223dbdb73a1947f2586e6120c88113b083ad/DefaultPythonSource/TA/TAPython/Python/ShelfTools/Images/DropHere.png -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ShelfTools/Images/LitSphere_40x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgerchenhp/TAPython_DefaultResources/1d5a223dbdb73a1947f2586e6120c88113b083ad/DefaultPythonSource/TA/TAPython/Python/ShelfTools/Images/LitSphere_40x.png -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ShelfTools/Images/Primitive_40x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgerchenhp/TAPython_DefaultResources/1d5a223dbdb73a1947f2586e6120c88113b083ad/DefaultPythonSource/TA/TAPython/Python/ShelfTools/Images/Primitive_40x.png -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ShelfTools/Images/PythonChameleonGreyIcon_40x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgerchenhp/TAPython_DefaultResources/1d5a223dbdb73a1947f2586e6120c88113b083ad/DefaultPythonSource/TA/TAPython/Python/ShelfTools/Images/PythonChameleonGreyIcon_40x.png -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ShelfTools/Images/PythonTextGreyIcon_40x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgerchenhp/TAPython_DefaultResources/1d5a223dbdb73a1947f2586e6120c88113b083ad/DefaultPythonSource/TA/TAPython/Python/ShelfTools/Images/PythonTextGreyIcon_40x.png -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ShelfTools/Images/folderIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgerchenhp/TAPython_DefaultResources/1d5a223dbdb73a1947f2586e6120c88113b083ad/DefaultPythonSource/TA/TAPython/Python/ShelfTools/Images/folderIcon.png -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ShelfTools/Shelf.json: -------------------------------------------------------------------------------- 1 | { 2 | "TabLabel": "Chameleon Shelf Lit", 3 | "InitTabSize": [610, 76], 4 | "InitTabPosition": [180, 110], 5 | "InitPyCmd": "import ShelfTools, importlib; importlib.reload(ShelfTools); chameleon_shelf = ShelfTools.Shelf.Shelf(%JsonPath)", 6 | "OnClosePyCmd": "chameleon_shelf.on_close()", 7 | "Root":{ 8 | "SBorder": 9 | { 10 | "BorderImage": 11 | { 12 | "Style": "FCoreStyle", 13 | "Brush": "ToolPanel.GroupBorder" 14 | }, 15 | "ColorAndOpacity":[1,1,1,1], 16 | "Content": { 17 | "SHorizontalBox": { 18 | "Slots": [ 19 | { 20 | 21 | "SUniformWrapPanel": { 22 | "EvenRowDistribution": false, 23 | 24 | "Slots": [ 25 | { 26 | "SlotPadding": [5, 0], 27 | "SComboButton": { 28 | "ContentPadding": [-20, 0], 29 | "ButtonStyle":{ 30 | "Style": "FEditorStyle", 31 | "StyleName": "ToolbarComboButton" 32 | }, 33 | "ButtonColorAndOpacity": [1, 0, 0, 0], 34 | "ForegroundColor": [1, 0, 0, 1], 35 | "ButtonContent": { 36 | "SBox": { 37 | "MaxDesiredWidth": 32, 38 | "MaxDesiredHeight": 32, 39 | "Content": { 40 | "SImage": { 41 | "Aka": "IsPythonReadyImgB", 42 | "Image": { 43 | "Style": "FEditorStyle", 44 | "Brush": "LevelEditor.GameSettings" 45 | } 46 | ,"DesiredSizeOverride": [30, 30] 47 | } 48 | } 49 | } 50 | }, 51 | "HasDownArrow": false, 52 | "OnGetMenuContent": { 53 | "items": [ 54 | { 55 | "name": "Lock Text", 56 | "Command": "chameleon_shelf.lock_text(True)" 57 | }, 58 | { 59 | "name": "Unlock Text for Editing", 60 | "Command": "chameleon_shelf.lock_text(False)" 61 | }, 62 | { 63 | "name": "Clear All Shelf", 64 | "Command": "chameleon_shelf.clear_shelf()" 65 | } 66 | ] 67 | }, 68 | "HAlign": "Center" 69 | } 70 | }, 71 | //generate start 72 | { 73 | "SBox": { 74 | "Aka": "ButtonGroup_0", "MaxDesiredWidth": 20, "MaxDesiredHeight": 20, 75 | "Content": { 76 | "SDropTarget": { "Aka":"Drop_0", "OnDrop": "chameleon_shelf.on_drop(id=0, %**kwargs)", 77 | "Content": { 78 | "SOverlay": { 79 | "Slots": [{ 80 | "SButton": {"ButtonStyle": {"Style": "FEditorStyle", "StyleName": "HoverHintOnly"}, 81 | "OnClick": "chameleon_shelf.on_button_click(id=0)", 82 | "Content": { "SImage": {"Aka": "Img_0", "ImagePathInPlugin": "Resources/PythonGreyIcon_40x.png", "ColorAndOpacity": [1,1,1,0.6]}} 83 | } 84 | },{ 85 | "Padding": [0, 20, 0, 0], 86 | "SEditableText":{"Aka": "Txt_0", "Text": "", "ColorAndOpacity": [1,1,1,1], "Justification": "Right"} 87 | } 88 | ] 89 | } 90 | } 91 | } 92 | } 93 | } 94 | }, 95 | { 96 | "SBox": { 97 | "Aka": "ButtonGroup_1", "MaxDesiredWidth": 20, "MaxDesiredHeight": 20, 98 | "Content": { 99 | "SDropTarget": { "Aka":"Drop_1", "OnDrop": "chameleon_shelf.on_drop(id=1, %**kwargs)", 100 | "Content": { 101 | "SOverlay": { 102 | "Slots": [{ 103 | "SButton": {"ButtonStyle": {"Style": "FEditorStyle", "StyleName": "HoverHintOnly"}, 104 | "OnClick": "chameleon_shelf.on_button_click(id=1)", 105 | "Content": { "SImage": {"Aka": "Img_1", "ImagePathInPlugin": "Resources/PythonGreyIcon_40x.png", "ColorAndOpacity": [1,1,1,0.6]}} 106 | } 107 | },{ 108 | "Padding": [0, 20, 0, 0], 109 | "SEditableText":{"Aka": "Txt_1", "Text": "", "ColorAndOpacity": [1,1,1,1], "Justification": "Right"} 110 | } 111 | ] 112 | } 113 | } 114 | } 115 | } 116 | } 117 | }, 118 | { 119 | "SBox": { 120 | "Aka": "ButtonGroup_2", "MaxDesiredWidth": 20, "MaxDesiredHeight": 20, 121 | "Content": { 122 | "SDropTarget": { "Aka":"Drop_2", "OnDrop": "chameleon_shelf.on_drop(id=2, %**kwargs)", 123 | "Content": { 124 | "SOverlay": { 125 | "Slots": [{ 126 | "SButton": {"ButtonStyle": {"Style": "FEditorStyle", "StyleName": "HoverHintOnly"}, 127 | "OnClick": "chameleon_shelf.on_button_click(id=2)", 128 | "Content": { "SImage": {"Aka": "Img_2", "ImagePathInPlugin": "Resources/PythonGreyIcon_40x.png", "ColorAndOpacity": [1,1,1,0.6]}} 129 | } 130 | },{ 131 | "Padding": [0, 20, 0, 0], 132 | "SEditableText":{"Aka": "Txt_2", "Text": "", "ColorAndOpacity": [1,1,1,1], "Justification": "Right"} 133 | } 134 | ] 135 | } 136 | } 137 | } 138 | } 139 | } 140 | }, 141 | { 142 | "SBox": { 143 | "Aka": "ButtonGroup_3", "MaxDesiredWidth": 20, "MaxDesiredHeight": 20, 144 | "Content": { 145 | "SDropTarget": { "Aka":"Drop_3", "OnDrop": "chameleon_shelf.on_drop(id=3, %**kwargs)", 146 | "Content": { 147 | "SOverlay": { 148 | "Slots": [{ 149 | "SButton": {"ButtonStyle": {"Style": "FEditorStyle", "StyleName": "HoverHintOnly"}, 150 | "OnClick": "chameleon_shelf.on_button_click(id=3)", 151 | "Content": { "SImage": {"Aka": "Img_3", "ImagePathInPlugin": "Resources/PythonGreyIcon_40x.png", "ColorAndOpacity": [1,1,1,0.6]}} 152 | } 153 | },{ 154 | "Padding": [0, 20, 0, 0], 155 | "SEditableText":{"Aka": "Txt_3", "Text": "", "ColorAndOpacity": [1,1,1,1], "Justification": "Right"} 156 | } 157 | ] 158 | } 159 | } 160 | } 161 | } 162 | } 163 | }, 164 | { 165 | "SBox": { 166 | "Aka": "ButtonGroup_4", "MaxDesiredWidth": 20, "MaxDesiredHeight": 20, 167 | "Content": { 168 | "SDropTarget": { "Aka":"Drop_4", "OnDrop": "chameleon_shelf.on_drop(id=4, %**kwargs)", 169 | "Content": { 170 | "SOverlay": { 171 | "Slots": [{ 172 | "SButton": {"ButtonStyle": {"Style": "FEditorStyle", "StyleName": "HoverHintOnly"}, 173 | "OnClick": "chameleon_shelf.on_button_click(id=4)", 174 | "Content": { "SImage": {"Aka": "Img_4", "ImagePathInPlugin": "Resources/PythonGreyIcon_40x.png", "ColorAndOpacity": [1,1,1,0.6]}} 175 | } 176 | },{ 177 | "Padding": [0, 20, 0, 0], 178 | "SEditableText":{"Aka": "Txt_4", "Text": "", "ColorAndOpacity": [1,1,1,1], "Justification": "Right"} 179 | } 180 | ] 181 | } 182 | } 183 | } 184 | } 185 | } 186 | }, 187 | { 188 | "SBox": { 189 | "Aka": "ButtonGroup_5", "MaxDesiredWidth": 20, "MaxDesiredHeight": 20, 190 | "Content": { 191 | "SDropTarget": { "Aka":"Drop_5", "OnDrop": "chameleon_shelf.on_drop(id=5, %**kwargs)", 192 | "Content": { 193 | "SOverlay": { 194 | "Slots": [{ 195 | "SButton": {"ButtonStyle": {"Style": "FEditorStyle", "StyleName": "HoverHintOnly"}, 196 | "OnClick": "chameleon_shelf.on_button_click(id=5)", 197 | "Content": { "SImage": {"Aka": "Img_5", "ImagePathInPlugin": "Resources/PythonGreyIcon_40x.png", "ColorAndOpacity": [1,1,1,0.6]}} 198 | } 199 | },{ 200 | "Padding": [0, 20, 0, 0], 201 | "SEditableText":{"Aka": "Txt_5", "Text": "", "ColorAndOpacity": [1,1,1,1], "Justification": "Right"} 202 | } 203 | ] 204 | } 205 | } 206 | } 207 | } 208 | } 209 | }, 210 | { 211 | "SBox": { 212 | "Aka": "ButtonGroup_6", "MaxDesiredWidth": 20, "MaxDesiredHeight": 20, 213 | "Content": { 214 | "SDropTarget": { "Aka":"Drop_6", "OnDrop": "chameleon_shelf.on_drop(id=6, %**kwargs)", 215 | "Content": { 216 | "SOverlay": { 217 | "Slots": [{ 218 | "SButton": {"ButtonStyle": {"Style": "FEditorStyle", "StyleName": "HoverHintOnly"}, 219 | "OnClick": "chameleon_shelf.on_button_click(id=6)", 220 | "Content": { "SImage": {"Aka": "Img_6", "ImagePathInPlugin": "Resources/PythonGreyIcon_40x.png", "ColorAndOpacity": [1,1,1,0.6]}} 221 | } 222 | },{ 223 | "Padding": [0, 20, 0, 0], 224 | "SEditableText":{"Aka": "Txt_6", "Text": "", "ColorAndOpacity": [1,1,1,1], "Justification": "Right"} 225 | } 226 | ] 227 | } 228 | } 229 | } 230 | } 231 | } 232 | }, 233 | { 234 | "SBox": { 235 | "Aka": "ButtonGroup_7", "MaxDesiredWidth": 20, "MaxDesiredHeight": 20, 236 | "Content": { 237 | "SDropTarget": { "Aka":"Drop_7", "OnDrop": "chameleon_shelf.on_drop(id=7, %**kwargs)", 238 | "Content": { 239 | "SOverlay": { 240 | "Slots": [{ 241 | "SButton": {"ButtonStyle": {"Style": "FEditorStyle", "StyleName": "HoverHintOnly"}, 242 | "OnClick": "chameleon_shelf.on_button_click(id=7)", 243 | "Content": { "SImage": {"Aka": "Img_7", "ImagePathInPlugin": "Resources/PythonGreyIcon_40x.png", "ColorAndOpacity": [1,1,1,0.6]}} 244 | } 245 | },{ 246 | "Padding": [0, 20, 0, 0], 247 | "SEditableText":{"Aka": "Txt_7", "Text": "", "ColorAndOpacity": [1,1,1,1], "Justification": "Right"} 248 | } 249 | ] 250 | } 251 | } 252 | } 253 | } 254 | } 255 | }, 256 | { 257 | "SBox": { 258 | "Aka": "ButtonGroup_8", "MaxDesiredWidth": 20, "MaxDesiredHeight": 20, 259 | "Content": { 260 | "SDropTarget": { "Aka":"Drop_8", "OnDrop": "chameleon_shelf.on_drop(id=8, %**kwargs)", 261 | "Content": { 262 | "SOverlay": { 263 | "Slots": [{ 264 | "SButton": {"ButtonStyle": {"Style": "FEditorStyle", "StyleName": "HoverHintOnly"}, 265 | "OnClick": "chameleon_shelf.on_button_click(id=8)", 266 | "Content": { "SImage": {"Aka": "Img_8", "ImagePathInPlugin": "Resources/PythonGreyIcon_40x.png", "ColorAndOpacity": [1,1,1,0.6]}} 267 | } 268 | },{ 269 | "Padding": [0, 20, 0, 0], 270 | "SEditableText":{"Aka": "Txt_8", "Text": "", "ColorAndOpacity": [1,1,1,1], "Justification": "Right"} 271 | } 272 | ] 273 | } 274 | } 275 | } 276 | } 277 | } 278 | }, 279 | { 280 | "SBox": { 281 | "Aka": "ButtonGroup_9", "MaxDesiredWidth": 20, "MaxDesiredHeight": 20, 282 | "Content": { 283 | "SDropTarget": { "Aka":"Drop_9", "OnDrop": "chameleon_shelf.on_drop(id=9, %**kwargs)", 284 | "Content": { 285 | "SOverlay": { 286 | "Slots": [{ 287 | "SButton": {"ButtonStyle": {"Style": "FEditorStyle", "StyleName": "HoverHintOnly"}, 288 | "OnClick": "chameleon_shelf.on_button_click(id=9)", 289 | "Content": { "SImage": {"Aka": "Img_9", "ImagePathInPlugin": "Resources/PythonGreyIcon_40x.png", "ColorAndOpacity": [1,1,1,0.6]}} 290 | } 291 | },{ 292 | "Padding": [0, 20, 0, 0], 293 | "SEditableText":{"Aka": "Txt_9", "Text": "", "ColorAndOpacity": [1,1,1,1], "Justification": "Right"} 294 | } 295 | ] 296 | } 297 | } 298 | } 299 | } 300 | } 301 | }, 302 | { 303 | "SBox": { 304 | "Aka": "ButtonGroup_10", "MaxDesiredWidth": 20, "MaxDesiredHeight": 20, 305 | "Content": { 306 | "SDropTarget": { "Aka":"Drop_10", "OnDrop": "chameleon_shelf.on_drop(id=10, %**kwargs)", 307 | "Content": { 308 | "SOverlay": { 309 | "Slots": [{ 310 | "SButton": {"ButtonStyle": {"Style": "FEditorStyle", "StyleName": "HoverHintOnly"}, 311 | "OnClick": "chameleon_shelf.on_button_click(id=10)", 312 | "Content": { "SImage": {"Aka": "Img_10", "ImagePathInPlugin": "Resources/PythonGreyIcon_40x.png", "ColorAndOpacity": [1,1,1,0.6]}} 313 | } 314 | },{ 315 | "Padding": [0, 20, 0, 0], 316 | "SEditableText":{"Aka": "Txt_10", "Text": "", "ColorAndOpacity": [1,1,1,1], "Justification": "Right"} 317 | } 318 | ] 319 | } 320 | } 321 | } 322 | } 323 | } 324 | }, 325 | { 326 | "SBox": { 327 | "Aka": "ButtonGroup_11", "MaxDesiredWidth": 20, "MaxDesiredHeight": 20, 328 | "Content": { 329 | "SDropTarget": { "Aka":"Drop_11", "OnDrop": "chameleon_shelf.on_drop(id=11, %**kwargs)", 330 | "Content": { 331 | "SOverlay": { 332 | "Slots": [{ 333 | "SButton": {"ButtonStyle": {"Style": "FEditorStyle", "StyleName": "HoverHintOnly"}, 334 | "OnClick": "chameleon_shelf.on_button_click(id=11)", 335 | "Content": { "SImage": {"Aka": "Img_11", "ImagePathInPlugin": "Resources/PythonGreyIcon_40x.png", "ColorAndOpacity": [1,1,1,0.6]}} 336 | } 337 | },{ 338 | "Padding": [0, 20, 0, 0], 339 | "SEditableText":{"Aka": "Txt_11", "Text": "", "ColorAndOpacity": [1,1,1,1], "Justification": "Right"} 340 | } 341 | ] 342 | } 343 | } 344 | } 345 | } 346 | } 347 | }, 348 | 349 | //generate end 350 | { 351 | "SBox": {"MinDesiredWidth": 32, "MinDesiredHeight": 32, 352 | "Aka": "DropAtLast", 353 | "Content": { 354 | "SDropTarget": { 355 | 356 | "OnDrop": "chameleon_shelf.on_drop_last(%**kwargs)", 357 | "Content": { 358 | "SImage": { 359 | "Image": { 360 | "Style": "FEditorStyle", 361 | "Brush": "MainFrame.ToggleFullscreen" 362 | }, 363 | "ColorAndOpacity": [1, 1, 1, 0.8] 364 | } 365 | } 366 | } 367 | } 368 | } 369 | }, 370 | { 371 | "SBox": { 372 | "Aka": "DropIsFull", 373 | "MinDesiredWidth": 32, 374 | "MinDesiredHeight": 32, 375 | "Content": { 376 | "SImage": { 377 | "Image": { 378 | "Style": "FEditorStyle", 379 | "Brush": "PlayWorld.PausePlaySession" 380 | }, 381 | "ColorAndOpacity": [1, 1, 1, 0.5] 382 | } 383 | } 384 | } 385 | } 386 | ] 387 | } 388 | } 389 | ] 390 | } 391 | } 392 | } 393 | } 394 | } 395 | 396 | -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ShelfTools/Shelf.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | 4 | import unreal 5 | from Utilities.Utils import Singleton 6 | 7 | 8 | class Shelf(metaclass=Singleton): 9 | ''' 10 | This is a demo tool for showing how to create Chamelon Tools in Python 11 | ''' 12 | MAXIMUM_ICON_COUNT = 12 13 | Visible = "Visible" 14 | Collapsed = "Collapsed" 15 | 16 | def __init__(self, jsonPath:str): 17 | self.jsonPath = jsonPath 18 | self.data = unreal.PythonBPLib.get_chameleon_data(self.jsonPath) 19 | 20 | self.shelf_data = self.load_data() 21 | self.is_text_readonly = True 22 | self.ui_drop_at_last_aka = "DropAtLast" 23 | self.ui_drop_is_full_aka = "DropIsFull" 24 | self.update_ui(bForce=True) 25 | 26 | 27 | def update_ui(self, bForce=False): 28 | visibles = [False] * Shelf.MAXIMUM_ICON_COUNT 29 | for i, shortcut in enumerate(self.shelf_data.shortcuts): 30 | if i >= Shelf.MAXIMUM_ICON_COUNT: 31 | continue 32 | self.data.set_visibility(self.get_ui_button_group_name(i), Shelf.Visible) 33 | self.data.set_tool_tip_text(self.get_ui_button_group_name(i), self.shelf_data.shortcuts[i].get_tool_tips()) 34 | self.data.set_text(self.get_ui_text_name(i), self.shelf_data.shortcuts[i].text) 35 | 36 | # ITEM_TYPE_PY_CMD = 1 ITEM_TYPE_CHAMELEON = 2 ITEM_TYPE_ACTOR = 3 ITEM_TYPE_ASSETS = 4 ITEM_TYPE_ASSETS_FOLDER = 5 37 | icon_name = ["PythonTextGreyIcon_40x.png", "PythonChameleonGreyIcon_40x.png", "LitSphere_40x.png", "Primitive_40x.png", "folderIcon.png"][shortcut.drop_type-1] 38 | if os.path.exists(os.path.join(os.path.dirname(__file__), f"Images/{icon_name}")): 39 | self.data.set_image_from(self.get_ui_img_name(i), f"Images/{icon_name}") 40 | else: 41 | unreal.log_warning("file: {} not exists in this tool's folder: {}".format(f"Images/{icon_name}", os.path.join(os.path.dirname(__file__)))) 42 | visibles[i] = True 43 | 44 | for i, v in enumerate(visibles): 45 | if not v: 46 | self.data.set_visibility(self.get_ui_button_group_name(i), Shelf.Collapsed) 47 | 48 | self.lock_text(self.is_text_readonly, bForce) 49 | bFull = len(self.shelf_data) == Shelf.MAXIMUM_ICON_COUNT 50 | self.data.set_visibility(self.ui_drop_at_last_aka, "Collapsed" if bFull else "Visible") 51 | self.data.set_visibility(self.ui_drop_is_full_aka, "Visible" if bFull else "Collapsed" ) 52 | 53 | 54 | def lock_text(self, bLock, bForce=False): 55 | if self.is_text_readonly != bLock or bForce: 56 | for i in range(Shelf.MAXIMUM_ICON_COUNT): 57 | self.data.set_text_read_only(self.get_ui_text_name(i), bLock) 58 | self.data.set_color_and_opacity(self.get_ui_text_name(i), [1,1,1,1] if bLock else [1,0,0,1]) 59 | self.data.set_visibility(self.get_ui_text_name(i), "HitTestInvisible" if bLock else "Visible" ) 60 | 61 | self.is_text_readonly = bLock 62 | 63 | 64 | def get_ui_button_group_name(self, index): 65 | return f"ButtonGroup_{index}" 66 | 67 | def get_ui_text_name(self, index): 68 | return f"Txt_{index}" 69 | 70 | def get_ui_img_name(self, index): 71 | return f"Img_{index}" 72 | 73 | def on_close(self): 74 | self.save_data() 75 | 76 | def get_data_path(self): 77 | return os.path.join(os.path.dirname(__file__), "saved_shelf.json") 78 | 79 | def load_data(self): 80 | saved_file_path = self.get_data_path() 81 | if os.path.exists(saved_file_path): 82 | return ShelfData.load(saved_file_path) 83 | else: 84 | return ShelfData() 85 | 86 | def save_data(self): 87 | # fetch text from UI 88 | for i, shortcut in enumerate(self.shelf_data.shortcuts): 89 | shortcut.text = self.data.get_text(self.get_ui_text_name(i)) 90 | saved_file_path = self.get_data_path() 91 | if self.shelf_data != None: 92 | ShelfData.save(self.shelf_data, saved_file_path) 93 | else: 94 | unreal.log_warning("data null") 95 | 96 | def clear_shelf(self): 97 | self.shelf_data.clear() 98 | self.update_ui() 99 | 100 | def set_item_to_shelf(self, index, shelf_item): 101 | if index >= len(self.shelf_data): 102 | self.shelf_data.add(shelf_item) 103 | else: 104 | self.shelf_data.set(index, shelf_item) 105 | self.update_ui() 106 | 107 | # add shortcuts 108 | def add_py_code_shortcut(self, index, py_code): 109 | shelf_item = ShelfItem(icon="", drop_type=ShelfItem.ITEM_TYPE_PY_CMD) 110 | shelf_item.py_cmd = py_code 111 | shelf_item.text=py_code[:3] 112 | 113 | self.set_item_to_shelf(index, shelf_item) 114 | 115 | def add_chameleon_shortcut(self, index, chameleon_json): 116 | short_name = os.path.basename(chameleon_json) 117 | if short_name.lower().startswith("chameleon") and len(short_name) > 9: 118 | short_name = short_name[9:] 119 | 120 | shelf_item = ShelfItem(icon="", drop_type=ShelfItem.ITEM_TYPE_CHAMELEON) 121 | shelf_item.chameleon_json = chameleon_json 122 | shelf_item.text = short_name[:3] 123 | self.set_item_to_shelf(index, shelf_item) 124 | 125 | def add_actors_shortcut(self, index, actor_names): 126 | shelf_item = ShelfItem(icon="", drop_type=ShelfItem.ITEM_TYPE_ACTOR) 127 | shelf_item.actors = actor_names 128 | shelf_item.text = shelf_item.actors[0][:3] if shelf_item.actors else "" 129 | shelf_item.text += str(len(shelf_item.actors)) 130 | 131 | self.set_item_to_shelf(index, shelf_item) 132 | 133 | def add_assets_shortcut(self, index, assets): 134 | shelf_item = ShelfItem(icon="", drop_type=ShelfItem.ITEM_TYPE_ASSETS) 135 | shelf_item.assets = assets 136 | if assets: 137 | first_asset = unreal.load_asset(assets[0]) 138 | if first_asset: 139 | shelf_item.text = f"{first_asset.get_name()[:3]}{str(len(shelf_item.assets)) if len(shelf_item.assets)>1 else ''}" 140 | else: 141 | shelf_item.text = "None" 142 | else: 143 | shelf_item.text = "" 144 | 145 | self.set_item_to_shelf(index, shelf_item) 146 | 147 | def add_folders_shortcut(self, index, folders): 148 | shelf_item = ShelfItem(icon="", drop_type=ShelfItem.ITEM_TYPE_ASSETS_FOLDER) 149 | shelf_item.folders = folders 150 | if folders: 151 | shelf_item.text = f"{(os.path.basename(folders[0]))[:3]}{str(len(folders)) if len(folders)>1 else ''}" 152 | else: 153 | shelf_item.text = "" 154 | 155 | self.set_item_to_shelf(index, shelf_item) 156 | 157 | def get_dropped_by_type(self, *args, **kwargs): 158 | py_cmd = kwargs.get("text", "") 159 | 160 | file_names = kwargs.get("files", None) 161 | if file_names: 162 | json_files = [n for n in file_names if n.lower().endswith(".json")] 163 | chameleon_json = json_files[0] if json_files else "" 164 | else: 165 | chameleon_json = "" 166 | 167 | actors = kwargs.get("actors", []) 168 | assets = kwargs.get("assets", []) 169 | folders = kwargs.get("assets_folders", []) 170 | 171 | return py_cmd, chameleon_json, actors, assets, folders 172 | 173 | def on_drop(self, id, *args, **kwargs): 174 | print(f"OnDrop: id:{id} {kwargs}") 175 | py_cmd, chameleon_json, actors, assets, folders = self.get_dropped_by_type(*args, **kwargs) 176 | if chameleon_json: 177 | self.add_chameleon_shortcut(id, chameleon_json) 178 | elif py_cmd: 179 | self.add_py_code_shortcut(id, py_cmd) 180 | elif actors: 181 | self.add_actors_shortcut(id, actors) 182 | elif assets: 183 | self.add_assets_shortcut(id, assets) 184 | elif folders: 185 | self.add_folders_shortcut(id, folders) 186 | else: 187 | print("Drop python snippet, chameleon json, actors or assets.") 188 | 189 | 190 | def on_drop_last(self, *args, **kwargs): 191 | print(f"on drop last: {args}, {kwargs}") 192 | if len(self.shelf_data) <= Shelf.MAXIMUM_ICON_COUNT: 193 | self.on_drop(len(self.shelf_data) + 1, *args, **kwargs) 194 | 195 | 196 | def select_actors(self, actor_names): 197 | actors = [unreal.PythonBPLib.find_actor_by_name(name) for name in actor_names] 198 | unreal.PythonBPLib.select_none() 199 | for i, actor in enumerate(actors): 200 | if actor: 201 | unreal.PythonBPLib.select_actor(actor, selected=True, notify=True, force_refresh= i == len(actors)-1) 202 | 203 | def select_assets(self, assets): 204 | exists_assets = [asset for asset in assets if unreal.EditorAssetLibrary.does_asset_exist(asset)] 205 | unreal.PythonBPLib.set_selected_assets_by_paths(exists_assets) 206 | 207 | def select_assets_folders(self, assets_folders): 208 | print(f"select_assets_folders: {assets_folders}") 209 | unreal.PythonBPLib.set_selected_folder(assets_folders) 210 | 211 | def on_button_click(self, id): 212 | shortcut = self.shelf_data.shortcuts[id] 213 | if not shortcut: 214 | unreal.log_warning("shortcut == None") 215 | return 216 | if shortcut.drop_type == ShelfItem.ITEM_TYPE_PY_CMD: 217 | eval(shortcut.py_cmd) 218 | elif shortcut.drop_type == ShelfItem.ITEM_TYPE_CHAMELEON: 219 | unreal.ChameleonData.launch_chameleon_tool(shortcut.chameleon_json) 220 | elif shortcut.drop_type == ShelfItem.ITEM_TYPE_ACTOR: 221 | self.select_actors(shortcut.actors) # do anything what you want 222 | elif shortcut.drop_type == ShelfItem.ITEM_TYPE_ASSETS: 223 | self.select_assets(shortcut.assets) 224 | elif shortcut.drop_type == ShelfItem.ITEM_TYPE_ASSETS_FOLDER: 225 | self.select_assets_folders(shortcut.folders) 226 | 227 | 228 | class ShelfItem: 229 | ITEM_TYPE_NONE = 0 230 | ITEM_TYPE_PY_CMD = 1 231 | ITEM_TYPE_CHAMELEON = 2 232 | ITEM_TYPE_ACTOR = 3 233 | ITEM_TYPE_ASSETS = 4 234 | ITEM_TYPE_ASSETS_FOLDER = 5 235 | def __init__(self, drop_type, icon=""): 236 | self.drop_type = drop_type 237 | self.icon = icon 238 | self.py_cmd = "" 239 | self.chameleon_json = "" 240 | self.actors = [] 241 | self.assets = [] 242 | self.folders = [] 243 | self.text = "" 244 | def get_tool_tips(self): 245 | if self.drop_type == ShelfItem.ITEM_TYPE_PY_CMD: 246 | return f"PyCmd: {self.py_cmd}" 247 | elif self.drop_type == ShelfItem.ITEM_TYPE_CHAMELEON: 248 | return f"Chameleon Tools: {os.path.basename(self.chameleon_json)}" 249 | elif self.drop_type == ShelfItem.ITEM_TYPE_ACTOR: 250 | return f"{len(self.actors)} actors: {self.actors}" 251 | elif self.drop_type == ShelfItem.ITEM_TYPE_ASSETS: 252 | return f"{len(self.assets)} actors: {self.assets}" 253 | elif self.drop_type == ShelfItem.ITEM_TYPE_ASSETS_FOLDER: 254 | return f"{len(self.folders)} folders: {self.folders}" 255 | 256 | class ShelfData: 257 | def __init__(self): 258 | self.shortcuts = [] 259 | 260 | def __len__(self): 261 | return len(self.shortcuts) 262 | 263 | def add(self, item): 264 | assert isinstance(item, ShelfItem) 265 | self.shortcuts.append(item) 266 | 267 | def set(self, index, item): 268 | assert isinstance(item, ShelfItem) 269 | self.shortcuts[index] = item 270 | 271 | def clear(self): 272 | self.shortcuts.clear() 273 | 274 | @staticmethod 275 | def save(shelf_data, file_path): 276 | with open(file_path, 'w') as f: 277 | f.write(json.dumps(shelf_data, default=lambda o: o.__dict__, sort_keys=True, indent=4)) 278 | print(f"Shelf data saved: {file_path}") 279 | 280 | @staticmethod 281 | def load(file_path): 282 | if not os.path.exists(file_path): 283 | return None 284 | with open(file_path, 'r') as f: 285 | content = json.load(f) 286 | instance = ShelfData() 287 | instance.shortcuts = [] 288 | for item in content["shortcuts"]: 289 | shelf_item = ShelfItem(item["drop_type"], item["icon"]) 290 | shelf_item.py_cmd = item["py_cmd"] 291 | shelf_item.chameleon_json = item["chameleon_json"] 292 | shelf_item.text = item["text"] 293 | shelf_item.actors = item["actors"] 294 | shelf_item.assets = item["assets"] 295 | shelf_item.folders = item["folders"] 296 | 297 | instance.shortcuts.append(shelf_item) 298 | return instance 299 | 300 | -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/ShelfTools/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from . import Shelf 3 | import importlib 4 | importlib.reload(Shelf) 5 | 6 | 7 | -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/Utilities/ChameleonTaskExecutor.py: -------------------------------------------------------------------------------- 1 | import json 2 | from enum import Enum, auto 3 | import inspect 4 | from typing import Callable, Union 5 | 6 | from concurrent.futures import ThreadPoolExecutor, Future 7 | from threading import Lock 8 | 9 | import logging 10 | 11 | import unreal 12 | 13 | logger = logging.getLogger(__name__) 14 | 15 | 16 | class FuncType(Enum): 17 | STATIC_METHOD = auto() 18 | CLASS_METHOD = auto() 19 | LAMBDA = auto() 20 | UNBOUND_METHOD = auto() 21 | INSTANCE_METHOD = auto() 22 | INSTANCE_METHOD_OF_CLASS = auto() 23 | STATIC_FUNCTION = auto() 24 | BUILTIN = auto() 25 | UNKNOWN = auto() 26 | 27 | 28 | def get_func_type(callback: callable, cls=None) -> FuncType: 29 | if isinstance(callback, staticmethod): 30 | return FuncType.STATIC_METHOD 31 | 32 | if not callable(callback): 33 | raise ValueError("callback must be a callable object") 34 | 35 | if cls: 36 | for _, obj in cls.__dict__.items(): 37 | if obj is callback: 38 | if isinstance(obj, staticmethod): 39 | return FuncType.STATIC_METHOD 40 | elif isinstance(obj, classmethod): 41 | return FuncType.CLASS_METHOD 42 | break 43 | elif isinstance(callback, staticmethod): 44 | return FuncType.STATIC_METHOD 45 | 46 | if hasattr(callback, "__name__") and callback.__name__ == "": 47 | return FuncType.LAMBDA 48 | 49 | if inspect.ismethod(callback): 50 | if callback.__self__ is None: 51 | return FuncType.UNBOUND_METHOD 52 | elif isinstance(callback.__self__, type): 53 | return FuncType.CLASS_METHOD 54 | else: 55 | return FuncType.INSTANCE_METHOD 56 | 57 | if inspect.isfunction(callback): 58 | params_names = list(inspect.signature(callback).parameters.keys()) 59 | if params_names and params_names[0] == "self": 60 | return FuncType.INSTANCE_METHOD_OF_CLASS 61 | return FuncType.STATIC_FUNCTION 62 | 63 | if inspect.isbuiltin(callback): 64 | return FuncType.BUILTIN 65 | 66 | return FuncType.UNKNOWN 67 | 68 | 69 | 70 | class ChameleonTaskExecutor: 71 | """ 72 | ChameleonTaskExecutor is a class for managing and executing tasks in parallel. 73 | It uses a ThreadPoolExecutor to run tasks concurrently. 74 | """ 75 | def __init__(self, owner): 76 | """ 77 | Initialize the ChameleonTaskExecutor with the owner of the tasks. 78 | """ 79 | assert isinstance(owner.data, unreal.ChameleonData) 80 | self.owner = owner 81 | self.executor = ThreadPoolExecutor() 82 | self.futures_dict = {} 83 | self.lock = Lock() 84 | 85 | @staticmethod 86 | def _find_var_name_in_outer(target_var, by_type:bool=False)->str: 87 | frames = inspect.getouterframes(inspect.currentframe()) 88 | top_frame = frames[-1] 89 | instance_name_in_global = "" 90 | for k, v in top_frame.frame.f_globals.items(): 91 | if by_type: 92 | if isinstance(v, target_var): 93 | # print(f"!! found: {k} @ frame: frame count: {len(frames)}") 94 | instance_name_in_global = k 95 | break 96 | if type(v) == target_var: 97 | # print(f"!! found: {k} @ frame: frame count: {len(frames)}") 98 | instance_name_in_global = k 99 | break 100 | else: 101 | if v == target_var: 102 | # print(f"!! found: {k} @ frame: frame count: {len(frames)}") 103 | instance_name_in_global = k 104 | break 105 | return instance_name_in_global 106 | 107 | @staticmethod 108 | def _number_of_param(callback)->int: 109 | try: 110 | if isinstance(callback, str): 111 | param_str = callback[callback.find("("): callback.find(")") + 1].strip() 112 | return param_str[1:-1].find(",") 113 | else: 114 | sig = inspect.signature(callback) 115 | param_count = len(sig.parameters) 116 | return param_count 117 | except Exception as e: 118 | print(e) 119 | return 0 120 | 121 | @staticmethod 122 | def _get_balanced_bracket_code(content, file_name, lineno): 123 | def _is_brackets_balanced(content): 124 | v = 0 125 | for c in content: 126 | if c == "(": 127 | v += 1 128 | elif c == ")": 129 | v -= 1 130 | return v == 0 131 | 132 | if "(" in content and _is_brackets_balanced(content): 133 | return content 134 | try: 135 | with open(file_name, 'r', encoding="utf-8") as f: 136 | lines = f.readlines() 137 | 138 | line = "" 139 | for i in range(lineno-1, len(lines)): 140 | line += lines[i].strip() 141 | if "(" in line and _is_brackets_balanced(line): 142 | return line 143 | except Exception as e: 144 | raise RuntimeError(f"Failed to process file {file_name} line {lineno} : {e}") 145 | 146 | return None 147 | 148 | @staticmethod 149 | def get_cmd_str_from_callable(callback: Union[callable, str]) -> str: 150 | """Get the command string from a callable object. The command string is used to call the callable object""" 151 | if isinstance(callback, str): 152 | return callback 153 | callback_type = get_func_type(callback) 154 | if callback_type == FuncType.BUILTIN: 155 | return "{}(%)".format(callback.__qualname__) 156 | elif callback_type == FuncType.LAMBDA: 157 | raise ValueError("Lambda function is not supported") 158 | else: 159 | frames = inspect.getouterframes(inspect.currentframe()) 160 | 161 | last_callable_frame_idx = -1 162 | for i, frame in enumerate(frames): 163 | for var_name, var_value in frame.frame.f_locals.items(): 164 | if callable(var_value) and hasattr(var_value, "__code__"): 165 | if var_value.__code__ == callback.__code__: 166 | last_callable_frame_idx = i 167 | 168 | # The upper frame of the last callable frame is the frame that contains the callback, 169 | # so we can get the code context of the callback from the upper frame 170 | upper_frame = frames[last_callable_frame_idx + 1] if len(frames) > last_callable_frame_idx + 1 else None 171 | 172 | code_context = "".join(upper_frame.code_context) 173 | code_line = ChameleonTaskExecutor._get_balanced_bracket_code(code_context, upper_frame.filename, upper_frame.lineno) 174 | 175 | callback_params = code_line[code_line.index("(") + 1: code_line.rfind(")")].split(",") 176 | 177 | callback_param = "" 178 | for param in callback_params: 179 | if callback.__name__ in param: 180 | callback_param = param if "=" not in param else param[param.index('=')+1:] 181 | break 182 | 183 | if callback_param: 184 | # found 185 | if callback_type == FuncType.INSTANCE_METHOD or callback_param.startswith("self."): 186 | instance_name = ChameleonTaskExecutor._find_var_name_in_outer(upper_frame.frame.f_locals["self"]) 187 | cmd = f"{instance_name}.{callback_param[callback_param.index('.') + 1:]}(%)" 188 | else: 189 | cmd = f"{callback_param}(%)" 190 | return cmd 191 | return f"{callback.__qualname__}(%)" 192 | 193 | 194 | 195 | 196 | def submit_task(self, task:Callable, args=None, kwargs=None, on_finish_callback: Union[Callable, str] = None)-> int: 197 | """ 198 | Submit a task to be executed. The task should be a callable object. 199 | Args and kwargs are optional arguments to the task. 200 | Callback is an optional function to be called when the task is done. 201 | """ 202 | if args is None: 203 | args = [] 204 | if kwargs is None: 205 | kwargs = {} 206 | 207 | future = self.executor.submit(task, *args, **kwargs) 208 | assert future is not None, "future is None" 209 | future_id = id(future) 210 | with self.lock: 211 | self.futures_dict[future_id] = future 212 | 213 | cmd = ChameleonTaskExecutor.get_cmd_str_from_callable(on_finish_callback) 214 | param_count = ChameleonTaskExecutor._number_of_param(on_finish_callback) 215 | 216 | cmd = cmd.replace("%", str(future_id) if param_count else "") 217 | 218 | def _func(_future): 219 | unreal.PythonBPLib.exec_python_command(cmd, force_game_thread=True) 220 | 221 | future.add_done_callback(_func) 222 | 223 | unreal.log(f"submit_task callback cmd: {cmd}, param_count: {param_count}") 224 | 225 | return future_id 226 | 227 | def get_future(self, future_id)-> Future: 228 | with self.lock: 229 | return self.futures_dict.get(future_id, None) 230 | 231 | def get_task_is_running(self, future_id)-> bool: 232 | future = self.get_future(future_id) 233 | if future is not None: 234 | return future.running() 235 | return False 236 | 237 | def is_any_task_running(self): 238 | for future_id in self.futures_dict.keys(): 239 | if self.get_task_is_running(future_id): 240 | return True 241 | return False -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/Utilities/DisUnrealStub.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import os 3 | import logging 4 | 5 | """ 6 | This script is used to split the unreal.py into multiple files. For better auto-completion in IDE. 7 | more info: https://www.tacolor.xyz/tapython/auto_complete_for_tapython.html 8 | """ 9 | 10 | def split_stub(file_path, targetFolder): 11 | with open(file_path, 'r', encoding='utf-8') as f: 12 | lines = f.readlines() 13 | doc_ranges = [] 14 | 15 | class_name = "_Global" 16 | last_line_number = 0 17 | for line_number, line in enumerate(lines): 18 | if line[0:6] == "class " and line[:-1]: 19 | last_class_name = class_name 20 | class_name = line[6: line.find('(') ] 21 | print("{} Class Name: {} line: {}".format(line_number, last_class_name, line.strip())) 22 | doc_ranges.append([last_line_number, line_number, last_class_name]) 23 | last_line_number = line_number 24 | # add the last content 25 | doc_ranges.append([last_line_number, len(lines)-1, class_name]) 26 | 27 | if not os.path.exists(targetFolder): 28 | os.makedirs(targetFolder) 29 | 30 | init_py_file_path = os.path.join(targetFolder, "__init__.py") 31 | init_lines = [] 32 | for start, end, class_name in doc_ranges: 33 | with open(f"{targetFolder}/{class_name}.py", 'w', encoding='utf-8') as f: 34 | f.writelines(lines[start:end]) 35 | init_lines.append(f"from .{class_name} import *\n") 36 | 37 | with open(init_py_file_path, 'w', encoding="UTF-8") as f: 38 | f.writelines(init_lines) 39 | 40 | if __name__ == "__main__": 41 | local_folder = os.path.dirname(__file__) 42 | stub_folder = os.path.join(local_folder, "../../../..", "Intermediate/PythonStub") 43 | latest_unreal_py = os.path.abspath(os.path.join(stub_folder, "unreal.py")) 44 | 45 | if os.path.exists(os.path.exists(latest_unreal_py)): 46 | target_folder = os.path.abspath(os.path.join(local_folder, "..", "unreal")) 47 | split_stub(file_path=latest_unreal_py, targetFolder=target_folder) 48 | print("unreal stub has export to: {}".format(target_folder)) 49 | else: 50 | logging.warning(f"Can't find the stub file: {latest_unreal_py}. Please turn on Developer Mode in UE Editor Preferences > Plugins > Python.") 51 | 52 | -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/Python/Utilities/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from . Utils import * 3 | -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/UI/HotkeyConfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "Hotkeys": 3 | { 4 | "HotkeyA": { 5 | "ChameleonTools": "../Python/ChameleonGallery/ChameleonGallery.json" 6 | }, 7 | "HotkeyB": { 8 | "command": "unreal.EditorLevelLibrary.set_selected_level_actors([actor for actor in unreal.EditorLevelLibrary.get_all_level_actors() if len(str(actor.get_name())) > 60])" 9 | }, 10 | "HotkeyC": { 11 | "command": "print('Hotkey C')" 12 | }, 13 | "HotkeyD": { 14 | "command": "print('Hotkey D')" 15 | }, 16 | "HotkeyE": { 17 | "command": "print('Hotkey E')" 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /DefaultPythonSource/TA/TAPython/UI/MenuConfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "OnSelectFolderMenu": 3 | { 4 | "name:": "Python Menu OnSelectFolderMenu", 5 | "items": 6 | [ 7 | { 8 | "name": "TA Python Example", 9 | "items": [ 10 | { 11 | "name": "Example (1): Log Folder Name", 12 | "command": "from Example import Example; Example.do_some_things(unreal.PythonBPLib.get_selected_folder())" 13 | }, 14 | { 15 | "name": "Example (2): Sub Menu", 16 | "items": [ 17 | { 18 | "name": "A item in sub menu.", 19 | "command": "print('sub menu clicked')" 20 | }, 21 | { 22 | "name": "Another item in sub menu.", 23 | "command": "print('Another sub menu clicked')" 24 | } 25 | ] 26 | } 27 | ] 28 | } 29 | ] 30 | }, 31 | "OnSelectAssetsMenu": 32 | { 33 | "name:": "Python Menu OnSelectAssetsMenu", 34 | "items": 35 | [ 36 | { 37 | "name": "TA Python Example", 38 | "items": [ 39 | { 40 | "name": "Example (3): Log BP Classes", 41 | "tooltip": "Only Active when Blueprint selected", 42 | "command": "import Utilities, QueryTools; QueryTools.Utils.log_classes(Utilities.Utils.get_selected_assets()[0]) ", 43 | "canExecuteAction": "import QueryTools; return QueryTools.Utils.is_selected_asset_type([unreal.Blueprint])" 44 | } 45 | ] 46 | } 47 | ] 48 | }, 49 | "OnMainMenu": 50 | { 51 | "name": "Python Menu On Main Menu", 52 | "items": 53 | [ 54 | { 55 | "name": "TA Python Example", 56 | "items": [ 57 | { 58 | "name": "Example (4): Waiting for your tools", 59 | "command": "print('Hello world.')" 60 | } 61 | ] 62 | } 63 | ] 64 | }, 65 | "OnToolbar": 66 | { 67 | "name": "Python Menu on toolbar", 68 | "items":[ 69 | { 70 | "name": "Get Selected", 71 | "items": [ 72 | { 73 | "name": "selected comp --> '_r'", 74 | "command": "import Utilities.Utils; _r = Utilities.Utils.get_selected_comp(); print(_r)", 75 | "tooltip": "Assign the first selected Component to global var: '_r', for experiments in the Python Console" 76 | }, 77 | { 78 | "name": "selected actor --> '_r'", 79 | "command": "import Utilities.Utils; _r = Utilities.Utils.get_selected_actor(); print(_r)", 80 | "tooltip": "Assign the first selected Actor to global var: '_r', for experiments in the Python Console" 81 | }, 82 | { 83 | "name": "selected asset --> '_r'", 84 | "command": "import Utilities.Utils; _r = Utilities.Utils.get_selected_assets(); _r = _r[0] if len(_r) > 0 else _r; print(_r)", 85 | "tooltip": "Assign the first selected Asset to global var: '_r', for experiments in the Python Console" 86 | } 87 | ] 88 | }, 89 | { 90 | "name": "Query Tools", 91 | "items": [ 92 | { 93 | "name": "Print Selected Assets References", 94 | "command": "import QueryTools; QueryTools.queryTools.print_selected_assets_refs()" 95 | }, 96 | { 97 | "name": "Print Selected Assets Dependencies", 98 | "command": "import QueryTools; QueryTools.queryTools.print_selected_assets_deps()" 99 | }, 100 | { 101 | "name": "Print Selected Assets Related", 102 | "command": "import QueryTools; QueryTools.queryTools.print_selected_assets_related()" 103 | } 104 | ] 105 | }, 106 | { 107 | "name": "Development", 108 | "items": [ 109 | { 110 | "name": "GC keepFlag = 0x00000000", 111 | "command": "unreal.PythonBPLib.gc(0x00000000, False)", 112 | "enabled": true 113 | }, 114 | { 115 | "name": "GC keepFlag = 0xFFFFFFFF", 116 | "command": "unreal.PythonBPLib.gc(0xFFFFFFFF, False)", 117 | "enabled": true 118 | } 119 | ] 120 | }, 121 | { 122 | "name": "Open simple tool", 123 | "command": "import entry; reload(entry); entry.launch_tools('SimpleTools')", 124 | "enabled": false 125 | } 126 | ] 127 | }, 128 | "OnToolBarChameleon": { 129 | "name": "Python Chameleon on toolbar", 130 | "items": [ 131 | { 132 | "name": "Minimal Example", 133 | "ChameleonTools": "../Python/Example/MinimalExample.json", 134 | "icon": { 135 | "style": "ChameleonStyle", 136 | "name": "Flash" 137 | } 138 | }, 139 | { 140 | "name": "Minimal AsyncTask Example", 141 | "ChameleonTools": "../Python/Example/MinimalAsyncTaskExample.json", 142 | "icon": { 143 | "ImagePathInPlugin": "Resources/flash_32x.png" 144 | } 145 | }, 146 | { 147 | "name": "Chameleon Widget Gallery", 148 | "ChameleonTools": "../Python/ChameleonGallery/ChameleonGallery.json", 149 | "icon": { 150 | "style": "ChameleonStyle", 151 | "name": "Picture" 152 | } 153 | }, 154 | { 155 | "name": "Chameleon Shelf Tool", 156 | "ChameleonTools": "../Python/ShelfTools/Shelf.json", 157 | "icon": { 158 | "ImagePathInPlugin": "Resources/briefcase_32x.png" 159 | } 160 | }, 161 | { 162 | "name": "Development", 163 | "icon": { 164 | "ImagePathInPlugin": "Resources/Chameleon_32x.png" 165 | }, 166 | "items": [ 167 | { 168 | "name": "Object Detail Viewer", 169 | "ChameleonTools": "../Python/QueryTools/ObjectDetailViewer.json", 170 | "enabled": true, 171 | "icon": { 172 | "style": "ChameleonStyle", 173 | "name": "List" 174 | } 175 | } 176 | ] 177 | } 178 | ] 179 | }, 180 | "OnOutlineMenu": { 181 | "name:": "Python Menu On OutlineMenu", 182 | "items": 183 | [ 184 | { 185 | "name": "Print selected actors", 186 | "command": "print(unreal.get_editor_subsystem(unreal.EditorActorSubsystem).get_selected_level_actors())" 187 | } 188 | ] 189 | }, 190 | "OnMaterialEditorMenu": { 191 | "name": "Python Menu On Material Editor", 192 | "items": 193 | [ 194 | { 195 | "name": "TA Python Material Example", 196 | "items": [ 197 | { 198 | "name": "Print Editing Material / MF", 199 | "command": "print(%asset_paths)" 200 | }, 201 | { 202 | "name": "Log Editing Nodes", 203 | "command": "editing_asset = unreal.load_asset(%asset_paths[0]); unreal.PythonMaterialLib.log_editing_nodes(editing_asset)" 204 | }, 205 | { 206 | "name": "Selected Nodes --> global variable _r", 207 | "command": "_r = unreal.PythonMaterialLib.get_selected_nodes_in_material_editor(unreal.load_asset(%asset_paths[0]))" 208 | }, 209 | { 210 | "name": "Selected Node --> _r", 211 | "command": "_r = unreal.PythonMaterialLib.get_selected_nodes_in_material_editor(unreal.load_asset(%asset_paths[0]))[0]" 212 | } 213 | ] 214 | } 215 | ] 216 | }, 217 | "OnTabContextMenu":{ 218 | "name": "TA Python Tab", 219 | "items": [ 220 | { 221 | "name": "Log tool's json path", 222 | "command": "print(%tool_path)" 223 | }, 224 | { 225 | "name": "Log instance variable name", 226 | "command": "import Utilities; Utilities.Utils.guess_instance_name(%tool_path)" 227 | }, 228 | { 229 | "name": "Reload this tool", 230 | "command": "unreal.ChameleonData.request_close(%tool_path); unreal.ChameleonData.launch_chameleon_tool(%tool_path)" 231 | } 232 | ] 233 | } 234 | } -------------------------------------------------------------------------------- /Images/001_tools_preview_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgerchenhp/TAPython_DefaultResources/1d5a223dbdb73a1947f2586e6120c88113b083ad/Images/001_tools_preview_small.png -------------------------------------------------------------------------------- /Images/002_python_plugin_tiltle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgerchenhp/TAPython_DefaultResources/1d5a223dbdb73a1947f2586e6120c88113b083ad/Images/002_python_plugin_tiltle.png -------------------------------------------------------------------------------- /Images/021_tapython_plugin_title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgerchenhp/TAPython_DefaultResources/1d5a223dbdb73a1947f2586e6120c88113b083ad/Images/021_tapython_plugin_title.png -------------------------------------------------------------------------------- /Images/G000_SketchEditing.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cgerchenhp/TAPython_DefaultResources/1d5a223dbdb73a1947f2586e6120c88113b083ad/Images/G000_SketchEditing.gif -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 ChenHP 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TAPython_DefaultResources 2 | This repo contains the UE Plugin [TAPython](https://tacolor.xyz/pages/TAPython.html) Default Resources. Both menu and demo tools created by [TAPython](https://tacolor.xyz/pages/TAPython.html). 3 | 4 | ![plugin title](Images/021_tapython_plugin_title.png) 5 | 6 | ![plugin title](Images/001_tools_preview_small.png) 7 | 8 | ![Sketch Editing](Images/G000_SketchEditing.gif) 9 | 10 | 11 | 12 | ## Documentation of the TAPython 13 | - [Widget Gallery](https://tacolor.xyz/pages/ChameleonGallery.html) 14 | 15 | - [Supported Slates](https://tacolor.xyz/pages/SupportedSlates.html) 16 | 17 | - [ChameleonData API](https://tacolor.xyz/pages/ChameleonDataAPI.html) 18 | 19 | - [PythonLib API](https://tacolor.xyz/pages/PythonEditorLib.html) 20 | 21 | 22 | 23 | 24 | ## branches: 25 | 26 | - master: The latest DefaultResources for latest [Unreal Engine](https://www.unrealengine.com), current is UE 5.0 preview 1 27 | - 5_0_ea: The DefaultResources for Unreal Engine 5.0 EA 28 | 29 | 30 | UE4.26, 4.27 branches will coming soon. 31 | 32 | 33 | 34 | 35 | --------------------------------------------------------------------------------