sltgui 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sltgui-0.2.0/.github/FUNDING.yml +3 -0
- sltgui-0.2.0/.github/workflows/publish_to_pypi.yml +43 -0
- sltgui-0.2.0/.github/workflows/publish_to_testpypi.yml +24 -0
- sltgui-0.2.0/.gitignore +221 -0
- sltgui-0.2.0/.python-version +1 -0
- sltgui-0.2.0/.vscode/launch.json +23 -0
- sltgui-0.2.0/.vscode/settings.json +3 -0
- sltgui-0.2.0/LICENSE +21 -0
- sltgui-0.2.0/PKG-INFO +113 -0
- sltgui-0.2.0/README.md +136 -0
- sltgui-0.2.0/README_pypi.md +93 -0
- sltgui-0.2.0/bump_major.ps1 +18 -0
- sltgui-0.2.0/bump_minor.ps1 +18 -0
- sltgui-0.2.0/bump_patch.ps1 +18 -0
- sltgui-0.2.0/pyproject.toml +48 -0
- sltgui-0.2.0/src/sltgui/__init__.py +19 -0
- sltgui-0.2.0/src/sltgui/binary_editor_window.py +728 -0
- sltgui-0.2.0/src/sltgui/enum_def_dict_editor.py +618 -0
- sltgui-0.2.0/src/sltgui/struct_def_dict_editor.py +1173 -0
- sltgui-0.2.0/tests/test_binary_editor_window.py +811 -0
- sltgui-0.2.0/tests/test_editor_primitive_types.py +814 -0
- sltgui-0.2.0/tests/test_enum_def_dict_editor.py +272 -0
- sltgui-0.2.0/uv.lock +142 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
|
|
6
|
+
permissions:
|
|
7
|
+
contents: write
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build-and-publish:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- name: Extract version from pyproject.toml
|
|
17
|
+
id: version
|
|
18
|
+
run: |
|
|
19
|
+
VERSION=$(grep -m1 '^version = "' pyproject.toml | sed -E 's/^version = "([^"]+)"$/\1/')
|
|
20
|
+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
|
21
|
+
echo "tag=v$VERSION" >> "$GITHUB_OUTPUT"
|
|
22
|
+
|
|
23
|
+
- name: Install uv
|
|
24
|
+
uses: astral-sh/setup-uv@v3
|
|
25
|
+
|
|
26
|
+
- name: Build distribution
|
|
27
|
+
run: uv build
|
|
28
|
+
|
|
29
|
+
- name: Publish to PyPI
|
|
30
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
31
|
+
with:
|
|
32
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
33
|
+
packages-dir: dist
|
|
34
|
+
|
|
35
|
+
- name: Create GitHub release and upload artifacts
|
|
36
|
+
uses: softprops/action-gh-release@v2
|
|
37
|
+
with:
|
|
38
|
+
tag_name: ${{ steps.version.outputs.tag }}
|
|
39
|
+
name: ${{ steps.version.outputs.tag }}
|
|
40
|
+
generate_release_notes: true
|
|
41
|
+
files: |
|
|
42
|
+
dist/*.tar.gz
|
|
43
|
+
dist/*.whl
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Publish to TestPyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
|
|
6
|
+
jobs:
|
|
7
|
+
build-and-publish:
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
|
|
13
|
+
- name: Install uv
|
|
14
|
+
uses: astral-sh/setup-uv@v3
|
|
15
|
+
|
|
16
|
+
- name: Build wheel
|
|
17
|
+
run: uv build
|
|
18
|
+
|
|
19
|
+
- name: Publish to TestPyPI
|
|
20
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
21
|
+
with:
|
|
22
|
+
password: ${{ secrets.TEST_PYPI_API_TOKEN }}
|
|
23
|
+
repository-url: https://test.pypi.org/legacy/
|
|
24
|
+
packages-dir: dist
|
sltgui-0.2.0/.gitignore
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[codz]
|
|
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
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py.cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
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
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
# Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# UV
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
# uv.lock
|
|
102
|
+
|
|
103
|
+
# poetry
|
|
104
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
105
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
106
|
+
# commonly ignored for libraries.
|
|
107
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
108
|
+
# poetry.lock
|
|
109
|
+
# poetry.toml
|
|
110
|
+
|
|
111
|
+
# pdm
|
|
112
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
113
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
114
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
115
|
+
# pdm.lock
|
|
116
|
+
# pdm.toml
|
|
117
|
+
.pdm-python
|
|
118
|
+
.pdm-build/
|
|
119
|
+
|
|
120
|
+
# pixi
|
|
121
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
122
|
+
# pixi.lock
|
|
123
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
124
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
125
|
+
.pixi
|
|
126
|
+
|
|
127
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
128
|
+
__pypackages__/
|
|
129
|
+
|
|
130
|
+
# Celery stuff
|
|
131
|
+
celerybeat-schedule
|
|
132
|
+
celerybeat.pid
|
|
133
|
+
|
|
134
|
+
# Redis
|
|
135
|
+
*.rdb
|
|
136
|
+
*.aof
|
|
137
|
+
*.pid
|
|
138
|
+
|
|
139
|
+
# RabbitMQ
|
|
140
|
+
mnesia/
|
|
141
|
+
rabbitmq/
|
|
142
|
+
rabbitmq-data/
|
|
143
|
+
|
|
144
|
+
# ActiveMQ
|
|
145
|
+
activemq-data/
|
|
146
|
+
|
|
147
|
+
# SageMath parsed files
|
|
148
|
+
*.sage.py
|
|
149
|
+
|
|
150
|
+
# Environments
|
|
151
|
+
.env
|
|
152
|
+
.envrc
|
|
153
|
+
.venv
|
|
154
|
+
env/
|
|
155
|
+
venv/
|
|
156
|
+
ENV/
|
|
157
|
+
env.bak/
|
|
158
|
+
venv.bak/
|
|
159
|
+
|
|
160
|
+
# Spyder project settings
|
|
161
|
+
.spyderproject
|
|
162
|
+
.spyproject
|
|
163
|
+
|
|
164
|
+
# Rope project settings
|
|
165
|
+
.ropeproject
|
|
166
|
+
|
|
167
|
+
# mkdocs documentation
|
|
168
|
+
/site
|
|
169
|
+
|
|
170
|
+
# mypy
|
|
171
|
+
.mypy_cache/
|
|
172
|
+
.dmypy.json
|
|
173
|
+
dmypy.json
|
|
174
|
+
|
|
175
|
+
# Pyre type checker
|
|
176
|
+
.pyre/
|
|
177
|
+
|
|
178
|
+
# pytype static type analyzer
|
|
179
|
+
.pytype/
|
|
180
|
+
|
|
181
|
+
# Cython debug symbols
|
|
182
|
+
cython_debug/
|
|
183
|
+
|
|
184
|
+
# PyCharm
|
|
185
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
186
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
187
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
188
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
189
|
+
# .idea/
|
|
190
|
+
|
|
191
|
+
# Abstra
|
|
192
|
+
# Abstra is an AI-powered process automation framework.
|
|
193
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
194
|
+
# Learn more at https://abstra.io/docs
|
|
195
|
+
.abstra/
|
|
196
|
+
|
|
197
|
+
# Visual Studio Code
|
|
198
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
199
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
200
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
201
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
202
|
+
# .vscode/
|
|
203
|
+
# Temporary file for partial code execution
|
|
204
|
+
tempCodeRunnerFile.py
|
|
205
|
+
|
|
206
|
+
# Ruff stuff:
|
|
207
|
+
.ruff_cache/
|
|
208
|
+
|
|
209
|
+
# PyPI configuration file
|
|
210
|
+
.pypirc
|
|
211
|
+
|
|
212
|
+
# Marimo
|
|
213
|
+
marimo/_static/
|
|
214
|
+
marimo/_lsp/
|
|
215
|
+
__marimo__/
|
|
216
|
+
|
|
217
|
+
# Streamlit
|
|
218
|
+
.streamlit/secrets.toml
|
|
219
|
+
|
|
220
|
+
# sltgui
|
|
221
|
+
setting.json
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.14
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.2.0",
|
|
3
|
+
"configurations": [
|
|
4
|
+
{
|
|
5
|
+
"name": "Debug Pytest (single test)",
|
|
6
|
+
"type": "python",
|
|
7
|
+
"request": "launch",
|
|
8
|
+
"module": "pytest",
|
|
9
|
+
"args": [
|
|
10
|
+
"-k", "${input:test_name}"
|
|
11
|
+
],
|
|
12
|
+
"console": "integratedTerminal"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"inputs": [
|
|
16
|
+
{
|
|
17
|
+
"id": "test_name",
|
|
18
|
+
"type": "promptString",
|
|
19
|
+
"description": "Enter pytest -k expression",
|
|
20
|
+
"default": "test_bits_get_cross_byte"
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
sltgui-0.2.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 fangface
|
|
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.
|
sltgui-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: sltgui
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: GUI for visualizing and inspecting binary structure layouts defined by StructLayoutToolkit. Provides a hierarchical tree view, precise offset/size display, and interactive inspection of parsed struct instances.
|
|
5
|
+
Project-URL: Homepage, https://github.com/fangface-hub/StructLayoutToolkitGui
|
|
6
|
+
Project-URL: Documentation, https://readthedocs.org
|
|
7
|
+
Project-URL: Repository, https://github.com/fangface-hub/StructLayoutToolkitGui
|
|
8
|
+
Project-URL: Issues, https://github.com/fangface-hub/StructLayoutToolkitGui/issues
|
|
9
|
+
Author: fangface
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: byte,deserialization,layout,serialization,struct
|
|
13
|
+
Requires-Python: >=3.14
|
|
14
|
+
Requires-Dist: sltcalc>=0.1.0
|
|
15
|
+
Requires-Dist: sltcodec>=2.1.0
|
|
16
|
+
Requires-Dist: sltcore>=1.5.0
|
|
17
|
+
Requires-Dist: tkinterex>=1.1.3
|
|
18
|
+
Requires-Dist: treeviewex>=1.0.2
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
|
|
21
|
+
# StructLayoutToolkitGui
|
|
22
|
+
|
|
23
|
+
StructLayoutToolkitGui is a desktop application for inspecting and editing
|
|
24
|
+
binary files using structure layouts defined by the StructLayoutToolkit
|
|
25
|
+
ecosystem. It combines a hierarchical binary viewer with editors for structure
|
|
26
|
+
and enumeration definitions.
|
|
27
|
+
|
|
28
|
+
## Features
|
|
29
|
+
|
|
30
|
+
- Decode binary files with a selected `StructDef`.
|
|
31
|
+
- Display field offsets, raw bytes, names, types, values, and sizes.
|
|
32
|
+
- Inspect nested structures in a hierarchical tree view.
|
|
33
|
+
- Edit decoded field values and encode them back to binary data.
|
|
34
|
+
- View and edit raw hexadecimal data when no structure is selected.
|
|
35
|
+
- Create and edit `StructDef` and `EnumDef` dictionaries.
|
|
36
|
+
- Re-decode loaded data after changing type definitions.
|
|
37
|
+
- Open, save, and save-as both binary and StructLayout files.
|
|
38
|
+
- Configure the number of bytes shown per row in raw mode.
|
|
39
|
+
|
|
40
|
+
## Requirements
|
|
41
|
+
|
|
42
|
+
- Python 3.14 or later
|
|
43
|
+
- Tkinter support in the Python installation
|
|
44
|
+
|
|
45
|
+
Tkinter is included with standard Python installations on Windows and macOS.
|
|
46
|
+
Some Linux distributions provide it as a separate system package.
|
|
47
|
+
|
|
48
|
+
## Installation
|
|
49
|
+
|
|
50
|
+
Install the package from PyPI:
|
|
51
|
+
|
|
52
|
+
```console
|
|
53
|
+
python -m pip install sltgui
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Running the Application
|
|
57
|
+
|
|
58
|
+
Start the binary editor with:
|
|
59
|
+
|
|
60
|
+
```console
|
|
61
|
+
python -m sltgui.binary_editor_window
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Basic Workflow
|
|
65
|
+
|
|
66
|
+
1. Open a StructLayout JSON file from **Type Definition > Open StructLayout**.
|
|
67
|
+
2. Open a binary file from **File > Open Binary**.
|
|
68
|
+
3. Double-click a value cell to edit a decoded field.
|
|
69
|
+
4. Use **Re-decode** after updating Struct or Enum definitions.
|
|
70
|
+
5. Save changes with **Save Binary** or choose a new destination with **Save Binary As**.
|
|
71
|
+
|
|
72
|
+
The files may also be opened in the opposite order. A binary opened without a
|
|
73
|
+
layout is shown in raw mode and is decoded when a valid StructLayout is loaded.
|
|
74
|
+
|
|
75
|
+
Static offsets and sizes use `byte,bit` notation. For example, `4,0` represents
|
|
76
|
+
four bytes and `0,3` represents three bits.
|
|
77
|
+
|
|
78
|
+
## Using the Window from Python
|
|
79
|
+
|
|
80
|
+
The GUI classes are also available as a Python API:
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
import tkinter as tk
|
|
84
|
+
|
|
85
|
+
from sltgui import BinaryEditorWindow
|
|
86
|
+
|
|
87
|
+
root = tk.Tk()
|
|
88
|
+
root.withdraw()
|
|
89
|
+
window = BinaryEditorWindow(root)
|
|
90
|
+
window.protocol("WM_DELETE_WINDOW", root.destroy)
|
|
91
|
+
root.mainloop()
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The package exports `BinaryEditorWindow`, `StructDefDictEditor`, and
|
|
95
|
+
`EnumDefDictEditor`.
|
|
96
|
+
|
|
97
|
+
## Related Projects
|
|
98
|
+
|
|
99
|
+
StructLayoutToolkitGui uses the following StructLayoutToolkit packages:
|
|
100
|
+
|
|
101
|
+
- `sltcore` for core structure and size types
|
|
102
|
+
- `sltcodec` for StructLayout serialization and binary encoding/decoding
|
|
103
|
+
- `sltcalc` for expression evaluation
|
|
104
|
+
|
|
105
|
+
## Links
|
|
106
|
+
|
|
107
|
+
- [Source code](https://github.com/fangface-hub/StructLayoutToolkitGui)
|
|
108
|
+
- [Issue tracker](https://github.com/fangface-hub/StructLayoutToolkitGui/issues)
|
|
109
|
+
- [Developer documentation](https://github.com/fangface-hub/StructLayoutToolkitGui/blob/main/README.md)
|
|
110
|
+
|
|
111
|
+
## License
|
|
112
|
+
|
|
113
|
+
StructLayoutToolkitGui is distributed under the MIT License.
|
sltgui-0.2.0/README.md
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# StructLayoutToolkitGui
|
|
2
|
+
|
|
3
|
+
StructLayoutToolkitGui is a Tkinter application for viewing and editing binary
|
|
4
|
+
data using structure layouts defined with StructLayoutToolkit. It also provides
|
|
5
|
+
GUI editors for structure and enumeration definitions.
|
|
6
|
+
|
|
7
|
+
## Development Environment
|
|
8
|
+
|
|
9
|
+
- Python 3.14 or later
|
|
10
|
+
- [uv](https://docs.astral.sh/uv/)
|
|
11
|
+
- A Python environment with Tkinter support
|
|
12
|
+
|
|
13
|
+
The project depends on SltCore for structure definitions, SltCodec for encoding
|
|
14
|
+
and decoding, and SltCalc for expression evaluation. See `pyproject.toml` for
|
|
15
|
+
the exact version requirements.
|
|
16
|
+
|
|
17
|
+
### Setup
|
|
18
|
+
|
|
19
|
+
```powershell
|
|
20
|
+
git clone https://github.com/fangface-hub/StructLayoutToolkitGui.git
|
|
21
|
+
Set-Location StructLayoutToolkitGui
|
|
22
|
+
uv sync
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Run
|
|
26
|
+
|
|
27
|
+
```powershell
|
|
28
|
+
uv run python -m sltgui.binary_editor_window
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Test
|
|
32
|
+
|
|
33
|
+
Run the complete test suite:
|
|
34
|
+
|
|
35
|
+
```powershell
|
|
36
|
+
uv run pytest -q
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
To run a specific test file:
|
|
40
|
+
|
|
41
|
+
```powershell
|
|
42
|
+
uv run pytest tests/test_binary_editor_window.py -q
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Source Layout
|
|
46
|
+
|
|
47
|
+
| Path | Responsibility |
|
|
48
|
+
| --- | --- |
|
|
49
|
+
| `src/sltgui/binary_editor_window.py` | Main window for opening, decoding, editing, encoding, and saving binary data |
|
|
50
|
+
| `src/sltgui/struct_def_dict_editor.py` | Modal editor for the `StructDef` dictionary |
|
|
51
|
+
| `src/sltgui/enum_def_dict_editor.py` | Modal editor for the `EnumDef` dictionary |
|
|
52
|
+
| `src/sltgui/__init__.py` | Public API with lazy imports for the GUI classes |
|
|
53
|
+
| `tests/` | Unit tests with GUI dependencies replaced by stubs |
|
|
54
|
+
|
|
55
|
+
The package exposes three public classes:
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
from sltgui import BinaryEditorWindow, EnumDefDictEditor, StructDefDictEditor
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Data Flow
|
|
62
|
+
|
|
63
|
+
1. Load a `StructLayout` JSON file to obtain its `TypeDict` and selected `StructDef`.
|
|
64
|
+
2. Pass the binary data to `decode()` to create a `StructInstance`.
|
|
65
|
+
3. Render `StructInstance.field_instances` in the tree view.
|
|
66
|
+
4. When a value is edited, convert its text back to the original value type and create a new field with `FieldInstance.with_value()`.
|
|
67
|
+
5. Pass the updated instance to `encode()`, then call `decode()` again to keep the display and derived data synchronized.
|
|
68
|
+
|
|
69
|
+
The `Update` action in the Struct and Enum definition editors updates the shared
|
|
70
|
+
`TypeDict`, but it does not automatically rebuild an existing `StructInstance`.
|
|
71
|
+
Use `Re-decode` in the main window after changing definitions.
|
|
72
|
+
|
|
73
|
+
## Implementation Notes
|
|
74
|
+
|
|
75
|
+
### Updating Instances
|
|
76
|
+
|
|
77
|
+
`FieldInstance` is immutable. Replacing only its value with
|
|
78
|
+
`dataclasses.replace()` can leave derived data such as `enum_item` out of date.
|
|
79
|
+
Always use `FieldInstance.with_value(value, type_dict)` when changing a value.
|
|
80
|
+
|
|
81
|
+
For nested structures, rebuild each object from the target `FieldInstance` up
|
|
82
|
+
to the parent `StructInstance`. See
|
|
83
|
+
`BinaryEditorWindow._replace_instance_value()` for the current implementation.
|
|
84
|
+
|
|
85
|
+
### InfoSize
|
|
86
|
+
|
|
87
|
+
Static offsets and sizes are stored as `InfoSize` objects. The GUI displays and
|
|
88
|
+
accepts them in `byte,bit` format. For example, four bytes are written as `4,0`
|
|
89
|
+
and three bits as `0,3`. Offsets and sizes may also contain expression strings,
|
|
90
|
+
so do not unconditionally coerce every value to `InfoSize`.
|
|
91
|
+
|
|
92
|
+
### TreeviewEx
|
|
93
|
+
|
|
94
|
+
Use numeric column IDs such as `#1` and `#2`, rather than column names, when
|
|
95
|
+
configuring editable, read-only, or combobox cells. When adding or reordering
|
|
96
|
+
columns, update the corresponding column ID constants and tests.
|
|
97
|
+
|
|
98
|
+
### Saving Files
|
|
99
|
+
|
|
100
|
+
`Save` overwrites the currently open file or the file most recently selected
|
|
101
|
+
with `Save As`. For new data without a destination, it falls back to `Save As`.
|
|
102
|
+
`BinaryEditorWindow.binary_file` and `struct_layout_file` track the current
|
|
103
|
+
paths.
|
|
104
|
+
|
|
105
|
+
## Verifying Changes
|
|
106
|
+
|
|
107
|
+
Run the tests for the affected area first, followed by the complete test suite.
|
|
108
|
+
When changing GUI state transitions, verify at least these workflows:
|
|
109
|
+
|
|
110
|
+
- Open a StructLayout, then open a binary file.
|
|
111
|
+
- Open a binary file in raw mode, then open a StructLayout.
|
|
112
|
+
- Update Struct or Enum definitions, then use `Re-decode`.
|
|
113
|
+
- Edit a value, then save the binary file.
|
|
114
|
+
- Use `Save` to overwrite an open file.
|
|
115
|
+
|
|
116
|
+
## Build and Release
|
|
117
|
+
|
|
118
|
+
The project uses Hatchling to build distributions:
|
|
119
|
+
|
|
120
|
+
```powershell
|
|
121
|
+
uv build
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
PowerShell scripts are available for version updates:
|
|
125
|
+
|
|
126
|
+
```powershell
|
|
127
|
+
./bump_patch.ps1
|
|
128
|
+
./bump_minor.ps1
|
|
129
|
+
./bump_major.ps1
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
The workflows in `.github/workflows/` publish manually to TestPyPI or PyPI. The
|
|
133
|
+
PyPI workflow creates a tag and GitHub Release from the version in
|
|
134
|
+
`pyproject.toml`, then attaches the wheel and source distribution. Before
|
|
135
|
+
publishing, verify the version, run the complete test suite, and inspect the
|
|
136
|
+
artifacts produced by `uv build`.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# StructLayoutToolkitGui
|
|
2
|
+
|
|
3
|
+
StructLayoutToolkitGui is a desktop application for inspecting and editing
|
|
4
|
+
binary files using structure layouts defined by the StructLayoutToolkit
|
|
5
|
+
ecosystem. It combines a hierarchical binary viewer with editors for structure
|
|
6
|
+
and enumeration definitions.
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- Decode binary files with a selected `StructDef`.
|
|
11
|
+
- Display field offsets, raw bytes, names, types, values, and sizes.
|
|
12
|
+
- Inspect nested structures in a hierarchical tree view.
|
|
13
|
+
- Edit decoded field values and encode them back to binary data.
|
|
14
|
+
- View and edit raw hexadecimal data when no structure is selected.
|
|
15
|
+
- Create and edit `StructDef` and `EnumDef` dictionaries.
|
|
16
|
+
- Re-decode loaded data after changing type definitions.
|
|
17
|
+
- Open, save, and save-as both binary and StructLayout files.
|
|
18
|
+
- Configure the number of bytes shown per row in raw mode.
|
|
19
|
+
|
|
20
|
+
## Requirements
|
|
21
|
+
|
|
22
|
+
- Python 3.14 or later
|
|
23
|
+
- Tkinter support in the Python installation
|
|
24
|
+
|
|
25
|
+
Tkinter is included with standard Python installations on Windows and macOS.
|
|
26
|
+
Some Linux distributions provide it as a separate system package.
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
Install the package from PyPI:
|
|
31
|
+
|
|
32
|
+
```console
|
|
33
|
+
python -m pip install sltgui
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Running the Application
|
|
37
|
+
|
|
38
|
+
Start the binary editor with:
|
|
39
|
+
|
|
40
|
+
```console
|
|
41
|
+
python -m sltgui.binary_editor_window
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Basic Workflow
|
|
45
|
+
|
|
46
|
+
1. Open a StructLayout JSON file from **Type Definition > Open StructLayout**.
|
|
47
|
+
2. Open a binary file from **File > Open Binary**.
|
|
48
|
+
3. Double-click a value cell to edit a decoded field.
|
|
49
|
+
4. Use **Re-decode** after updating Struct or Enum definitions.
|
|
50
|
+
5. Save changes with **Save Binary** or choose a new destination with **Save Binary As**.
|
|
51
|
+
|
|
52
|
+
The files may also be opened in the opposite order. A binary opened without a
|
|
53
|
+
layout is shown in raw mode and is decoded when a valid StructLayout is loaded.
|
|
54
|
+
|
|
55
|
+
Static offsets and sizes use `byte,bit` notation. For example, `4,0` represents
|
|
56
|
+
four bytes and `0,3` represents three bits.
|
|
57
|
+
|
|
58
|
+
## Using the Window from Python
|
|
59
|
+
|
|
60
|
+
The GUI classes are also available as a Python API:
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
import tkinter as tk
|
|
64
|
+
|
|
65
|
+
from sltgui import BinaryEditorWindow
|
|
66
|
+
|
|
67
|
+
root = tk.Tk()
|
|
68
|
+
root.withdraw()
|
|
69
|
+
window = BinaryEditorWindow(root)
|
|
70
|
+
window.protocol("WM_DELETE_WINDOW", root.destroy)
|
|
71
|
+
root.mainloop()
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The package exports `BinaryEditorWindow`, `StructDefDictEditor`, and
|
|
75
|
+
`EnumDefDictEditor`.
|
|
76
|
+
|
|
77
|
+
## Related Projects
|
|
78
|
+
|
|
79
|
+
StructLayoutToolkitGui uses the following StructLayoutToolkit packages:
|
|
80
|
+
|
|
81
|
+
- `sltcore` for core structure and size types
|
|
82
|
+
- `sltcodec` for StructLayout serialization and binary encoding/decoding
|
|
83
|
+
- `sltcalc` for expression evaluation
|
|
84
|
+
|
|
85
|
+
## Links
|
|
86
|
+
|
|
87
|
+
- [Source code](https://github.com/fangface-hub/StructLayoutToolkitGui)
|
|
88
|
+
- [Issue tracker](https://github.com/fangface-hub/StructLayoutToolkitGui/issues)
|
|
89
|
+
- [Developer documentation](https://github.com/fangface-hub/StructLayoutToolkitGui/blob/main/README.md)
|
|
90
|
+
|
|
91
|
+
## License
|
|
92
|
+
|
|
93
|
+
StructLayoutToolkitGui is distributed under the MIT License.
|