├── .github
└── workflows
│ └── dotnet-desktop.yml
├── .gitignore
├── BflytPreview
├── App.config
├── Automation
│ ├── BflanTemplates.cs
│ ├── ValueImportForm.Designer.cs
│ ├── ValueImportForm.cs
│ └── ValueImportForm.resx
├── BflanEditor.Designer.cs
├── BflanEditor.cs
├── BflanEditor.resx
├── BflanTemplates
│ ├── ColorAnimation.json
│ └── ColorAnimation.template
├── BflytPreview.csproj
├── EditorForms
│ ├── HexEditorForm.cs
│ ├── IFileProvider.cs
│ ├── InputDialog.cs
│ ├── LayoutDiffForm.Designer.cs
│ ├── LayoutDiffForm.cs
│ ├── LayoutDiffForm.resx
│ ├── SzsEditor.Designer.cs
│ ├── SzsEditor.cs
│ └── SzsEditor.resx
├── EditorView.Designer.cs
├── EditorView.cs
├── EditorView.resx
├── MainForm.Designer.cs
├── MainForm.cs
├── MainForm.resx
├── OpenTK.dll.config
├── Program.cs
├── Properties
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ ├── Resources.resx
│ ├── Settings.Designer.cs
│ └── Settings.settings
├── Settings.Designer.cs
├── Settings.settings
├── SettingsWindow.Designer.cs
├── SettingsWindow.cs
├── SettingsWindow.resx
├── favicon.ico
├── icon.ico
└── packages.config
├── LICENSE
├── README.md
├── Screenshot.png
├── Screenshots
├── Dragging.gif
├── EditorPreview.png
├── Example.png
├── LayoutEditing.png
├── MainMenu.png
├── PaneMenu.png
├── PropertiesMenu.png
├── SaveFile.png
├── Settings.png
├── Szs-loading.png
└── SzsEditor.png
├── SwitchLayoutEditor.sln
├── docs
└── EditorAutoUpdate.xml
└── dragdroptree.txt
/.github/workflows/dotnet-desktop.yml:
--------------------------------------------------------------------------------
1 | name: LayoutEditor
2 | on:
3 | workflow_dispatch:
4 | push:
5 | pull_request:
6 | jobs:
7 | Build:
8 | runs-on: windows-latest
9 | steps:
10 | - name: Setup msbuild
11 | uses: microsoft/setup-msbuild@v1.0.2
12 | # Needs switchThemesCommon to build
13 | - uses: actions/checkout@v3
14 | with:
15 | repository: 'exelix11/SwitchThemeInjector'
16 | path: 'SwitchThemeInjector'
17 | - uses: actions/checkout@v3
18 | with:
19 | path: 'SwitchLayoutEditor'
20 | - name: Restore packages
21 | run: |
22 | cd %GITHUB_WORKSPACE%/SwitchLayoutEditor
23 | mkdir packages
24 | cd packages
25 | nuget install %GITHUB_WORKSPACE%/SwitchLayoutEditor/BflytPreview/packages.config
26 | shell: cmd
27 | - name: Build project
28 | run: |
29 | cd %GITHUB_WORKSPACE%\SwitchLayoutEditor\
30 | msbuild -p:Configuration=Release
31 | del %GITHUB_WORKSPACE%\SwitchLayoutEditor\BflytPreview\bin\Release\*.xml
32 | shell: cmd
33 | - uses: actions/upload-artifact@v4
34 | with:
35 | name: LayoutEditor
36 | path: ${{ github.workspace }}/SwitchLayoutEditor/BflytPreview/bin/Release/
37 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.suo
8 | *.user
9 | *.userosscache
10 | *.sln.docstates
11 |
12 | # User-specific files (MonoDevelop/Xamarin Studio)
13 | *.userprefs
14 |
15 | # Build results
16 | [Dd]ebug/
17 | [Dd]ebugPublic/
18 | [Rr]elease/
19 | [Rr]eleases/
20 | x64/
21 | x86/
22 | bld/
23 | [Bb]in/
24 | [Oo]bj/
25 | [Ll]og/
26 | [Bb]uild/
27 |
28 | # Visual Studio 2015/2017 cache/options directory
29 | .vs/
30 | # Uncomment if you have tasks that create the project's static files in wwwroot
31 | #wwwroot/
32 |
33 | # Visual Studio 2017 auto generated files
34 | Generated\ Files/
35 |
36 | # MSTest test Results
37 | [Tt]est[Rr]esult*/
38 | [Bb]uild[Ll]og.*
39 |
40 | # NUNIT
41 | *.VisualState.xml
42 | TestResult.xml
43 |
44 | # Build Results of an ATL Project
45 | [Dd]ebugPS/
46 | [Rr]eleasePS/
47 | dlldata.c
48 |
49 | # Benchmark Results
50 | BenchmarkDotNet.Artifacts/
51 |
52 | # .NET Core
53 | project.lock.json
54 | project.fragment.lock.json
55 | artifacts/
56 | **/Properties/launchSettings.json
57 |
58 | # StyleCop
59 | StyleCopReport.xml
60 |
61 | # Files built by Visual Studio
62 | *_i.c
63 | *_p.c
64 | *_i.h
65 | *.ilk
66 | *.meta
67 | *.obj
68 | *.iobj
69 | *.pch
70 | *.pdb
71 | *.ipdb
72 | *.pgc
73 | *.pgd
74 | *.rsp
75 | *.sbr
76 | *.tlb
77 | *.tli
78 | *.tlh
79 | *.tmp
80 | *.tmp_proj
81 | *.log
82 | *.vspscc
83 | *.vssscc
84 | .builds
85 | *.pidb
86 | *.svclog
87 | *.scc
88 |
89 | # Chutzpah Test files
90 | _Chutzpah*
91 |
92 | # Visual C++ cache files
93 | ipch/
94 | *.aps
95 | *.ncb
96 | *.opendb
97 | *.opensdf
98 | *.sdf
99 | *.cachefile
100 | *.VC.db
101 | *.VC.VC.opendb
102 |
103 | # Visual Studio profiler
104 | *.psess
105 | *.vsp
106 | *.vspx
107 | *.sap
108 |
109 | # Visual Studio Trace Files
110 | *.e2e
111 |
112 | # TFS 2012 Local Workspace
113 | $tf/
114 |
115 | # Guidance Automation Toolkit
116 | *.gpState
117 |
118 | # ReSharper is a .NET coding add-in
119 | _ReSharper*/
120 | *.[Rr]e[Ss]harper
121 | *.DotSettings.user
122 |
123 | # JustCode is a .NET coding add-in
124 | .JustCode
125 |
126 | # TeamCity is a build add-in
127 | _TeamCity*
128 |
129 | # DotCover is a Code Coverage Tool
130 | *.dotCover
131 |
132 | # AxoCover is a Code Coverage Tool
133 | .axoCover/*
134 | !.axoCover/settings.json
135 |
136 | # Visual Studio code coverage results
137 | *.coverage
138 | *.coveragexml
139 |
140 | # NCrunch
141 | _NCrunch_*
142 | .*crunch*.local.xml
143 | nCrunchTemp_*
144 |
145 | # MightyMoose
146 | *.mm.*
147 | AutoTest.Net/
148 |
149 | # Web workbench (sass)
150 | .sass-cache/
151 |
152 | # Installshield output folder
153 | [Ee]xpress/
154 |
155 | # DocProject is a documentation generator add-in
156 | DocProject/buildhelp/
157 | DocProject/Help/*.HxT
158 | DocProject/Help/*.HxC
159 | DocProject/Help/*.hhc
160 | DocProject/Help/*.hhk
161 | DocProject/Help/*.hhp
162 | DocProject/Help/Html2
163 | DocProject/Help/html
164 |
165 | # Click-Once directory
166 | publish/
167 |
168 | # Publish Web Output
169 | *.[Pp]ublish.xml
170 | *.azurePubxml
171 | # Note: Comment the next line if you want to checkin your web deploy settings,
172 | # but database connection strings (with potential passwords) will be unencrypted
173 | *.pubxml
174 | *.publishproj
175 |
176 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
177 | # checkin your Azure Web App publish settings, but sensitive information contained
178 | # in these scripts will be unencrypted
179 | PublishScripts/
180 |
181 | # NuGet Packages
182 | *.nupkg
183 | # The packages folder can be ignored because of Package Restore
184 | **/[Pp]ackages/*
185 | # except build/, which is used as an MSBuild target.
186 | !**/[Pp]ackages/build/
187 | # Uncomment if necessary however generally it will be regenerated when needed
188 | #!**/[Pp]ackages/repositories.config
189 | # NuGet v3's project.json files produces more ignorable files
190 | *.nuget.props
191 | *.nuget.targets
192 |
193 | # Microsoft Azure Build Output
194 | csx/
195 | *.build.csdef
196 |
197 | # Microsoft Azure Emulator
198 | ecf/
199 | rcf/
200 |
201 | # Windows Store app package directories and files
202 | AppPackages/
203 | BundleArtifacts/
204 | Package.StoreAssociation.xml
205 | _pkginfo.txt
206 | *.appx
207 |
208 | # Visual Studio cache files
209 | # files ending in .cache can be ignored
210 | *.[Cc]ache
211 | # but keep track of directories ending in .cache
212 | !*.[Cc]ache/
213 |
214 | # Others
215 | ClientBin/
216 | ~$*
217 | *~
218 | *.dbmdl
219 | *.dbproj.schemaview
220 | *.jfm
221 | *.pfx
222 | *.publishsettings
223 | orleans.codegen.cs
224 |
225 | # Including strong name files can present a security risk
226 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
227 | #*.snk
228 |
229 | # Since there are multiple workflows, uncomment next line to ignore bower_components
230 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
231 | #bower_components/
232 |
233 | # RIA/Silverlight projects
234 | Generated_Code/
235 |
236 | # Backup & report files from converting an old project file
237 | # to a newer Visual Studio version. Backup files are not needed,
238 | # because we have git ;-)
239 | _UpgradeReport_Files/
240 | Backup*/
241 | UpgradeLog*.XML
242 | UpgradeLog*.htm
243 | ServiceFabricBackup/
244 | *.rptproj.bak
245 |
246 | # SQL Server files
247 | *.mdf
248 | *.ldf
249 | *.ndf
250 |
251 | # Business Intelligence projects
252 | *.rdl.data
253 | *.bim.layout
254 | *.bim_*.settings
255 | *.rptproj.rsuser
256 |
257 | # Microsoft Fakes
258 | FakesAssemblies/
259 |
260 | # GhostDoc plugin setting file
261 | *.GhostDoc.xml
262 |
263 | # Node.js Tools for Visual Studio
264 | .ntvs_analysis.dat
265 | node_modules/
266 |
267 | # Visual Studio 6 build log
268 | *.plg
269 |
270 | # Visual Studio 6 workspace options file
271 | *.opt
272 |
273 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
274 | *.vbw
275 |
276 | # Visual Studio LightSwitch build output
277 | **/*.HTMLClient/GeneratedArtifacts
278 | **/*.DesktopClient/GeneratedArtifacts
279 | **/*.DesktopClient/ModelManifest.xml
280 | **/*.Server/GeneratedArtifacts
281 | **/*.Server/ModelManifest.xml
282 | _Pvt_Extensions
283 |
284 | # Paket dependency manager
285 | .paket/paket.exe
286 | paket-files/
287 |
288 | # FAKE - F# Make
289 | .fake/
290 |
291 | # JetBrains Rider
292 | .idea/
293 | *.sln.iml
294 |
295 | # CodeRush
296 | .cr/
297 |
298 | # Python Tools for Visual Studio (PTVS)
299 | __pycache__/
300 | *.pyc
301 |
302 | # Cake - Uncomment if you are using it
303 | # tools/**
304 | # !tools/packages.config
305 |
306 | # Tabs Studio
307 | *.tss
308 |
309 | # Telerik's JustMock configuration file
310 | *.jmconfig
311 |
312 | # BizTalk build output
313 | *.btp.cs
314 | *.btm.cs
315 | *.odx.cs
316 | *.xsd.cs
317 |
318 | # OpenCover UI analysis results
319 | OpenCover/
320 |
321 | # Azure Stream Analytics local run output
322 | ASALocalRun/
323 |
324 | # MSBuild Binary and Structured Log
325 | *.binlog
326 |
327 | # NVidia Nsight GPU debugger configuration file
328 | *.nvuser
329 |
330 | # MFractors (Xamarin productivity tool) working folder
331 | .mfractor/
332 | *.szs
333 | *.nxtheme
334 | *.o
335 | *.d
336 | *.elf
337 | *.nacp
338 | *.nro
339 | *.nso
340 | *.pfs0
341 | *.map
342 | *.lst
343 | *.7z
344 | *.zip
345 |
--------------------------------------------------------------------------------
/BflytPreview/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | Black
16 |
17 |
18 | Red
19 |
20 |
21 | LightGreen
22 |
23 |
24 |
25 |
26 |
27 | False
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/BflytPreview/Automation/BflanTemplates.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using SwitchThemes.Common.Serializers;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using static SwitchThemes.Common.Bflan.Pai1Section;
9 |
10 | namespace BflytPreview.Automation
11 | {
12 | public enum BflanTemplateKind
13 | {
14 | Pai1, // then FileName Contains PaiEntry[]
15 | PaiEntry, // ... contains PaiTag[]
16 | PaiTag, // ... contains PaiTagEntry[]
17 | PaiTagEntry, // ... contains Keyframe[]
18 | }
19 |
20 | public enum ReplaceValueKind
21 | {
22 | String,
23 | Int,
24 | Float
25 | }
26 |
27 | public class ValueReplacement
28 | {
29 | public ReplaceValueKind Kind;
30 | public string Keyword;
31 | public string Name;
32 | public string Default;
33 | }
34 |
35 | public class BflanTemplate
36 | {
37 | public string Name;
38 | public string FileName;
39 | public BflanTemplateKind Target;
40 | public List Parameters;
41 |
42 | public object[] DeserializeContent(string json)
43 | {
44 | switch (Target)
45 | {
46 | case BflanTemplateKind.Pai1:
47 | return JsonConvert.DeserializeObject(json).Select(x => x.Deserialize()).ToArray();
48 | case BflanTemplateKind.PaiEntry:
49 | return JsonConvert.DeserializeObject(json).Select(x => x.Deserialize()).ToArray();
50 | case BflanTemplateKind.PaiTag:
51 | return JsonConvert.DeserializeObject(json).Select(x => x.Deserialize()).ToArray();
52 | case BflanTemplateKind.PaiTagEntry:
53 | return JsonConvert.DeserializeObject(json).Select(x => x.Deserialize()).ToArray();
54 | default:
55 | throw new Exception("Unknown BflanTemplateKind");
56 | }
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/BflytPreview/Automation/ValueImportForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace BflytPreview.Automation
2 | {
3 | partial class ValueImportForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.propertyGrid1 = new System.Windows.Forms.PropertyGrid();
32 | this.btnOK = new System.Windows.Forms.Button();
33 | this.btnCancel = new System.Windows.Forms.Button();
34 | this.SuspendLayout();
35 | //
36 | // propertyGrid1
37 | //
38 | this.propertyGrid1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
39 | | System.Windows.Forms.AnchorStyles.Left)
40 | | System.Windows.Forms.AnchorStyles.Right)));
41 | this.propertyGrid1.Location = new System.Drawing.Point(2, 3);
42 | this.propertyGrid1.Name = "propertyGrid1";
43 | this.propertyGrid1.Size = new System.Drawing.Size(573, 408);
44 | this.propertyGrid1.TabIndex = 0;
45 | //
46 | // btnOK
47 | //
48 | this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
49 | this.btnOK.Location = new System.Drawing.Point(500, 417);
50 | this.btnOK.Name = "btnOK";
51 | this.btnOK.Size = new System.Drawing.Size(75, 23);
52 | this.btnOK.TabIndex = 1;
53 | this.btnOK.Text = "OK";
54 | this.btnOK.UseVisualStyleBackColor = true;
55 | this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
56 | //
57 | // btnCancel
58 | //
59 | this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
60 | this.btnCancel.Location = new System.Drawing.Point(419, 417);
61 | this.btnCancel.Name = "btnCancel";
62 | this.btnCancel.Size = new System.Drawing.Size(75, 23);
63 | this.btnCancel.TabIndex = 2;
64 | this.btnCancel.Text = "Cancel";
65 | this.btnCancel.UseVisualStyleBackColor = true;
66 | this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
67 | //
68 | // ValueImportForm
69 | //
70 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
71 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
72 | this.ClientSize = new System.Drawing.Size(578, 444);
73 | this.Controls.Add(this.btnCancel);
74 | this.Controls.Add(this.btnOK);
75 | this.Controls.Add(this.propertyGrid1);
76 | this.Name = "ValueImportForm";
77 | this.Text = "Edit template";
78 | this.Load += new System.EventHandler(this.ValueImportForm_Load);
79 | this.ResumeLayout(false);
80 |
81 | }
82 |
83 | #endregion
84 |
85 | private System.Windows.Forms.PropertyGrid propertyGrid1;
86 | private System.Windows.Forms.Button btnOK;
87 | private System.Windows.Forms.Button btnCancel;
88 | }
89 | }
--------------------------------------------------------------------------------
/BflytPreview/Automation/ValueImportForm.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json.Linq;
2 | using System;
3 | using System.Collections;
4 | using System.Collections.Generic;
5 | using System.ComponentModel;
6 | using System.Data;
7 | using System.Drawing;
8 | using System.Dynamic;
9 | using System.Linq;
10 | using System.Text;
11 | using System.Threading.Tasks;
12 | using System.Windows.Controls;
13 | using System.Windows.Forms;
14 |
15 | namespace BflytPreview.Automation
16 | {
17 | public partial class ValueImportForm : Form
18 | {
19 | public string Result = null;
20 |
21 | readonly string source;
22 | readonly BflanTemplate template;
23 | readonly Dictionary Values = new Dictionary();
24 |
25 | public ValueImportForm(BflanTemplate template, string json)
26 | {
27 | InitializeComponent();
28 |
29 | source = json;
30 | this.template = template;
31 |
32 | Values = template.Parameters.ToDictionary(x => x.Name, x => x.Default);
33 |
34 | this.propertyGrid1.SelectedObject = new DictionaryPropertyGridAdapter(Values);
35 | }
36 |
37 | private void ValueImportForm_Load(object sender, EventArgs e)
38 | {
39 |
40 | }
41 |
42 | private void btnCancel_Click(object sender, EventArgs e)
43 | {
44 | this.Close();
45 | }
46 |
47 | bool ValidateValues()
48 | {
49 | List invalid = new List();
50 |
51 | foreach (var templ in template.Parameters)
52 | {
53 | var value = Values[templ.Name];
54 |
55 | if (templ.Kind == ReplaceValueKind.Float)
56 | if (!float.TryParse((string)value, out var _))
57 | invalid.Add(templ.Name);
58 |
59 | if (templ.Kind == ReplaceValueKind.Int)
60 | if (!int.TryParse((string)value, out var _))
61 | invalid.Add(templ.Name);
62 | }
63 |
64 | if (invalid.Count > 0)
65 | {
66 | MessageBox.Show("The values for the following properties are not valid: " + string.Join(", ", invalid));
67 | return false;
68 | }
69 |
70 | return true;
71 | }
72 |
73 | private void btnOK_Click(object sender, EventArgs e)
74 | {
75 | if (!ValidateValues())
76 | return;
77 |
78 | Result = source;
79 | foreach (var par in template.Parameters)
80 | {
81 | var value = Values[par.Name];
82 |
83 | if (par.Kind == ReplaceValueKind.String)
84 | Result = Result.Replace(par.Keyword, $"\"{value}\"");
85 | else
86 | Result = Result.Replace(par.Keyword, value);
87 | }
88 |
89 | this.Close();
90 | }
91 | }
92 |
93 | class DictionaryPropertyGridAdapter : ICustomTypeDescriptor
94 | {
95 | IDictionary _dictionary;
96 |
97 | public DictionaryPropertyGridAdapter(IDictionary d)
98 | {
99 | _dictionary = d;
100 | }
101 |
102 | public string GetComponentName()
103 | {
104 | return TypeDescriptor.GetComponentName(this, true);
105 | }
106 |
107 | public EventDescriptor GetDefaultEvent()
108 | {
109 | return TypeDescriptor.GetDefaultEvent(this, true);
110 | }
111 |
112 | public string GetClassName()
113 | {
114 | return TypeDescriptor.GetClassName(this, true);
115 | }
116 |
117 | public EventDescriptorCollection GetEvents(Attribute[] attributes)
118 | {
119 | return TypeDescriptor.GetEvents(this, attributes, true);
120 | }
121 |
122 | EventDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetEvents()
123 | {
124 | return TypeDescriptor.GetEvents(this, true);
125 | }
126 |
127 | public TypeConverter GetConverter()
128 | {
129 | return TypeDescriptor.GetConverter(this, true);
130 | }
131 |
132 | public object GetPropertyOwner(PropertyDescriptor pd)
133 | {
134 | return _dictionary;
135 | }
136 |
137 | public AttributeCollection GetAttributes()
138 | {
139 | return TypeDescriptor.GetAttributes(this, true);
140 | }
141 |
142 | public object GetEditor(Type editorBaseType)
143 | {
144 | return TypeDescriptor.GetEditor(this, editorBaseType, true);
145 | }
146 |
147 | public PropertyDescriptor GetDefaultProperty()
148 | {
149 | return null;
150 | }
151 |
152 | PropertyDescriptorCollection
153 | System.ComponentModel.ICustomTypeDescriptor.GetProperties()
154 | {
155 | return ((ICustomTypeDescriptor)this).GetProperties(new Attribute[0]);
156 | }
157 |
158 | public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
159 | {
160 | ArrayList properties = new ArrayList();
161 | foreach (DictionaryEntry e in _dictionary)
162 | {
163 | properties.Add(new DictionaryPropertyDescriptor(_dictionary, e.Key));
164 | }
165 |
166 | PropertyDescriptor[] props =
167 | (PropertyDescriptor[])properties.ToArray(typeof(PropertyDescriptor));
168 |
169 | return new PropertyDescriptorCollection(props);
170 | }
171 | }
172 |
173 | class DictionaryPropertyDescriptor : PropertyDescriptor
174 | {
175 | IDictionary _dictionary;
176 | object _key;
177 |
178 | internal DictionaryPropertyDescriptor(IDictionary d, object key)
179 | : base(key.ToString(), null)
180 | {
181 | _dictionary = d;
182 | _key = key;
183 | }
184 |
185 | public override Type PropertyType
186 | {
187 | get { return _dictionary[_key].GetType(); }
188 | }
189 |
190 | public override void SetValue(object component, object value)
191 | {
192 | _dictionary[_key] = value;
193 | }
194 |
195 | public override object GetValue(object component)
196 | {
197 | return _dictionary[_key];
198 | }
199 |
200 | public override bool IsReadOnly
201 | {
202 | get { return false; }
203 | }
204 |
205 | public override Type ComponentType
206 | {
207 | get { return null; }
208 | }
209 |
210 | public override bool CanResetValue(object component)
211 | {
212 | return false;
213 | }
214 |
215 | public override void ResetValue(object component)
216 | {
217 | }
218 |
219 | public override bool ShouldSerializeValue(object component)
220 | {
221 | return false;
222 | }
223 | }
224 | }
225 |
--------------------------------------------------------------------------------
/BflytPreview/Automation/ValueImportForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/BflytPreview/BflanEditor.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace BflytPreview
2 | {
3 | partial class BflanEditor
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.components = new System.ComponentModel.Container();
32 | this.propertyGrid1 = new System.Windows.Forms.PropertyGrid();
33 | this.treeView1 = new System.Windows.Forms.TreeView();
34 | this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
35 | this.addEntryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
36 | this.duplicateToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
37 | this.deleteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
38 | this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
39 | this.expandAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
40 | this.menuStrip1 = new System.Windows.Forms.MenuStrip();
41 | this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
42 | this.saveAsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
43 | this.saveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
44 | this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
45 | this.exportToJSONToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
46 | this.importFromJSONToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
47 | this.ByteOrderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
48 | this.SwitchByteOrderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
49 | this.splitContainer1 = new System.Windows.Forms.SplitContainer();
50 | this.templatesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
51 | this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
52 | this.noTemplatesAvailableToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
53 | this.contextMenuStrip1.SuspendLayout();
54 | this.menuStrip1.SuspendLayout();
55 | ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
56 | this.splitContainer1.Panel1.SuspendLayout();
57 | this.splitContainer1.Panel2.SuspendLayout();
58 | this.splitContainer1.SuspendLayout();
59 | this.SuspendLayout();
60 | //
61 | // propertyGrid1
62 | //
63 | this.propertyGrid1.Dock = System.Windows.Forms.DockStyle.Fill;
64 | this.propertyGrid1.Location = new System.Drawing.Point(0, 0);
65 | this.propertyGrid1.Name = "propertyGrid1";
66 | this.propertyGrid1.Size = new System.Drawing.Size(356, 391);
67 | this.propertyGrid1.TabIndex = 0;
68 | this.propertyGrid1.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler(this.PropertyGrid1_PropertyValueChanged);
69 | //
70 | // treeView1
71 | //
72 | this.treeView1.ContextMenuStrip = this.contextMenuStrip1;
73 | this.treeView1.Dock = System.Windows.Forms.DockStyle.Fill;
74 | this.treeView1.Location = new System.Drawing.Point(0, 0);
75 | this.treeView1.Name = "treeView1";
76 | this.treeView1.Size = new System.Drawing.Size(180, 391);
77 | this.treeView1.TabIndex = 1;
78 | this.treeView1.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.TreeView1_AfterSelect);
79 | //
80 | // contextMenuStrip1
81 | //
82 | this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
83 | this.addEntryToolStripMenuItem,
84 | this.duplicateToolStripMenuItem,
85 | this.deleteToolStripMenuItem,
86 | this.toolStripSeparator3,
87 | this.templatesToolStripMenuItem,
88 | this.toolStripSeparator2,
89 | this.expandAllToolStripMenuItem});
90 | this.contextMenuStrip1.Name = "contextMenuStrip1";
91 | this.contextMenuStrip1.Size = new System.Drawing.Size(181, 148);
92 | //
93 | // addEntryToolStripMenuItem
94 | //
95 | this.addEntryToolStripMenuItem.Name = "addEntryToolStripMenuItem";
96 | this.addEntryToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
97 | this.addEntryToolStripMenuItem.Text = "Add entry";
98 | this.addEntryToolStripMenuItem.Click += new System.EventHandler(this.AddEntryToolStripMenuItem_Click);
99 | //
100 | // duplicateToolStripMenuItem
101 | //
102 | this.duplicateToolStripMenuItem.Name = "duplicateToolStripMenuItem";
103 | this.duplicateToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
104 | this.duplicateToolStripMenuItem.Text = "Duplicate";
105 | this.duplicateToolStripMenuItem.Click += new System.EventHandler(this.duplicateToolStripMenuItem_Click);
106 | //
107 | // deleteToolStripMenuItem
108 | //
109 | this.deleteToolStripMenuItem.Name = "deleteToolStripMenuItem";
110 | this.deleteToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
111 | this.deleteToolStripMenuItem.Text = "Delete";
112 | this.deleteToolStripMenuItem.Click += new System.EventHandler(this.DeleteToolStripMenuItem_Click);
113 | //
114 | // toolStripSeparator2
115 | //
116 | this.toolStripSeparator2.Name = "toolStripSeparator2";
117 | this.toolStripSeparator2.Size = new System.Drawing.Size(177, 6);
118 | //
119 | // expandAllToolStripMenuItem
120 | //
121 | this.expandAllToolStripMenuItem.Name = "expandAllToolStripMenuItem";
122 | this.expandAllToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.L)));
123 | this.expandAllToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
124 | this.expandAllToolStripMenuItem.Text = "Expand all";
125 | this.expandAllToolStripMenuItem.Click += new System.EventHandler(this.expandAllToolStripMenuItem_Click);
126 | //
127 | // menuStrip1
128 | //
129 | this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
130 | this.fileToolStripMenuItem,
131 | this.ByteOrderToolStripMenuItem});
132 | this.menuStrip1.Location = new System.Drawing.Point(0, 0);
133 | this.menuStrip1.Name = "menuStrip1";
134 | this.menuStrip1.Size = new System.Drawing.Size(540, 24);
135 | this.menuStrip1.TabIndex = 2;
136 | this.menuStrip1.Text = "menuStrip1";
137 | //
138 | // fileToolStripMenuItem
139 | //
140 | this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
141 | this.saveAsToolStripMenuItem,
142 | this.saveToolStripMenuItem,
143 | this.toolStripSeparator1,
144 | this.exportToJSONToolStripMenuItem,
145 | this.importFromJSONToolStripMenuItem});
146 | this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
147 | this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
148 | this.fileToolStripMenuItem.Text = "File";
149 | //
150 | // saveAsToolStripMenuItem
151 | //
152 | this.saveAsToolStripMenuItem.Name = "saveAsToolStripMenuItem";
153 | this.saveAsToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift)
154 | | System.Windows.Forms.Keys.S)));
155 | this.saveAsToolStripMenuItem.Size = new System.Drawing.Size(212, 22);
156 | this.saveAsToolStripMenuItem.Text = "Save as";
157 | this.saveAsToolStripMenuItem.Click += new System.EventHandler(this.SaveToolStripMenuItem_Click);
158 | //
159 | // saveToolStripMenuItem
160 | //
161 | this.saveToolStripMenuItem.Name = "saveToolStripMenuItem";
162 | this.saveToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S)));
163 | this.saveToolStripMenuItem.Size = new System.Drawing.Size(212, 22);
164 | this.saveToolStripMenuItem.Text = "Save";
165 | this.saveToolStripMenuItem.Visible = false;
166 | this.saveToolStripMenuItem.Click += new System.EventHandler(this.SaveAsToArchiveToolStripMenuItem_Click);
167 | //
168 | // toolStripSeparator1
169 | //
170 | this.toolStripSeparator1.Name = "toolStripSeparator1";
171 | this.toolStripSeparator1.Size = new System.Drawing.Size(209, 6);
172 | //
173 | // exportToJSONToolStripMenuItem
174 | //
175 | this.exportToJSONToolStripMenuItem.Name = "exportToJSONToolStripMenuItem";
176 | this.exportToJSONToolStripMenuItem.Size = new System.Drawing.Size(212, 22);
177 | this.exportToJSONToolStripMenuItem.Text = "Export to JSON";
178 | this.exportToJSONToolStripMenuItem.Click += new System.EventHandler(this.ExportToJSONToolStripMenuItem_Click);
179 | //
180 | // importFromJSONToolStripMenuItem
181 | //
182 | this.importFromJSONToolStripMenuItem.Name = "importFromJSONToolStripMenuItem";
183 | this.importFromJSONToolStripMenuItem.Size = new System.Drawing.Size(212, 22);
184 | this.importFromJSONToolStripMenuItem.Text = "Import from JSON";
185 | this.importFromJSONToolStripMenuItem.Click += new System.EventHandler(this.ImportFromJSONToolStripMenuItem_Click);
186 | //
187 | // ByteOrderToolStripMenuItem
188 | //
189 | this.ByteOrderToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
190 | this.SwitchByteOrderToolStripMenuItem});
191 | this.ByteOrderToolStripMenuItem.Name = "ByteOrderToolStripMenuItem";
192 | this.ByteOrderToolStripMenuItem.Size = new System.Drawing.Size(113, 20);
193 | this.ByteOrderToolStripMenuItem.Text = "Big endian (Wii u)";
194 | //
195 | // SwitchByteOrderToolStripMenuItem
196 | //
197 | this.SwitchByteOrderToolStripMenuItem.Name = "SwitchByteOrderToolStripMenuItem";
198 | this.SwitchByteOrderToolStripMenuItem.Size = new System.Drawing.Size(234, 22);
199 | this.SwitchByteOrderToolStripMenuItem.Text = "Switch to little endian (Switch)";
200 | this.SwitchByteOrderToolStripMenuItem.Click += new System.EventHandler(this.SwitchByteOrderToolStripMenuItem_Click);
201 | //
202 | // splitContainer1
203 | //
204 | this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
205 | this.splitContainer1.Location = new System.Drawing.Point(0, 24);
206 | this.splitContainer1.Name = "splitContainer1";
207 | //
208 | // splitContainer1.Panel1
209 | //
210 | this.splitContainer1.Panel1.Controls.Add(this.treeView1);
211 | //
212 | // splitContainer1.Panel2
213 | //
214 | this.splitContainer1.Panel2.Controls.Add(this.propertyGrid1);
215 | this.splitContainer1.Size = new System.Drawing.Size(540, 391);
216 | this.splitContainer1.SplitterDistance = 180;
217 | this.splitContainer1.TabIndex = 3;
218 | //
219 | // templatesToolStripMenuItem
220 | //
221 | this.templatesToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
222 | this.noTemplatesAvailableToolStripMenuItem});
223 | this.templatesToolStripMenuItem.Name = "templatesToolStripMenuItem";
224 | this.templatesToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
225 | this.templatesToolStripMenuItem.Text = "Insert template";
226 | this.templatesToolStripMenuItem.DropDownOpening += new System.EventHandler(this.templatesToolStripMenuItem_DropDownOpening);
227 | //
228 | // toolStripSeparator3
229 | //
230 | this.toolStripSeparator3.Name = "toolStripSeparator3";
231 | this.toolStripSeparator3.Size = new System.Drawing.Size(177, 6);
232 | //
233 | // noTemplatesAvailableToolStripMenuItem
234 | //
235 | this.noTemplatesAvailableToolStripMenuItem.Name = "noTemplatesAvailableToolStripMenuItem";
236 | this.noTemplatesAvailableToolStripMenuItem.Size = new System.Drawing.Size(194, 22);
237 | this.noTemplatesAvailableToolStripMenuItem.Text = "No templates available";
238 | //
239 | // BflanEditor
240 | //
241 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
242 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
243 | this.ClientSize = new System.Drawing.Size(540, 415);
244 | this.Controls.Add(this.splitContainer1);
245 | this.Controls.Add(this.menuStrip1);
246 | this.KeyPreview = true;
247 | this.MainMenuStrip = this.menuStrip1;
248 | this.Name = "BflanEditor";
249 | this.Text = "BflanEditor";
250 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.BflanEditor_FormClosing);
251 | this.Load += new System.EventHandler(this.BflanEditor_Load);
252 | this.LocationChanged += new System.EventHandler(this.BflanEditor_LocationChanged);
253 | this.Click += new System.EventHandler(this.BflanEditor_Click);
254 | this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.BflanEditor_KeyDown);
255 | this.contextMenuStrip1.ResumeLayout(false);
256 | this.menuStrip1.ResumeLayout(false);
257 | this.menuStrip1.PerformLayout();
258 | this.splitContainer1.Panel1.ResumeLayout(false);
259 | this.splitContainer1.Panel2.ResumeLayout(false);
260 | ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
261 | this.splitContainer1.ResumeLayout(false);
262 | this.ResumeLayout(false);
263 | this.PerformLayout();
264 |
265 | }
266 |
267 | #endregion
268 |
269 | private System.Windows.Forms.PropertyGrid propertyGrid1;
270 | private System.Windows.Forms.TreeView treeView1;
271 | private System.Windows.Forms.MenuStrip menuStrip1;
272 | private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
273 | private System.Windows.Forms.ToolStripMenuItem saveAsToolStripMenuItem;
274 | private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem;
275 | private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
276 | private System.Windows.Forms.ToolStripMenuItem addEntryToolStripMenuItem;
277 | private System.Windows.Forms.ToolStripMenuItem deleteToolStripMenuItem;
278 | private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
279 | private System.Windows.Forms.ToolStripMenuItem exportToJSONToolStripMenuItem;
280 | private System.Windows.Forms.ToolStripMenuItem importFromJSONToolStripMenuItem;
281 | private System.Windows.Forms.ToolStripMenuItem ByteOrderToolStripMenuItem;
282 | private System.Windows.Forms.ToolStripMenuItem SwitchByteOrderToolStripMenuItem;
283 | private System.Windows.Forms.SplitContainer splitContainer1;
284 | private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
285 | private System.Windows.Forms.ToolStripMenuItem expandAllToolStripMenuItem;
286 | private System.Windows.Forms.ToolStripMenuItem duplicateToolStripMenuItem;
287 | private System.Windows.Forms.ToolStripSeparator toolStripSeparator3;
288 | private System.Windows.Forms.ToolStripMenuItem templatesToolStripMenuItem;
289 | private System.Windows.Forms.ToolStripMenuItem noTemplatesAvailableToolStripMenuItem;
290 | }
291 | }
--------------------------------------------------------------------------------
/BflytPreview/BflanEditor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 | using System.IO;
11 | using SwitchThemes.Common;
12 | using BflytPreview.EditorForms;
13 | using Newtonsoft.Json;
14 | using SwitchThemes.Common.Serializers;
15 | using SwitchThemes.Common.Bflan;
16 | using System.Diagnostics;
17 | using BflytPreview.Automation;
18 |
19 | namespace BflytPreview
20 | {
21 | public partial class BflanEditor : Form
22 | {
23 | readonly LoadedTemplate[] BflanTemplates;
24 |
25 | BflanFile file = null;
26 |
27 | IFileWriter _saveTo;
28 | public IFileWriter SaveTo
29 | {
30 | get => _saveTo;
31 | set
32 | {
33 | _saveTo?.EditorClosed();
34 | _saveTo = value;
35 | saveToolStripMenuItem.Visible = _saveTo != null;
36 | this.Text = value?.ToString() ?? "";
37 | }
38 | }
39 |
40 | class LoadedTemplate
41 | {
42 | public BflanTemplate Manifest;
43 | public string FullPathToTemplate;
44 |
45 | public static LoadedTemplate FromJsonManifest(string path)
46 | {
47 | path = Path.GetFullPath(path);
48 | var res = new LoadedTemplate
49 | {
50 | Manifest = JsonConvert.DeserializeObject(File.ReadAllText(path))
51 | };
52 |
53 | if (res.Manifest == null)
54 | throw new Exception("Couldn't load the json for " + path);
55 |
56 | if (Path.IsPathRooted(res.Manifest.FileName))
57 | {
58 | res.FullPathToTemplate = res.Manifest.FileName;
59 | }
60 | else
61 | {
62 | var root = Path.GetDirectoryName(path);
63 | res.FullPathToTemplate = Path.Combine(root, res.Manifest.FileName);
64 | }
65 |
66 | if (!File.Exists(res.FullPathToTemplate))
67 | throw new Exception($"Couldn't find the template file for {path}, tried searchingi n {res.FullPathToTemplate}");
68 |
69 | return res;
70 | }
71 | }
72 |
73 | public BflanEditor(BflanFile _file, IFileWriter saveTo)
74 | {
75 | InitializeComponent();
76 | file = _file;
77 | SaveTo = saveTo;
78 |
79 | try
80 | {
81 | if (Directory.Exists("BflanTemplates"))
82 | BflanTemplates = Directory.EnumerateFiles("BflanTemplates", "*.json")
83 | .Select(x => LoadedTemplate.FromJsonManifest(x))
84 | .ToArray();
85 | else
86 | BflanTemplates = new LoadedTemplate[0];
87 | }
88 | catch (Exception ex)
89 | {
90 | MessageBox.Show("Error while loading BFLAn template: " + ex.Message + "\r\n\r\nFix the issue then close and reopen this editor to reload the files");
91 | BflanTemplates = new LoadedTemplate[0];
92 | }
93 | }
94 |
95 | private void BflanEditor_Load(object sender, EventArgs e)
96 | {
97 | if (file == null) this.Close();
98 | UpdateTreeview();
99 | FormBringToFront();
100 | }
101 |
102 | void UpdateByteOrder()
103 | {
104 | ByteOrderToolStripMenuItem.Text =
105 | file.byteOrder == Syroot.BinaryData.ByteOrder.BigEndian ?
106 | "Big endian (Wii u)" : "Little endian (Switch/3DS)";
107 | SwitchByteOrderToolStripMenuItem.Text =
108 | file.byteOrder == Syroot.BinaryData.ByteOrder.BigEndian ?
109 | "Change to little endian" : "Change to big endian";
110 | }
111 |
112 | void UpdateTreeview()
113 | {
114 | UpdateByteOrder();
115 | treeView1.Nodes.Clear();
116 | foreach (var section in file.Sections)
117 | BflanObjectTonode(section, treeView1.Nodes);
118 | }
119 |
120 | void BflanObjectTonode(object obj, TreeNodeCollection parent)
121 | {
122 | var subnode = parent.Add(obj.ToString());
123 | subnode.Tag = obj;
124 | BflanObjectChildrenToNode(obj, subnode);
125 | }
126 |
127 | void BflanObjectChildrenToNode(object obj, TreeNode node)
128 | {
129 | if (obj is Pai1Section paisection)
130 | {
131 | foreach (var entry in paisection.Entries)
132 | BflanObjectTonode(entry, node.Nodes);
133 | }
134 | else if (obj is Pai1Section.PaiEntry paientry)
135 | {
136 | foreach (var tag in paientry.Tags)
137 | BflanObjectTonode(tag, node.Nodes);
138 | }
139 | else if (obj is Pai1Section.PaiTag paitag)
140 | {
141 | foreach (var entry in paitag.Entries)
142 | BflanObjectTonode(entry, node.Nodes);
143 | }
144 | }
145 |
146 | private void TreeView1_AfterSelect(object sender, TreeViewEventArgs e) =>
147 | propertyGrid1.SelectedObject = e.Node.Tag;
148 |
149 | private void SaveToolStripMenuItem_Click(object sender, EventArgs e)
150 | {
151 | SaveFileDialog sav = new SaveFileDialog() { Filter = "Bflan file|*.bflan" };
152 | if (sav.ShowDialog() != DialogResult.OK) return;
153 | SaveTo = new DiskFileProvider(sav.FileName);
154 | SaveTo.Save(file.WriteFile());
155 | }
156 |
157 | private void SaveAsToArchiveToolStripMenuItem_Click(object sender, EventArgs e)
158 | {
159 | if (_saveTo != null)
160 | _saveTo.Save(file.WriteFile());
161 | else saveAsToolStripMenuItem.PerformClick();
162 | }
163 |
164 | private void BflanEditor_FormClosing(object sender, FormClosingEventArgs e)
165 | {
166 | SaveTo?.EditorClosed();
167 | Settings.Default.ShowImage = false;
168 | }
169 |
170 | void FormBringToFront()
171 | {
172 | this.Activate();
173 | this.BringToFront();
174 | this.Focus();
175 | }
176 |
177 | private void BflanEditor_Click(object sender, EventArgs e) => FormBringToFront();
178 | private void BflanEditor_LocationChanged(object sender, EventArgs e) => FormBringToFront();
179 |
180 | private void InsertEntry(object target, object entry, TreeNode viewNode)
181 | {
182 | if (target is Pai1Section sect && entry is Pai1Section.PaiEntry paiEntry)
183 | sect.Entries.Add(paiEntry);
184 | else if (target is Pai1Section.PaiEntry targetPai && entry is Pai1Section.PaiTag paiTag)
185 | targetPai.Tags.Add(paiTag);
186 | else if (target is Pai1Section.PaiTag targetPaiTag && entry is Pai1Section.PaiTagEntry paiTagEntry)
187 | targetPaiTag.Entries.Add(paiTagEntry);
188 | else
189 | {
190 | MessageBox.Show("Can't insert the parent object here");
191 | return;
192 | }
193 |
194 | BflanObjectTonode(entry, viewNode.Nodes);
195 | }
196 |
197 | private void AddEntryToolStripMenuItem_Click(object sender, EventArgs e)
198 | {
199 | var parent = treeView1.SelectedNode.Tag;
200 | object entry = null;
201 |
202 | if (parent is Pai1Section)
203 | entry = new Pai1Section.PaiEntry() { Name = "NEW-" };
204 | else if (parent is Pai1Section.PaiEntry)
205 | entry = new Pai1Section.PaiTag() { TagType = "NEW-" };
206 | else if (parent is Pai1Section.PaiTag paiTag)
207 | entry = new Pai1Section.PaiTagEntry() { FLEUEntryName = paiTag.IsFLEU ? "New FLEU entry" : null };
208 | else
209 | {
210 | MessageBox.Show("Can't add an entry to the parent object");
211 | return;
212 | }
213 |
214 | if (entry != null)
215 | InsertEntry(parent, entry, treeView1.SelectedNode);
216 | }
217 |
218 | private void duplicateToolStripMenuItem_Click(object sender, EventArgs e)
219 | {
220 | if (treeView1.SelectedNode == null || treeView1.SelectedNode.Parent == null) return;
221 |
222 | var clone = ((ICloneable)treeView1.SelectedNode.Tag).Clone();
223 |
224 | // Can names be duplicate ?
225 | var parent = treeView1.SelectedNode.Parent;
226 | InsertEntry(parent.Tag, clone, parent);
227 | }
228 |
229 | private void DeleteToolStripMenuItem_Click(object sender, EventArgs e)
230 | {
231 | var selected = treeView1.SelectedNode;
232 | var parent = treeView1.SelectedNode?.Parent;
233 | if (selected.Tag is Pai1Section.PaiEntry entry)
234 | {
235 | var par = (Pai1Section)parent.Tag;
236 | par.Entries.Remove(entry);
237 | }
238 | else if (selected.Tag is Pai1Section.PaiTag tag)
239 | {
240 | var par = (Pai1Section.PaiEntry)parent.Tag;
241 | par.Tags.Remove(tag);
242 | }
243 | else if (selected.Tag is Pai1Section.PaiTagEntry tagEntry)
244 | {
245 | var par = (Pai1Section.PaiTag)parent.Tag;
246 | par.Entries.Remove(tagEntry);
247 | }
248 | else
249 | {
250 | MessageBox.Show("Can't remove this element");
251 | return;
252 | }
253 |
254 | parent.Nodes.Remove(selected);
255 | }
256 |
257 | private void ExportToJSONToolStripMenuItem_Click(object sender, EventArgs e)
258 | {
259 | SaveFileDialog sav = new SaveFileDialog() { Filter = "JSON file|*.json" };
260 | if (sav.ShowDialog() != DialogResult.OK) return;
261 | File.WriteAllText(sav.FileName, JsonConvert.SerializeObject(BflanSerializer.Serialize(file), Formatting.Indented));
262 | }
263 |
264 | private void ImportFromJSONToolStripMenuItem_Click(object sender, EventArgs e)
265 | {
266 | OpenFileDialog opn = new OpenFileDialog() { Filter = "JSON file|*.json" };
267 | if (opn.ShowDialog() != DialogResult.OK) return;
268 | var SerializedFile = JsonConvert.DeserializeObject(File.ReadAllText(opn.FileName));
269 | var newFile = SerializedFile.Deserialize();
270 | if (file != null && newFile.Version != file.Version)
271 | {
272 | if (MessageBox.Show("Do you want to keep the format version of the original file ?\n(You should for custom themes)", "", MessageBoxButtons.YesNo) == DialogResult.Yes)
273 | newFile.Version = file.Version;
274 | }
275 | file = newFile;
276 | UpdateTreeview();
277 | }
278 |
279 | public static Form OpenFromJson()
280 | {
281 | var b = new BflanEditor(null, null);
282 | b.ImportFromJSONToolStripMenuItem_Click(null,null);
283 | if (b.file == null) return null;
284 | return b;
285 | }
286 |
287 | private void PropertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
288 | {
289 | treeView1.SelectedNode.Text = treeView1.SelectedNode.Tag.ToString();
290 | treeView1.Invalidate();
291 | }
292 |
293 | private void SwitchByteOrderToolStripMenuItem_Click(object sender, EventArgs e)
294 | {
295 | file.byteOrder = file.byteOrder == Syroot.BinaryData.ByteOrder.BigEndian ?
296 | Syroot.BinaryData.ByteOrder.LittleEndian : Syroot.BinaryData.ByteOrder.BigEndian;
297 | UpdateByteOrder();
298 | }
299 |
300 | private void BflanEditor_KeyDown(object sender, KeyEventArgs e)
301 | {
302 | e.SuppressKeyPress = true;
303 | if (e.Shift && e.Control && e.KeyCode == Keys.S)
304 | saveAsToolStripMenuItem.PerformClick();
305 | else if (e.Control && e.KeyCode == Keys.S)
306 | saveToolStripMenuItem.PerformClick();
307 | else if (e.Control && e.KeyCode == Keys.L)
308 | treeView1.ExpandAll();
309 | else if (e.Control && e.KeyCode == Keys.K)
310 | treeView1.CollapseAll();
311 | else e.SuppressKeyPress = false;
312 | }
313 |
314 | private void expandAllToolStripMenuItem_Click(object sender, EventArgs e) =>
315 | treeView1.ExpandAll();
316 |
317 | private void templatesToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
318 | {
319 | templatesToolStripMenuItem.DropDownItems.Clear();
320 |
321 | var currentItem = treeView1.SelectedNode?.Tag;
322 | LoadedTemplate[] templates = null;
323 |
324 | if (currentItem != null)
325 | {
326 | if (!(currentItem is IBflanGenericCollection))
327 | return;
328 |
329 | if (currentItem is Pai1Section) // Contains PaiEntry[]
330 | templates = BflanTemplates.Where(x => x.Manifest.Target == Automation.BflanTemplateKind.Pai1).ToArray();
331 | else if (currentItem is Pai1Section.PaiEntry) // contains PaiTag[]
332 | templates = BflanTemplates.Where(x => x.Manifest.Target == Automation.BflanTemplateKind.PaiEntry).ToArray();
333 | else if (currentItem is Pai1Section.PaiTag) // contains PaiTagEntry[]
334 | templates = BflanTemplates.Where(x => x.Manifest.Target == Automation.BflanTemplateKind.PaiTag).ToArray();
335 | else if (currentItem is Pai1Section.PaiTagEntry) // contains Keyframe[]
336 | templates = BflanTemplates.Where(x => x.Manifest.Target == Automation.BflanTemplateKind.PaiTagEntry).ToArray();
337 | }
338 |
339 | if (templates != null && templates.Length != 0)
340 | {
341 | foreach (var t in templates)
342 | {
343 | var item = templatesToolStripMenuItem.DropDownItems.Add(t.Manifest.Name);
344 | item.Tag = t;
345 | item.Click += templateDynamicItem_Click;
346 | }
347 | }
348 | else
349 | {
350 | templatesToolStripMenuItem.DropDownItems.Add("No templates available for this item");
351 | }
352 | }
353 |
354 | private void templateDynamicItem_Click(object sender, EventArgs e)
355 | {
356 | if (!(treeView1.SelectedNode?.Tag is IBflanGenericCollection bflanItem))
357 | return;
358 |
359 | var template = ((ToolStripItem)sender).Tag as LoadedTemplate;
360 | if (template == null) return;
361 |
362 | if (!File.Exists(template.FullPathToTemplate))
363 | {
364 | MessageBox.Show($"The file {template.FullPathToTemplate} associated with this template was not found");
365 | return;
366 | }
367 |
368 | var content = File.ReadAllText(template.FullPathToTemplate);
369 | using var importer = new ValueImportForm(template.Manifest, content);
370 | importer.ShowDialog();
371 |
372 | if (importer.Result == null)
373 | return;
374 |
375 | object[] deserialized = template.Manifest.DeserializeContent(importer.Result);
376 |
377 | foreach (var obj in deserialized)
378 | bflanItem.InsertElement(obj);
379 |
380 | treeView1.SelectedNode.Nodes.Clear();
381 | BflanObjectChildrenToNode(bflanItem, treeView1.SelectedNode);
382 | }
383 | }
384 | }
385 |
--------------------------------------------------------------------------------
/BflytPreview/BflanEditor.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 132, 17
122 |
123 |
124 | 17, 17
125 |
126 |
--------------------------------------------------------------------------------
/BflytPreview/BflanTemplates/ColorAnimation.json:
--------------------------------------------------------------------------------
1 | {
2 | "Name": "Animate color RGBA",
3 | "FileName": "ColorAnimation.template",
4 | "Target": "PaiEntry",
5 | "Parameters": [
6 | {
7 | "Kind": "Int",
8 | "Name": "Start frame",
9 | "Default": "0",
10 | "Keyword": "%START_FRAME%"
11 | },
12 | {
13 | "Kind": "Int",
14 | "Name": "End frame",
15 | "Default": "20",
16 | "Keyword": "%END_FRAME%"
17 | },
18 | {
19 | "Kind": "Int",
20 | "Name": "Red start value",
21 | "Default": "255",
22 | "Keyword": "%RED_START_VAL%"
23 | },
24 | {
25 | "Kind": "Int",
26 | "Name": "Red end value",
27 | "Default": "0",
28 | "Keyword": "%RED_END_VAL%"
29 | },
30 | {
31 | "Kind": "Int",
32 | "Name": "Green start value",
33 | "Default": "255",
34 | "Keyword": "%GREEN_START_VAL%"
35 | },
36 | {
37 | "Kind": "Int",
38 | "Name": "Green end value",
39 | "Default": "0",
40 | "Keyword": "%GREEN_END_VAL%"
41 | },
42 | {
43 | "Kind": "Int",
44 | "Name": "Blue start value",
45 | "Default": "255",
46 | "Keyword": "%BLUE_START_VAL%"
47 | },
48 | {
49 | "Kind": "Int",
50 | "Name": "Blue end value",
51 | "Default": "0",
52 | "Keyword": "%BLUE_END_VAL%"
53 | },
54 | {
55 | "Kind": "Int",
56 | "Name": "Alpha start value",
57 | "Default": "255",
58 | "Keyword": "%ALPHA_START_VAL%"
59 | },
60 | {
61 | "Kind": "Int",
62 | "Name": "Alpha end value",
63 | "Default": "0",
64 | "Keyword": "%ALPHA_END_VAL%"
65 | }
66 | ]
67 | }
--------------------------------------------------------------------------------
/BflytPreview/BflanTemplates/ColorAnimation.template:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "Unknown": 0,
4 | "TagType": "FLVC",
5 | "Entries": [
6 | {
7 | "Index": 0,
8 | "AnimationTarget": 0,
9 | "DataType": 2,
10 | "KeyFrames": [
11 | { "Frame": %START_FRAME%, "Value": %RED_START_VAL%, "Blend": 0 },
12 | { "Frame": %END_FRAME%, "Value": %RED_END_VAL%, "Blend": 0 }
13 | ],
14 | "FLEUUnknownInt": 0,
15 | "FLEUEntryName": ""
16 | },
17 | {
18 | "Index": 0,
19 | "AnimationTarget": 4,
20 | "DataType": 2,
21 | "KeyFrames": [
22 | { "Frame": %START_FRAME%, "Value": %RED_START_VAL%, "Blend": 0 },
23 | { "Frame": %END_FRAME%, "Value": %RED_END_VAL%, "Blend": 0 }
24 | ],
25 | "FLEUUnknownInt": 0,
26 | "FLEUEntryName": ""
27 | },
28 | {
29 | "Index": 0,
30 | "AnimationTarget": 8,
31 | "DataType": 2,
32 | "KeyFrames": [
33 | { "Frame": %START_FRAME%, "Value": %RED_START_VAL%, "Blend": 0 },
34 | { "Frame": %END_FRAME%, "Value": %RED_END_VAL%, "Blend": 0 }
35 | ],
36 | "FLEUUnknownInt": 0,
37 | "FLEUEntryName": ""
38 | },
39 | {
40 | "Index": 0,
41 | "AnimationTarget": 12,
42 | "DataType": 2,
43 | "KeyFrames": [
44 | { "Frame": %START_FRAME%, "Value": %RED_START_VAL%, "Blend": 0 },
45 | { "Frame": %END_FRAME%, "Value": %RED_END_VAL%, "Blend": 0 }
46 | ],
47 | "FLEUUnknownInt": 0,
48 | "FLEUEntryName": ""
49 | }
50 | ]
51 | }
52 | ]
--------------------------------------------------------------------------------
/BflytPreview/BflytPreview.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {D59C0348-7D8E-46DF-8761-1CA9C5FF5556}
8 | WinExe
9 | BflytPreview
10 | Switch Layout Editor
11 | v4.8
12 | 512
13 | true
14 |
15 |
16 | publish\
17 | true
18 | Disk
19 | false
20 | Foreground
21 | 7
22 | Days
23 | false
24 | false
25 | true
26 | 0
27 | 1.0.0.%2a
28 | false
29 | false
30 | true
31 |
32 |
33 |
34 | AnyCPU
35 | true
36 | full
37 | false
38 | bin\Debug\
39 | TRACE;DEBUG;WIN;LYTEDITOR
40 | prompt
41 | 4
42 | 8.0
43 |
44 |
45 | AnyCPU
46 | none
47 | true
48 | bin\Release\
49 | TRACE;WIN;LYTEDITOR
50 | prompt
51 | 4
52 | 8.0
53 | false
54 |
55 |
56 | icon.ico
57 |
58 |
59 | true
60 |
61 |
62 |
63 | ..\packages\Newtonsoft.Json.13.0.2\lib\net45\Newtonsoft.Json.dll
64 |
65 |
66 | ..\packages\Octokit.5.0.0\lib\netstandard2.0\Octokit.dll
67 |
68 |
69 | ..\packages\OpenTK.3.3.3\lib\net20\OpenTK.dll
70 |
71 |
72 | ..\packages\OpenTK.GLControl.3.3.3\lib\net20\OpenTK.GLControl.dll
73 |
74 |
75 |
76 |
77 |
78 | ..\packages\System.Collections.Specialized.4.3.0\lib\net46\System.Collections.Specialized.dll
79 | True
80 | True
81 |
82 |
83 |
84 |
85 | ..\packages\System.ComponentModel.Primitives.4.3.0\lib\net45\System.ComponentModel.Primitives.dll
86 | True
87 | True
88 |
89 |
90 |
91 |
92 |
93 | ..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll
94 |
95 |
96 |
97 | ..\packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll
98 |
99 |
100 | ..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll
101 | True
102 | True
103 |
104 |
105 | ..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll
106 | True
107 | True
108 |
109 |
110 | ..\packages\System.IO.FileSystem.Watcher.4.3.0\lib\net46\System.IO.FileSystem.Watcher.dll
111 | True
112 | True
113 |
114 |
115 | ..\packages\System.Reflection.TypeExtensions.4.7.0\lib\net461\System.Reflection.TypeExtensions.dll
116 |
117 |
118 | ..\packages\System.Runtime.4.3.1\lib\net462\System.Runtime.dll
119 | True
120 | True
121 |
122 |
123 | ..\packages\System.Runtime.Extensions.4.3.1\lib\net462\System.Runtime.Extensions.dll
124 | True
125 | True
126 |
127 |
128 | ..\packages\System.Runtime.InteropServices.4.3.0\lib\net463\System.Runtime.InteropServices.dll
129 | True
130 | True
131 |
132 |
133 | ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll
134 | True
135 | True
136 |
137 |
138 | ..\packages\System.Threading.Thread.4.3.0\lib\net46\System.Threading.Thread.dll
139 | True
140 | True
141 |
142 |
143 | ..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 | Form
163 |
164 |
165 | ValueImportForm.cs
166 |
167 |
168 | Form
169 |
170 |
171 | BflanEditor.cs
172 |
173 |
174 |
175 |
176 |
177 | Form
178 |
179 |
180 | LayoutDiffForm.cs
181 |
182 |
183 | Form
184 |
185 |
186 | SzsEditor.cs
187 |
188 |
189 | Form
190 |
191 |
192 | EditorView.cs
193 |
194 |
195 | Form
196 |
197 |
198 | MainForm.cs
199 |
200 |
201 |
202 |
203 | True
204 | True
205 | Settings.settings
206 |
207 |
208 | Form
209 |
210 |
211 | SettingsWindow.cs
212 |
213 |
214 | ValueImportForm.cs
215 |
216 |
217 | BflanEditor.cs
218 |
219 |
220 | LayoutDiffForm.cs
221 |
222 |
223 | SzsEditor.cs
224 |
225 |
226 | EditorView.cs
227 |
228 |
229 | MainForm.cs
230 |
231 |
232 | ResXFileCodeGenerator
233 | Resources.Designer.cs
234 | Designer
235 |
236 |
237 | True
238 | Resources.resx
239 | True
240 |
241 |
242 | SettingsWindow.cs
243 |
244 |
245 | PreserveNewest
246 |
247 |
248 | PreserveNewest
249 |
250 |
251 |
252 |
253 | SettingsSingleFileGenerator
254 | Settings.Designer.cs
255 |
256 |
257 | True
258 | Settings.settings
259 | True
260 |
261 |
262 | SettingsSingleFileGenerator
263 | Settings.Designer.cs
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 | False
276 | Microsoft .NET Framework 4.6.1 %28x86 et x64%29
277 | true
278 |
279 |
280 | False
281 | .NET Framework 3.5 SP1
282 | false
283 |
284 |
285 |
286 |
287 |
--------------------------------------------------------------------------------
/BflytPreview/EditorForms/HexEditorForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.Design;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Windows.Forms;
8 |
9 | namespace BflytPreview.EditorForms
10 | {
11 | public class HexEditorForm
12 | {
13 | public static void Show(byte[] data)
14 | {
15 | Form f = new Form();
16 | f.Text = "Hex editor";
17 | ByteViewer bv = new ByteViewer();
18 | bv.Dock = DockStyle.Fill;
19 | f.Controls.Add(bv);
20 | bv.SetBytes(data);
21 | f.TopMost = true;
22 | f.Show();
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/BflytPreview/EditorForms/IFileProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace BflytPreview
8 | {
9 | public interface IFileWriter
10 | {
11 | void Save(byte[] Data);
12 | void EditorClosed();
13 |
14 | string Path { get; }
15 | }
16 |
17 | public class DiskFileProvider : IFileWriter
18 | {
19 | public DiskFileProvider(string path) =>
20 | Path = path;
21 |
22 | public string Path { get; set; }
23 |
24 | public void EditorClosed() { }
25 |
26 | public void Save(byte[] Data) =>
27 | System.IO.File.WriteAllBytes(Path, Data);
28 |
29 | public override string ToString() => Path;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/BflytPreview/EditorForms/InputDialog.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Windows.Forms;
8 |
9 | namespace BflytPreview.EditorForms
10 | {
11 | public static class InputDialog
12 | {
13 | public static DialogResult Show(string title, string promptText, ref string value)
14 | {
15 | Form form = new Form();
16 | Label label = new Label();
17 | TextBox textBox = new TextBox();
18 | Button buttonOk = new Button();
19 | Button buttonCancel = new Button();
20 |
21 | form.Text = title;
22 | label.Text = promptText;
23 | textBox.Text = value;
24 |
25 | buttonOk.Text = "OK";
26 | buttonCancel.Text = "Cancel";
27 | buttonOk.DialogResult = DialogResult.OK;
28 | buttonCancel.DialogResult = DialogResult.Cancel;
29 |
30 | label.SetBounds(9, 20, 372, 13);
31 | textBox.SetBounds(12, 36, 372, 20);
32 | buttonOk.SetBounds(228, 72, 75, 23);
33 | buttonCancel.SetBounds(309, 72, 75, 23);
34 |
35 | label.AutoSize = true;
36 | textBox.Anchor = textBox.Anchor | AnchorStyles.Right;
37 | buttonOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
38 | buttonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
39 |
40 | form.ClientSize = new Size(396, 107);
41 | form.Controls.AddRange(new Control[] { label, textBox, buttonOk, buttonCancel });
42 | form.ClientSize = new Size(Math.Max(300, label.Right + 10), form.ClientSize.Height);
43 | form.FormBorderStyle = FormBorderStyle.FixedDialog;
44 | form.StartPosition = FormStartPosition.CenterScreen;
45 | form.MinimizeBox = false;
46 | form.MaximizeBox = false;
47 | form.AcceptButton = buttonOk;
48 | form.CancelButton = buttonCancel;
49 |
50 | DialogResult dialogResult = form.ShowDialog();
51 | value = textBox.Text;
52 | return dialogResult;
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/BflytPreview/EditorForms/LayoutDiffForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace BflytPreview.EditorForms
2 | {
3 | partial class LayoutDiffForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(LayoutDiffForm));
32 | this.button1 = new System.Windows.Forms.Button();
33 | this.button2 = new System.Windows.Forms.Button();
34 | this.label1 = new System.Windows.Forms.Label();
35 | this.label2 = new System.Windows.Forms.Label();
36 | this.textBox1 = new System.Windows.Forms.TextBox();
37 | this.textBox2 = new System.Windows.Forms.TextBox();
38 | this.label3 = new System.Windows.Forms.Label();
39 | this.button3 = new System.Windows.Forms.Button();
40 | this.label4 = new System.Windows.Forms.Label();
41 | this.cb11Compat = new System.Windows.Forms.CheckBox();
42 | this.cbIgnoreMissingPanes = new System.Windows.Forms.CheckBox();
43 | this.SuspendLayout();
44 | //
45 | // button1
46 | //
47 | this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
48 | this.button1.Location = new System.Drawing.Point(487, 65);
49 | this.button1.Name = "button1";
50 | this.button1.Size = new System.Drawing.Size(32, 23);
51 | this.button1.TabIndex = 0;
52 | this.button1.Text = "...";
53 | this.button1.UseVisualStyleBackColor = true;
54 | this.button1.Click += new System.EventHandler(this.button1_Click);
55 | //
56 | // button2
57 | //
58 | this.button2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
59 | this.button2.Location = new System.Drawing.Point(487, 112);
60 | this.button2.Name = "button2";
61 | this.button2.Size = new System.Drawing.Size(32, 23);
62 | this.button2.TabIndex = 1;
63 | this.button2.Text = "...";
64 | this.button2.UseVisualStyleBackColor = true;
65 | this.button2.Click += new System.EventHandler(this.button2_Click);
66 | //
67 | // label1
68 | //
69 | this.label1.AutoSize = true;
70 | this.label1.Location = new System.Drawing.Point(12, 50);
71 | this.label1.Name = "label1";
72 | this.label1.Size = new System.Drawing.Size(63, 13);
73 | this.label1.TabIndex = 2;
74 | this.label1.Text = "Original szs:";
75 | //
76 | // label2
77 | //
78 | this.label2.AutoSize = true;
79 | this.label2.Location = new System.Drawing.Point(12, 99);
80 | this.label2.Name = "label2";
81 | this.label2.Size = new System.Drawing.Size(58, 13);
82 | this.label2.TabIndex = 3;
83 | this.label2.Text = "Edited szs:";
84 | //
85 | // textBox1
86 | //
87 | this.textBox1.AllowDrop = true;
88 | this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
89 | | System.Windows.Forms.AnchorStyles.Right)));
90 | this.textBox1.Location = new System.Drawing.Point(15, 67);
91 | this.textBox1.Name = "textBox1";
92 | this.textBox1.ReadOnly = true;
93 | this.textBox1.Size = new System.Drawing.Size(466, 20);
94 | this.textBox1.TabIndex = 4;
95 | this.textBox1.DragDrop += new System.Windows.Forms.DragEventHandler(this.textBox1_DragDrop);
96 | this.textBox1.DragEnter += new System.Windows.Forms.DragEventHandler(this.tbDragEnter);
97 | //
98 | // textBox2
99 | //
100 | this.textBox2.AllowDrop = true;
101 | this.textBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
102 | | System.Windows.Forms.AnchorStyles.Right)));
103 | this.textBox2.Location = new System.Drawing.Point(15, 115);
104 | this.textBox2.Name = "textBox2";
105 | this.textBox2.ReadOnly = true;
106 | this.textBox2.Size = new System.Drawing.Size(466, 20);
107 | this.textBox2.TabIndex = 5;
108 | this.textBox2.DragDrop += new System.Windows.Forms.DragEventHandler(this.textBox2_DragDrop);
109 | this.textBox2.DragEnter += new System.Windows.Forms.DragEventHandler(this.tbDragEnter);
110 | //
111 | // label3
112 | //
113 | this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
114 | | System.Windows.Forms.AnchorStyles.Right)));
115 | this.label3.Location = new System.Drawing.Point(2, 4);
116 | this.label3.Name = "label3";
117 | this.label3.Size = new System.Drawing.Size(528, 42);
118 | this.label3.TabIndex = 6;
119 | this.label3.Text = "Use this tool to generate a custom theme JSON file.\r\nThis will compare layout fil" +
120 | "es from two szs archives (generated layouts are compatible with Switch Themes In" +
121 | "jector).";
122 | //
123 | // button3
124 | //
125 | this.button3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
126 | this.button3.Location = new System.Drawing.Point(417, 348);
127 | this.button3.Name = "button3";
128 | this.button3.Size = new System.Drawing.Size(102, 23);
129 | this.button3.TabIndex = 7;
130 | this.button3.Text = "Generate diff";
131 | this.button3.UseVisualStyleBackColor = true;
132 | this.button3.Click += new System.EventHandler(this.button3_Click);
133 | //
134 | // label4
135 | //
136 | this.label4.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
137 | | System.Windows.Forms.AnchorStyles.Right)));
138 | this.label4.AutoEllipsis = true;
139 | this.label4.Location = new System.Drawing.Point(5, 150);
140 | this.label4.Name = "label4";
141 | this.label4.Size = new System.Drawing.Size(514, 69);
142 | this.label4.TabIndex = 8;
143 | this.label4.Text = resources.GetString("label4.Text");
144 | //
145 | // cb11Compat
146 | //
147 | this.cb11Compat.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
148 | | System.Windows.Forms.AnchorStyles.Right)));
149 | this.cb11Compat.Location = new System.Drawing.Point(12, 267);
150 | this.cb11Compat.Name = "cb11Compat";
151 | this.cb11Compat.Size = new System.Drawing.Size(499, 70);
152 | this.cb11Compat.TabIndex = 9;
153 | this.cb11Compat.Text = "Emulate 10.X layout on 11.0+\r\nThis options removes the \"Switch online\" button and" +
154 | " positions from the home menu, enabling this will make old layouts work on 11.0 " +
155 | "and later firmware.\r\n";
156 | this.cb11Compat.UseVisualStyleBackColor = true;
157 | this.cb11Compat.Visible = false;
158 | //
159 | // cbIgnoreMissingPanes
160 | //
161 | this.cbIgnoreMissingPanes.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
162 | | System.Windows.Forms.AnchorStyles.Right)));
163 | this.cbIgnoreMissingPanes.Location = new System.Drawing.Point(9, 218);
164 | this.cbIgnoreMissingPanes.Name = "cbIgnoreMissingPanes";
165 | this.cbIgnoreMissingPanes.Size = new System.Drawing.Size(499, 49);
166 | this.cbIgnoreMissingPanes.TabIndex = 10;
167 | this.cbIgnoreMissingPanes.Text = "Ignore missing panes between the two files.\r\nThis is a development option and you" +
168 | " should not use it, may produce broken layouts.";
169 | this.cbIgnoreMissingPanes.UseVisualStyleBackColor = true;
170 | //
171 | // LayoutDiffForm
172 | //
173 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
174 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
175 | this.ClientSize = new System.Drawing.Size(531, 376);
176 | this.Controls.Add(this.cbIgnoreMissingPanes);
177 | this.Controls.Add(this.label4);
178 | this.Controls.Add(this.button3);
179 | this.Controls.Add(this.label3);
180 | this.Controls.Add(this.textBox2);
181 | this.Controls.Add(this.textBox1);
182 | this.Controls.Add(this.label2);
183 | this.Controls.Add(this.label1);
184 | this.Controls.Add(this.button2);
185 | this.Controls.Add(this.button1);
186 | this.Controls.Add(this.cb11Compat);
187 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
188 | this.MaximizeBox = false;
189 | this.MinimizeBox = false;
190 | this.Name = "LayoutDiffForm";
191 | this.Text = "Layout Diff";
192 | this.Load += new System.EventHandler(this.LayoutDiffForm_Load);
193 | this.ResumeLayout(false);
194 | this.PerformLayout();
195 |
196 | }
197 |
198 | #endregion
199 |
200 | private System.Windows.Forms.Button button1;
201 | private System.Windows.Forms.Button button2;
202 | private System.Windows.Forms.Label label1;
203 | private System.Windows.Forms.Label label2;
204 | private System.Windows.Forms.TextBox textBox1;
205 | private System.Windows.Forms.TextBox textBox2;
206 | private System.Windows.Forms.Label label3;
207 | private System.Windows.Forms.Button button3;
208 | private System.Windows.Forms.Label label4;
209 | private System.Windows.Forms.CheckBox cb11Compat;
210 | private System.Windows.Forms.CheckBox cbIgnoreMissingPanes;
211 | }
212 | }
--------------------------------------------------------------------------------
/BflytPreview/EditorForms/LayoutDiffForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.IO;
7 | using System.Linq;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 | using System.Windows.Forms;
11 | using SARCExt;
12 | using SwitchThemes.Common;
13 |
14 | namespace BflytPreview.EditorForms
15 | {
16 | public partial class LayoutDiffForm : Form
17 | {
18 | public LayoutDiffForm(SarcData _Original = null, SarcData _Edited = null)
19 | {
20 | InitializeComponent();
21 | if (_Original != null)
22 | {
23 | textBox1.Text = "";
24 | button1.Enabled = false;
25 | textBox1.Enabled = false;
26 | textBox1.AllowDrop = false;
27 | Original = _Original;
28 | }
29 | if (_Edited != null)
30 | {
31 | textBox2.Text = "";
32 | button2.Enabled = false;
33 | textBox2.Enabled = false;
34 | textBox2.AllowDrop = false;
35 | Edited = _Edited;
36 | }
37 |
38 | EnableResidentMenuCheckbox(_Original ?? _Edited);
39 | }
40 |
41 | void EnableResidentMenuCheckbox(SarcData sarc)
42 | {
43 | if (cb11Compat.Tag != null) return;
44 | if (sarc == null) return;
45 | cb11Compat.Visible = (DefaultTemplates.GetFor(sarc)?.NXThemeName ?? "home") == "home";
46 | cb11Compat.Tag = "checked";
47 | }
48 |
49 | SarcData Original = null;
50 | SarcData Edited = null;
51 |
52 | private void button1_Click(object sender, EventArgs e) =>
53 | Original = SelectFile(ref textBox1) ?? Original;
54 |
55 | private void button2_Click(object sender, EventArgs e) =>
56 | Edited = SelectFile(ref textBox2) ?? Edited;
57 |
58 | private void textBox1_DragDrop(object sender, DragEventArgs e) =>
59 | Original = SelectFile(ref textBox1, e) ?? Original;
60 |
61 | private void textBox2_DragDrop(object sender, DragEventArgs e) =>
62 | Edited = SelectFile(ref textBox2, e) ?? Edited;
63 |
64 | private void tbDragEnter(object sender, DragEventArgs e)
65 | {
66 | if (e.Data.GetDataPresent(DataFormats.FileDrop))
67 | e.Effect = DragDropEffects.Copy;
68 | }
69 |
70 | SarcData SelectFile(ref TextBox target, string name = null)
71 | {
72 | if (name is null)
73 | {
74 | OpenFileDialog opn = new OpenFileDialog() { Filter = "szs files|*.szs" };
75 | if (opn.ShowDialog() != DialogResult.OK) return null;
76 | name = opn.FileName;
77 | }
78 | target.Text = name;
79 | var sarc = SARC.Unpack(ManagedYaz0.Decompress(File.ReadAllBytes(target.Text)));
80 | EnableResidentMenuCheckbox(sarc);
81 | return sarc;
82 | }
83 |
84 | SarcData SelectFile(ref TextBox target, DragEventArgs e)
85 | {
86 | var f = (string[])e.Data.GetData(DataFormats.FileDrop);
87 | if (f.Any())
88 | return SelectFile(ref target, f.First());
89 | return null;
90 | }
91 |
92 | private void LayoutDiffForm_Load(object sender, EventArgs e)
93 | {
94 |
95 | }
96 |
97 | private void button3_Click(object sender, EventArgs e)
98 | {
99 | try
100 | {
101 | bool HideOnlineButton = false;
102 | if (cb11Compat.Visible)
103 | HideOnlineButton = cb11Compat.Checked;
104 |
105 | var diff = new LayoutDiff(Original, Edited, new LayoutDiff.DiffOptions {
106 | HideOnlineButton = HideOnlineButton,
107 | IgnoreMissingPanes = cbIgnoreMissingPanes.Checked,
108 | // Also ignore these since we can't shouldn't import animations if panes are missing
109 | IgnoreAnimations = cbIgnoreMissingPanes.Checked,
110 | IgnoreGroups = cbIgnoreMissingPanes.Checked,
111 | IgnoreMaterials = cbIgnoreMissingPanes.Checked,
112 | });
113 |
114 | var res = diff.ComputeDiff();
115 | var log = diff.OutputLog;
116 |
117 | if (!string.IsNullOrWhiteSpace(log))
118 | MessageBox.Show(log);
119 |
120 | if (res != null)
121 | {
122 | SaveFileDialog sav = new SaveFileDialog() { Filter = "json file|*.json" };
123 | if (sav.ShowDialog() != DialogResult.OK) return;
124 | File.WriteAllText(sav.FileName, res.AsJson());
125 | }
126 | }
127 | catch (Exception ex)
128 | {
129 | MessageBox.Show(ex.Message);
130 | }
131 | }
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/BflytPreview/EditorForms/SzsEditor.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace BflytPreview.EditorForms
2 | {
3 | partial class SzsEditor
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.components = new System.ComponentModel.Container();
32 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SzsEditor));
33 | this.listBox1 = new System.Windows.Forms.ListBox();
34 | this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
35 | this.copyNameToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
36 | this.renameToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
37 | this.extractToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
38 | this.replaceToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
39 | this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
40 | this.deleteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
41 | this.numericUpDown1 = new System.Windows.Forms.NumericUpDown();
42 | this.label1 = new System.Windows.Forms.Label();
43 | this.saveSzsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
44 | this.saveAsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
45 | this.saveToSzsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
46 | this.addFilesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
47 | this.extractAllFilesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
48 | this.menuStrip1 = new System.Windows.Forms.MenuStrip();
49 | this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
50 | this.layoutDiffToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
51 | this.thisFileIsTheOriginalSzsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
52 | this.thisFileIsTheEditedSzsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
53 | this.loadJSONPatchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
54 | this.extractNamesInClipboardToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
55 | this.tb_search = new System.Windows.Forms.TextBox();
56 | this.exportFileListToClipboardToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
57 | this.contextMenuStrip1.SuspendLayout();
58 | ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
59 | this.menuStrip1.SuspendLayout();
60 | this.SuspendLayout();
61 | //
62 | // listBox1
63 | //
64 | this.listBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
65 | | System.Windows.Forms.AnchorStyles.Left)
66 | | System.Windows.Forms.AnchorStyles.Right)));
67 | this.listBox1.ContextMenuStrip = this.contextMenuStrip1;
68 | this.listBox1.FormattingEnabled = true;
69 | this.listBox1.Location = new System.Drawing.Point(0, 27);
70 | this.listBox1.Name = "listBox1";
71 | this.listBox1.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended;
72 | this.listBox1.Size = new System.Drawing.Size(303, 212);
73 | this.listBox1.Sorted = true;
74 | this.listBox1.TabIndex = 4;
75 | this.listBox1.DoubleClick += new System.EventHandler(this.listBox1_DoubleClick);
76 | this.listBox1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.listBox1_KeyDown);
77 | //
78 | // contextMenuStrip1
79 | //
80 | this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
81 | this.copyNameToolStripMenuItem,
82 | this.renameToolStripMenuItem,
83 | this.extractToolStripMenuItem,
84 | this.replaceToolStripMenuItem1,
85 | this.toolStripSeparator1,
86 | this.deleteToolStripMenuItem});
87 | this.contextMenuStrip1.Name = "contextMenuStrip1";
88 | this.contextMenuStrip1.Size = new System.Drawing.Size(136, 120);
89 | //
90 | // copyNameToolStripMenuItem
91 | //
92 | this.copyNameToolStripMenuItem.Name = "copyNameToolStripMenuItem";
93 | this.copyNameToolStripMenuItem.Size = new System.Drawing.Size(135, 22);
94 | this.copyNameToolStripMenuItem.Text = "Copy name";
95 | this.copyNameToolStripMenuItem.Click += new System.EventHandler(this.copyNameToolStripMenuItem_Click);
96 | //
97 | // renameToolStripMenuItem
98 | //
99 | this.renameToolStripMenuItem.Name = "renameToolStripMenuItem";
100 | this.renameToolStripMenuItem.Size = new System.Drawing.Size(135, 22);
101 | this.renameToolStripMenuItem.Text = "Rename";
102 | this.renameToolStripMenuItem.Click += new System.EventHandler(this.renameToolStripMenuItem_Click);
103 | //
104 | // extractToolStripMenuItem
105 | //
106 | this.extractToolStripMenuItem.Name = "extractToolStripMenuItem";
107 | this.extractToolStripMenuItem.Size = new System.Drawing.Size(135, 22);
108 | this.extractToolStripMenuItem.Text = "Extract";
109 | this.extractToolStripMenuItem.Click += new System.EventHandler(this.extractToolStripMenuItem_Click);
110 | //
111 | // replaceToolStripMenuItem1
112 | //
113 | this.replaceToolStripMenuItem1.Name = "replaceToolStripMenuItem1";
114 | this.replaceToolStripMenuItem1.Size = new System.Drawing.Size(135, 22);
115 | this.replaceToolStripMenuItem1.Text = "Replace";
116 | this.replaceToolStripMenuItem1.Click += new System.EventHandler(this.replaceToolStripMenuItem1_Click);
117 | //
118 | // toolStripSeparator1
119 | //
120 | this.toolStripSeparator1.Name = "toolStripSeparator1";
121 | this.toolStripSeparator1.Size = new System.Drawing.Size(132, 6);
122 | //
123 | // deleteToolStripMenuItem
124 | //
125 | this.deleteToolStripMenuItem.Name = "deleteToolStripMenuItem";
126 | this.deleteToolStripMenuItem.Size = new System.Drawing.Size(135, 22);
127 | this.deleteToolStripMenuItem.Text = "Delete";
128 | this.deleteToolStripMenuItem.Click += new System.EventHandler(this.deleteToolStripMenuItem_Click);
129 | //
130 | // numericUpDown1
131 | //
132 | this.numericUpDown1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
133 | this.numericUpDown1.Location = new System.Drawing.Point(130, 253);
134 | this.numericUpDown1.Maximum = new decimal(new int[] {
135 | 9,
136 | 0,
137 | 0,
138 | 0});
139 | this.numericUpDown1.Name = "numericUpDown1";
140 | this.numericUpDown1.Size = new System.Drawing.Size(55, 20);
141 | this.numericUpDown1.TabIndex = 7;
142 | this.numericUpDown1.Value = new decimal(new int[] {
143 | 3,
144 | 0,
145 | 0,
146 | 0});
147 | //
148 | // label1
149 | //
150 | this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
151 | this.label1.AutoSize = true;
152 | this.label1.Location = new System.Drawing.Point(8, 256);
153 | this.label1.Name = "label1";
154 | this.label1.Size = new System.Drawing.Size(122, 13);
155 | this.label1.TabIndex = 6;
156 | this.label1.Text = "Compression level [0-9] :";
157 | //
158 | // saveSzsToolStripMenuItem
159 | //
160 | this.saveSzsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
161 | this.saveAsToolStripMenuItem,
162 | this.saveToSzsToolStripMenuItem});
163 | this.saveSzsToolStripMenuItem.Name = "saveSzsToolStripMenuItem";
164 | this.saveSzsToolStripMenuItem.Size = new System.Drawing.Size(43, 20);
165 | this.saveSzsToolStripMenuItem.Text = "Save";
166 | //
167 | // saveAsToolStripMenuItem
168 | //
169 | this.saveAsToolStripMenuItem.Name = "saveAsToolStripMenuItem";
170 | this.saveAsToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift)
171 | | System.Windows.Forms.Keys.S)));
172 | this.saveAsToolStripMenuItem.Size = new System.Drawing.Size(190, 22);
173 | this.saveAsToolStripMenuItem.Text = "Save as..";
174 | this.saveAsToolStripMenuItem.Click += new System.EventHandler(this.saveAsToolStripMenuItem_Click);
175 | //
176 | // saveToSzsToolStripMenuItem
177 | //
178 | this.saveToSzsToolStripMenuItem.Name = "saveToSzsToolStripMenuItem";
179 | this.saveToSzsToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S)));
180 | this.saveToSzsToolStripMenuItem.Size = new System.Drawing.Size(190, 22);
181 | this.saveToSzsToolStripMenuItem.Text = "Save";
182 | this.saveToSzsToolStripMenuItem.Visible = false;
183 | this.saveToSzsToolStripMenuItem.Click += new System.EventHandler(this.saveToSzsToolStripMenuItem_Click);
184 | //
185 | // addFilesToolStripMenuItem
186 | //
187 | this.addFilesToolStripMenuItem.Name = "addFilesToolStripMenuItem";
188 | this.addFilesToolStripMenuItem.Size = new System.Drawing.Size(65, 20);
189 | this.addFilesToolStripMenuItem.Text = "Add files";
190 | this.addFilesToolStripMenuItem.Click += new System.EventHandler(this.addFilesToolStripMenuItem_Click);
191 | //
192 | // extractAllFilesToolStripMenuItem
193 | //
194 | this.extractAllFilesToolStripMenuItem.Name = "extractAllFilesToolStripMenuItem";
195 | this.extractAllFilesToolStripMenuItem.Size = new System.Drawing.Size(94, 20);
196 | this.extractAllFilesToolStripMenuItem.Text = "Extract all files";
197 | this.extractAllFilesToolStripMenuItem.Click += new System.EventHandler(this.extractAllFilesToolStripMenuItem_Click);
198 | //
199 | // menuStrip1
200 | //
201 | this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
202 | this.saveSzsToolStripMenuItem,
203 | this.addFilesToolStripMenuItem,
204 | this.extractAllFilesToolStripMenuItem,
205 | this.toolsToolStripMenuItem});
206 | this.menuStrip1.Location = new System.Drawing.Point(0, 0);
207 | this.menuStrip1.Name = "menuStrip1";
208 | this.menuStrip1.Size = new System.Drawing.Size(303, 24);
209 | this.menuStrip1.TabIndex = 5;
210 | this.menuStrip1.Text = "menuStrip1";
211 | //
212 | // toolsToolStripMenuItem
213 | //
214 | this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
215 | this.layoutDiffToolStripMenuItem,
216 | this.loadJSONPatchToolStripMenuItem,
217 | this.extractNamesInClipboardToolStripMenuItem,
218 | this.exportFileListToClipboardToolStripMenuItem});
219 | this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem";
220 | this.toolsToolStripMenuItem.Size = new System.Drawing.Size(46, 20);
221 | this.toolsToolStripMenuItem.Text = "Tools";
222 | //
223 | // layoutDiffToolStripMenuItem
224 | //
225 | this.layoutDiffToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
226 | this.thisFileIsTheOriginalSzsToolStripMenuItem,
227 | this.thisFileIsTheEditedSzsToolStripMenuItem});
228 | this.layoutDiffToolStripMenuItem.Name = "layoutDiffToolStripMenuItem";
229 | this.layoutDiffToolStripMenuItem.Size = new System.Drawing.Size(269, 22);
230 | this.layoutDiffToolStripMenuItem.Text = "Layout diff";
231 | //
232 | // thisFileIsTheOriginalSzsToolStripMenuItem
233 | //
234 | this.thisFileIsTheOriginalSzsToolStripMenuItem.Name = "thisFileIsTheOriginalSzsToolStripMenuItem";
235 | this.thisFileIsTheOriginalSzsToolStripMenuItem.Size = new System.Drawing.Size(206, 22);
236 | this.thisFileIsTheOriginalSzsToolStripMenuItem.Text = "This file is the original szs";
237 | this.thisFileIsTheOriginalSzsToolStripMenuItem.Click += new System.EventHandler(this.thisFileIsTheOriginalSzsToolStripMenuItem_Click);
238 | //
239 | // thisFileIsTheEditedSzsToolStripMenuItem
240 | //
241 | this.thisFileIsTheEditedSzsToolStripMenuItem.Name = "thisFileIsTheEditedSzsToolStripMenuItem";
242 | this.thisFileIsTheEditedSzsToolStripMenuItem.Size = new System.Drawing.Size(206, 22);
243 | this.thisFileIsTheEditedSzsToolStripMenuItem.Text = "This file is the edited szs";
244 | this.thisFileIsTheEditedSzsToolStripMenuItem.Click += new System.EventHandler(this.thisFileIsTheEditedSzsToolStripMenuItem_Click);
245 | //
246 | // loadJSONPatchToolStripMenuItem
247 | //
248 | this.loadJSONPatchToolStripMenuItem.Name = "loadJSONPatchToolStripMenuItem";
249 | this.loadJSONPatchToolStripMenuItem.Size = new System.Drawing.Size(269, 22);
250 | this.loadJSONPatchToolStripMenuItem.Text = "Load JSON patch";
251 | this.loadJSONPatchToolStripMenuItem.Click += new System.EventHandler(this.loadJSONPatchToolStripMenuItem_Click);
252 | //
253 | // extractNamesInClipboardToolStripMenuItem
254 | //
255 | this.extractNamesInClipboardToolStripMenuItem.Name = "extractNamesInClipboardToolStripMenuItem";
256 | this.extractNamesInClipboardToolStripMenuItem.Size = new System.Drawing.Size(269, 22);
257 | this.extractNamesInClipboardToolStripMenuItem.Text = "Extract file names from the clipboard";
258 | this.extractNamesInClipboardToolStripMenuItem.Click += new System.EventHandler(this.extractNamesInClipboardToolStripMenuItem_Click);
259 | //
260 | // tb_search
261 | //
262 | this.tb_search.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
263 | | System.Windows.Forms.AnchorStyles.Right)));
264 | this.tb_search.Location = new System.Drawing.Point(195, 253);
265 | this.tb_search.Name = "tb_search";
266 | this.tb_search.Size = new System.Drawing.Size(100, 20);
267 | this.tb_search.TabIndex = 8;
268 | this.tb_search.Text = "Search";
269 | this.tb_search.TextChanged += new System.EventHandler(this.tb_search_TextChanged);
270 | //
271 | // exportFileListToClipboardToolStripMenuItem
272 | //
273 | this.exportFileListToClipboardToolStripMenuItem.Name = "exportFileListToClipboardToolStripMenuItem";
274 | this.exportFileListToClipboardToolStripMenuItem.Size = new System.Drawing.Size(269, 22);
275 | this.exportFileListToClipboardToolStripMenuItem.Text = "Write file list to clipboard";
276 | this.exportFileListToClipboardToolStripMenuItem.Click += new System.EventHandler(this.exportFileListToClipboardToolStripMenuItem_Click);
277 | //
278 | // SzsEditor
279 | //
280 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
281 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
282 | this.ClientSize = new System.Drawing.Size(303, 279);
283 | this.Controls.Add(this.tb_search);
284 | this.Controls.Add(this.listBox1);
285 | this.Controls.Add(this.menuStrip1);
286 | this.Controls.Add(this.numericUpDown1);
287 | this.Controls.Add(this.label1);
288 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
289 | this.KeyPreview = true;
290 | this.Name = "SzsEditor";
291 | this.Text = "Szs editor";
292 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.SzsEditor_FormClosing);
293 | this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.SzsEditor_FormClosed);
294 | this.Load += new System.EventHandler(this.SzsEditor_Load);
295 | this.LocationChanged += new System.EventHandler(this.SzsEditor_LocationChanged);
296 | this.Click += new System.EventHandler(this.SzsEditor_Click);
297 | this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.SzsEditor_KeyDown);
298 | this.contextMenuStrip1.ResumeLayout(false);
299 | ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit();
300 | this.menuStrip1.ResumeLayout(false);
301 | this.menuStrip1.PerformLayout();
302 | this.ResumeLayout(false);
303 | this.PerformLayout();
304 |
305 | }
306 |
307 | #endregion
308 |
309 | private System.Windows.Forms.ListBox listBox1;
310 | private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
311 | private System.Windows.Forms.ToolStripMenuItem copyNameToolStripMenuItem;
312 | private System.Windows.Forms.ToolStripMenuItem renameToolStripMenuItem;
313 | private System.Windows.Forms.ToolStripMenuItem extractToolStripMenuItem;
314 | private System.Windows.Forms.ToolStripMenuItem replaceToolStripMenuItem1;
315 | private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
316 | private System.Windows.Forms.ToolStripMenuItem deleteToolStripMenuItem;
317 | private System.Windows.Forms.NumericUpDown numericUpDown1;
318 | private System.Windows.Forms.Label label1;
319 | private System.Windows.Forms.ToolStripMenuItem saveSzsToolStripMenuItem;
320 | private System.Windows.Forms.ToolStripMenuItem saveAsToolStripMenuItem;
321 | private System.Windows.Forms.ToolStripMenuItem saveToSzsToolStripMenuItem;
322 | private System.Windows.Forms.ToolStripMenuItem addFilesToolStripMenuItem;
323 | private System.Windows.Forms.ToolStripMenuItem extractAllFilesToolStripMenuItem;
324 | private System.Windows.Forms.MenuStrip menuStrip1;
325 | private System.Windows.Forms.ToolStripMenuItem toolsToolStripMenuItem;
326 | private System.Windows.Forms.ToolStripMenuItem layoutDiffToolStripMenuItem;
327 | private System.Windows.Forms.ToolStripMenuItem thisFileIsTheOriginalSzsToolStripMenuItem;
328 | private System.Windows.Forms.ToolStripMenuItem thisFileIsTheEditedSzsToolStripMenuItem;
329 | private System.Windows.Forms.ToolStripMenuItem loadJSONPatchToolStripMenuItem;
330 | private System.Windows.Forms.TextBox tb_search;
331 | private System.Windows.Forms.ToolStripMenuItem extractNamesInClipboardToolStripMenuItem;
332 | private System.Windows.Forms.ToolStripMenuItem exportFileListToClipboardToolStripMenuItem;
333 | }
334 | }
--------------------------------------------------------------------------------
/BflytPreview/EditorForms/SzsEditor.cs:
--------------------------------------------------------------------------------
1 | using SARCExt;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.ComponentModel;
5 | using System.Data;
6 | using System.Drawing;
7 | using System.IO;
8 | using System.Linq;
9 | using System.Text;
10 | using System.Threading.Tasks;
11 | using System.Windows.Forms;
12 | using SwitchThemes.Common;
13 | using SwitchThemes.Common.Serializers;
14 | using SwitchThemes.Common.Bntxx;
15 | using Syroot.BinaryData;
16 | using SwitchThemes.Common.Bflyt;
17 |
18 | namespace BflytPreview.EditorForms
19 | {
20 | public partial class SzsEditor : Form
21 | {
22 | public class SzsFileProvider : IFileWriter
23 | {
24 | private SzsEditor Parent;
25 | internal Form EditorForm;
26 | public string Path { get; internal set; }
27 |
28 | public SzsFileProvider(SzsEditor parent, string path) =>
29 | (Parent, Path) = (parent, path);
30 |
31 | public void EditorClosed() =>
32 | Parent.CloseFileProvider(this);
33 |
34 | public void Save(byte[] Data) =>
35 | Parent.SaveFromProvider(this, Data);
36 |
37 | public override string ToString() => $"Szs file : {Path}";
38 | }
39 |
40 | internal List FileProviders = new List();
41 |
42 | internal void CloseFileProvider(SzsFileProvider file) =>
43 | FileProviders.Remove(file);
44 |
45 | internal void SaveFromProvider(SzsFileProvider file, byte[] Data)
46 | {
47 | if (!FileProviders.Contains(file)) throw new Exception("file is not a registered IFileWriter");
48 | loadedSarc.Files[file.Path] = Data;
49 | }
50 |
51 | IFileWriter _saveTo;
52 | public IFileWriter SaveTo
53 | {
54 | get => _saveTo;
55 | set
56 | {
57 | _saveTo?.EditorClosed();
58 | _saveTo = value;
59 | saveToSzsToolStripMenuItem.Visible = _saveTo != null;
60 | this.Text = value?.ToString() ?? "";
61 | }
62 | }
63 |
64 | SarcData loadedSarc;
65 | MainForm MainForm;
66 |
67 | public SzsEditor(SARCExt.SarcData _sarc, IFileWriter saveTo, MainForm _parentForm)
68 | {
69 | InitializeComponent();
70 | loadedSarc = _sarc;
71 | MainForm = _parentForm;
72 | SaveTo = saveTo;
73 | }
74 |
75 | private void SzsEditor_Load(object sender, EventArgs e)
76 | {
77 | #if !DEBUG
78 | extractNamesInClipboardToolStripMenuItem.Visible = false;
79 | exportFileListToClipboardToolStripMenuItem.Visible = false;
80 | #endif
81 |
82 | if (loadedSarc == null)
83 | {
84 | MessageBox.Show("No sarc has been loaded");
85 | this.Close();
86 | }
87 | else
88 | {
89 | listBox1.Items.AddRange(loadedSarc.Files.Keys.ToArray());
90 | FormBringToFront();
91 | }
92 | }
93 |
94 | private void SzsEditor_FormClosing(object sender, FormClosingEventArgs e)
95 | {
96 | if (FileProviders.Count != 0)
97 | {
98 | if (MessageBox.Show("There are some files of this SZS opened, this will close all of them and all the unsaved edits will be lost, do you want to continue ?", this.Text, MessageBoxButtons.YesNo) == DialogResult.No)
99 | e.Cancel = true;
100 | else
101 | {
102 | foreach (var k in FileProviders.ToArray())
103 | k.EditorForm?.Close();
104 | if (FileProviders.Count != 0)
105 | {
106 | MessageBox.Show($"Failed to close {FileProviders.Count} editors");
107 | e.Cancel = true;
108 | }
109 | }
110 | }
111 | }
112 |
113 | private void extractAllFilesToolStripMenuItem_Click(object sender, EventArgs e)
114 | {
115 | ExtractMultipleFiles(loadedSarc.Files.Keys.ToArray());
116 | }
117 |
118 | void ExtractMultipleFiles(IEnumerable files)
119 | {
120 | var dlg = new FolderBrowserDialog();
121 | if (dlg.ShowDialog() != DialogResult.OK)
122 | return;
123 | foreach (string f in files)
124 | {
125 | string fOut = Path.Combine(dlg.SelectedPath, f);
126 | DirectoryInfo dir = new DirectoryInfo(Path.GetDirectoryName(fOut));
127 | if (!dir.Exists)
128 | dir.Create();
129 | File.WriteAllBytes(fOut, loadedSarc.Files[f]);
130 | }
131 | }
132 |
133 | private void extractToolStripMenuItem_Click(object sender, EventArgs e)
134 | {
135 | if (listBox1.SelectedItems.Count > 1)
136 | ExtractMultipleFiles(listBox1.SelectedItems.Cast());
137 | else
138 | {
139 | var sav = new SaveFileDialog() { FileName = listBox1.SelectedItem.ToString() };
140 | if (sav.ShowDialog() != DialogResult.OK)
141 | return;
142 | File.WriteAllBytes(sav.FileName, loadedSarc.Files[listBox1.SelectedItem.ToString()]);
143 | }
144 | }
145 |
146 | private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
147 | {
148 | if (loadedSarc.HashOnly)
149 | {
150 | MessageBox.Show("Can't remove files from a hash only sarc");
151 | return;
152 | }
153 | string[] Targets = listBox1.SelectedItems.Cast().ToArray();
154 | foreach (var item in Targets)
155 | {
156 | loadedSarc.Files.Remove(item);
157 | listBox1.Items.Remove(item);
158 | }
159 | }
160 |
161 | private void addFilesToolStripMenuItem_Click(object sender, EventArgs e)
162 | {
163 | if (loadedSarc.HashOnly)
164 | {
165 | MessageBox.Show("Can't add files to a hash only sarc");
166 | return;
167 | }
168 | var opn = new OpenFileDialog() { Multiselect = true };
169 | if (opn.ShowDialog() != DialogResult.OK)
170 | return;
171 | foreach (var f in opn.FileNames)
172 | {
173 | string name = Path.GetFileName(f);
174 | if (InputDialog.Show("File name", "Write the name for this file, use / to place it in a folder", ref name) != DialogResult.OK)
175 | return;
176 |
177 | if (loadedSarc.Files.ContainsKey(name))
178 | {
179 | MessageBox.Show($"File {name} already in szs");
180 | continue;
181 | }
182 | loadedSarc.Files.Add(name, File.ReadAllBytes(f));
183 | listBox1.Items.Add(name);
184 | }
185 | }
186 |
187 | byte[] PackArchive()
188 | {
189 | if (numericUpDown1.Value == 0)
190 | return SARC.Pack(loadedSarc).Item2;
191 | else
192 | {
193 | var s = SARC.Pack(loadedSarc);
194 | return ManagedYaz0.Compress(s.Item2, (int)numericUpDown1.Value, s.Item1);
195 | }
196 | }
197 |
198 | void SaveSzsAs()
199 | {
200 | var sav = new SaveFileDialog() { Filter = "szs file|*.szs|sarc file|*.sarc" };
201 | if (sav.ShowDialog() != DialogResult.OK)
202 | return;
203 | SaveTo = new DiskFileProvider(sav.FileName);
204 | SaveTo.Save(PackArchive());
205 | }
206 |
207 | private void saveAsToolStripMenuItem_Click(object sender, EventArgs e) =>
208 | SaveSzsAs();
209 |
210 | private void listBox1_DoubleClick(object sender, EventArgs e)
211 | {
212 | if (listBox1.SelectedItem == null)
213 | return;
214 | var Fname = listBox1.SelectedItem.ToString();
215 |
216 | var alreadyOpened = FileProviders.Where(x => x.Path == Fname);
217 | if (alreadyOpened.FirstOrDefault() != null)
218 | {
219 | alreadyOpened.FirstOrDefault().EditorForm.Focus();
220 | return;
221 | }
222 |
223 | var provider = new SzsFileProvider(this, Fname);
224 | var form = MainForm.OpenFile(loadedSarc.Files[Fname], provider);
225 | if (form != null)
226 | {
227 | provider.EditorForm = form;
228 | FileProviders.Add(provider);
229 | }
230 | }
231 |
232 | private void replaceToolStripMenuItem1_Click(object sender, EventArgs e)
233 | {
234 | if (listBox1.SelectedItem == null) return;
235 | var opn = new OpenFileDialog();
236 | if (opn.ShowDialog() != DialogResult.OK) return;
237 | loadedSarc.Files[listBox1.SelectedItem.ToString()] = File.ReadAllBytes(opn.FileName);
238 | }
239 |
240 | private void copyNameToolStripMenuItem_Click(object sender, EventArgs e)
241 | {
242 | if (listBox1.SelectedItem == null) return;
243 | Clipboard.SetText(listBox1.SelectedItem.ToString());
244 | }
245 |
246 | private void renameToolStripMenuItem_Click(object sender, EventArgs e)
247 | {
248 | if (listBox1.SelectedItem == null) return;
249 | string originalName = listBox1.SelectedItem.ToString();
250 | string name = Path.GetFileName(originalName);
251 | if (InputDialog.Show("File name", "Write the name for this file, use / to place it in a folder", ref name) != DialogResult.OK)
252 | return;
253 |
254 | if (loadedSarc.Files.ContainsKey(name))
255 | {
256 | MessageBox.Show($"File {name} already in szs");
257 | return;
258 | }
259 | loadedSarc.Files.Add(name, loadedSarc.Files[originalName]);
260 | loadedSarc.Files.Remove(originalName);
261 | listBox1.Items.Add(name);
262 | listBox1.Items.Remove(originalName);
263 | }
264 |
265 | private void saveToSzsToolStripMenuItem_Click(object sender, EventArgs e)
266 | {
267 | if (SaveTo == null)
268 | SaveSzsAs();
269 | else SaveTo.Save(PackArchive());
270 | }
271 |
272 | void FormBringToFront()
273 | {
274 | this.Activate();
275 | this.BringToFront();
276 | this.Focus();
277 | }
278 |
279 | private void SzsEditor_Click(object sender, EventArgs e) => FormBringToFront();
280 | private void SzsEditor_LocationChanged(object sender, EventArgs e) => FormBringToFront();
281 |
282 | private void SzsEditor_FormClosed(object sender, FormClosedEventArgs e) =>
283 | SaveTo?.EditorClosed();
284 |
285 | private void thisFileIsTheOriginalSzsToolStripMenuItem_Click(object sender, EventArgs e)
286 | => new LayoutDiffForm(loadedSarc, null).ShowDialog();
287 |
288 | private void thisFileIsTheEditedSzsToolStripMenuItem_Click(object sender, EventArgs e)
289 | => new LayoutDiffForm(null, loadedSarc).ShowDialog();
290 |
291 | private void SzsEditor_KeyDown(object sender, KeyEventArgs e)
292 | {
293 | e.SuppressKeyPress = true;
294 | if (e.Shift && e.Control && e.KeyCode == Keys.S)
295 | saveAsToolStripMenuItem.PerformClick();
296 | else if (e.Control && e.KeyCode == Keys.S)
297 | saveToSzsToolStripMenuItem.PerformClick();
298 | else e.SuppressKeyPress = false;
299 | }
300 |
301 | private void loadJSONPatchToolStripMenuItem_Click(object sender, EventArgs e)
302 | {
303 | var opn = new OpenFileDialog();
304 | if (opn.ShowDialog() != DialogResult.OK) return;
305 |
306 | SzsPatcher P = new SzsPatcher(loadedSarc);
307 | LayoutPatch JSONLayout = LayoutPatch.Load(File.ReadAllText(opn.FileName));
308 |
309 | if (JSONLayout.IsCompatible(loadedSarc))
310 | {
311 | if (P.PatchLayouts(JSONLayout))
312 | {
313 | loadedSarc = P.GetFinalSarc();
314 | MessageBox.Show("Loaded JSON patch");
315 | }
316 | else MessageBox.Show("Failed to load the JSON patch.");
317 | }
318 |
319 | }
320 |
321 | private void listBox1_KeyDown(object sender, KeyEventArgs e)
322 | {
323 | if (listBox1.SelectedItem == null) return;
324 | if (e.KeyCode == Keys.Q)
325 | HexEditorForm.Show(loadedSarc.Files[listBox1.SelectedItem as string]);
326 | else if (e.KeyCode == Keys.Return)
327 | listBox1_DoubleClick(sender, null);
328 | }
329 |
330 | private void tb_search_TextChanged(object sender, EventArgs e)
331 | {
332 | listBox1.Items.Clear();
333 | if (tb_search.Text.Trim() == "")
334 | listBox1.Items.AddRange(loadedSarc.Files.Keys.ToArray());
335 | else
336 | foreach (var k in loadedSarc.Files.Keys)
337 | if (k.IndexOf(tb_search.Text, StringComparison.InvariantCultureIgnoreCase) != -1)
338 | listBox1.Items.Add(k);
339 | }
340 |
341 | private void extractNamesInClipboardToolStripMenuItem_Click(object sender, EventArgs e)
342 | {
343 | var names = Clipboard.GetText()
344 | .Split('\n')
345 | .Select(x => x.Trim())
346 | .Where(x => x != "")
347 | .ToArray();
348 |
349 | ExtractMultipleFiles(names);
350 | }
351 |
352 | private void exportFileListToClipboardToolStripMenuItem_Click(object sender, EventArgs e)
353 | {
354 | var names = loadedSarc.Files.Keys
355 | .Select(x => x.Trim())
356 | .Where(x => x != "")
357 | .ToArray();
358 | Clipboard.SetText(string.Join("\n", names));
359 | }
360 |
361 | //private void openAllBflanToolStripMenuItem_Click(object sender, EventArgs e)
362 | //{
363 | // foreach (var k in loadedSarc.Files.Keys)
364 | // if (k.EndsWith("bflan"))
365 | // MainForm.OpenFile(loadedSarc.Files[k], k);
366 | //}
367 | }
368 | }
369 |
--------------------------------------------------------------------------------
/BflytPreview/MainForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace BflytPreview
2 | {
3 | partial class MainForm
4 | {
5 | ///
6 | /// Variabile di progettazione necessaria.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Pulire le risorse in uso.
12 | ///
13 | /// ha valore true se le risorse gestite devono essere eliminate, false in caso contrario.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Codice generato da Progettazione Windows Form
24 |
25 | ///
26 | /// Metodo necessario per il supporto della finestra di progettazione. Non modificare
27 | /// il contenuto del metodo con l'editor di codice.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
32 | this.menuStrip1 = new System.Windows.Forms.MenuStrip();
33 | this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
34 | this.openBFLYTToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
35 | this.importJSONToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
36 | this.bFLANToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
37 | this.createSzsFromFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
38 | this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
39 | this.layoutDiffToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
40 | this.checkUpdateToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
41 | this.splitContainer1 = new System.Windows.Forms.SplitContainer();
42 | this.splitContainer2 = new System.Windows.Forms.SplitContainer();
43 | this.treeView1 = new System.Windows.Forms.TreeView();
44 | this.zoomSlider = new System.Windows.Forms.TrackBar();
45 | this.propertyGrid1 = new System.Windows.Forms.PropertyGrid();
46 | this.panel1 = new System.Windows.Forms.Panel();
47 | this.pictureBox1 = new System.Windows.Forms.PictureBox();
48 | this.pnlSubSystem = new System.Windows.Forms.Panel();
49 | this.menuStrip1.SuspendLayout();
50 | ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
51 | this.splitContainer1.Panel1.SuspendLayout();
52 | this.splitContainer1.Panel2.SuspendLayout();
53 | this.splitContainer1.SuspendLayout();
54 | ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).BeginInit();
55 | this.splitContainer2.Panel1.SuspendLayout();
56 | this.splitContainer2.Panel2.SuspendLayout();
57 | this.splitContainer2.SuspendLayout();
58 | ((System.ComponentModel.ISupportInitialize)(this.zoomSlider)).BeginInit();
59 | this.panel1.SuspendLayout();
60 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
61 | this.SuspendLayout();
62 | //
63 | // menuStrip1
64 | //
65 | this.menuStrip1.ImageScalingSize = new System.Drawing.Size(20, 20);
66 | this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
67 | this.fileToolStripMenuItem,
68 | this.toolsToolStripMenuItem,
69 | this.checkUpdateToolStripMenuItem});
70 | this.menuStrip1.Location = new System.Drawing.Point(0, 0);
71 | this.menuStrip1.Name = "menuStrip1";
72 | this.menuStrip1.Padding = new System.Windows.Forms.Padding(4, 2, 0, 2);
73 | this.menuStrip1.Size = new System.Drawing.Size(672, 24);
74 | this.menuStrip1.TabIndex = 1;
75 | this.menuStrip1.Text = "menuStrip1";
76 | //
77 | // fileToolStripMenuItem
78 | //
79 | this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
80 | this.openBFLYTToolStripMenuItem,
81 | this.importJSONToolStripMenuItem,
82 | this.createSzsFromFolderToolStripMenuItem});
83 | this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
84 | this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
85 | this.fileToolStripMenuItem.Text = "File";
86 | //
87 | // openBFLYTToolStripMenuItem
88 | //
89 | this.openBFLYTToolStripMenuItem.Name = "openBFLYTToolStripMenuItem";
90 | this.openBFLYTToolStripMenuItem.Size = new System.Drawing.Size(190, 22);
91 | this.openBFLYTToolStripMenuItem.Text = "Open file";
92 | this.openBFLYTToolStripMenuItem.Click += new System.EventHandler(this.openBFLYTToolStripMenuItem_Click);
93 | //
94 | // importJSONToolStripMenuItem
95 | //
96 | this.importJSONToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
97 | this.bFLANToolStripMenuItem});
98 | this.importJSONToolStripMenuItem.Name = "importJSONToolStripMenuItem";
99 | this.importJSONToolStripMenuItem.Size = new System.Drawing.Size(190, 22);
100 | this.importJSONToolStripMenuItem.Text = "Import JSON";
101 | //
102 | // bFLANToolStripMenuItem
103 | //
104 | this.bFLANToolStripMenuItem.Name = "bFLANToolStripMenuItem";
105 | this.bFLANToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
106 | this.bFLANToolStripMenuItem.Text = "BFLAN Animation";
107 | this.bFLANToolStripMenuItem.Click += new System.EventHandler(this.BFLANToolStripMenuItem_Click);
108 | //
109 | // createSzsFromFolderToolStripMenuItem
110 | //
111 | this.createSzsFromFolderToolStripMenuItem.Name = "createSzsFromFolderToolStripMenuItem";
112 | this.createSzsFromFolderToolStripMenuItem.Size = new System.Drawing.Size(190, 22);
113 | this.createSzsFromFolderToolStripMenuItem.Text = "Create Szs from folder";
114 | this.createSzsFromFolderToolStripMenuItem.Click += new System.EventHandler(this.createSzsFromFolderToolStripMenuItem_Click);
115 | //
116 | // toolsToolStripMenuItem
117 | //
118 | this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
119 | this.layoutDiffToolStripMenuItem});
120 | this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem";
121 | this.toolsToolStripMenuItem.Size = new System.Drawing.Size(46, 20);
122 | this.toolsToolStripMenuItem.Text = "Tools";
123 | //
124 | // layoutDiffToolStripMenuItem
125 | //
126 | this.layoutDiffToolStripMenuItem.Name = "layoutDiffToolStripMenuItem";
127 | this.layoutDiffToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
128 | this.layoutDiffToolStripMenuItem.Text = "Layout diff";
129 | this.layoutDiffToolStripMenuItem.Click += new System.EventHandler(this.layoutDiffToolStripMenuItem_Click);
130 | //
131 | // checkUpdateToolStripMenuItem
132 | //
133 | this.checkUpdateToolStripMenuItem.Name = "checkUpdateToolStripMenuItem";
134 | this.checkUpdateToolStripMenuItem.Size = new System.Drawing.Size(115, 20);
135 | this.checkUpdateToolStripMenuItem.Text = "Check for updates";
136 | this.checkUpdateToolStripMenuItem.Click += new System.EventHandler(this.checkUpdateToolStripMenuItem_Click);
137 | //
138 | // splitContainer1
139 | //
140 | this.splitContainer1.BackColor = System.Drawing.SystemColors.ControlDarkDark;
141 | this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
142 | this.splitContainer1.Location = new System.Drawing.Point(0, 24);
143 | this.splitContainer1.Name = "splitContainer1";
144 | //
145 | // splitContainer1.Panel1
146 | //
147 | this.splitContainer1.Panel1.Controls.Add(this.splitContainer2);
148 | //
149 | // splitContainer1.Panel2
150 | //
151 | this.splitContainer1.Panel2.Controls.Add(this.panel1);
152 | this.splitContainer1.Size = new System.Drawing.Size(672, 424);
153 | this.splitContainer1.SplitterDistance = 223;
154 | this.splitContainer1.TabIndex = 4;
155 | //
156 | // splitContainer2
157 | //
158 | this.splitContainer2.Dock = System.Windows.Forms.DockStyle.Fill;
159 | this.splitContainer2.Location = new System.Drawing.Point(0, 0);
160 | this.splitContainer2.Name = "splitContainer2";
161 | this.splitContainer2.Orientation = System.Windows.Forms.Orientation.Horizontal;
162 | //
163 | // splitContainer2.Panel1
164 | //
165 | this.splitContainer2.Panel1.Controls.Add(this.treeView1);
166 | //
167 | // splitContainer2.Panel2
168 | //
169 | this.splitContainer2.Panel2.BackColor = System.Drawing.SystemColors.Control;
170 | this.splitContainer2.Panel2.Controls.Add(this.zoomSlider);
171 | this.splitContainer2.Panel2.Controls.Add(this.propertyGrid1);
172 | this.splitContainer2.Size = new System.Drawing.Size(223, 424);
173 | this.splitContainer2.SplitterDistance = 211;
174 | this.splitContainer2.TabIndex = 4;
175 | //
176 | // treeView1
177 | //
178 | this.treeView1.Dock = System.Windows.Forms.DockStyle.Fill;
179 | this.treeView1.Enabled = false;
180 | this.treeView1.Location = new System.Drawing.Point(0, 0);
181 | this.treeView1.Name = "treeView1";
182 | this.treeView1.Size = new System.Drawing.Size(223, 211);
183 | this.treeView1.TabIndex = 3;
184 | this.treeView1.Visible = false;
185 | //
186 | // zoomSlider
187 | //
188 | this.zoomSlider.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
189 | this.zoomSlider.Enabled = false;
190 | this.zoomSlider.LargeChange = 1;
191 | this.zoomSlider.Location = new System.Drawing.Point(115, 155);
192 | this.zoomSlider.Name = "zoomSlider";
193 | this.zoomSlider.Size = new System.Drawing.Size(104, 45);
194 | this.zoomSlider.TabIndex = 1;
195 | this.zoomSlider.Value = 5;
196 | this.zoomSlider.Visible = false;
197 | //
198 | // propertyGrid1
199 | //
200 | this.propertyGrid1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
201 | | System.Windows.Forms.AnchorStyles.Left)
202 | | System.Windows.Forms.AnchorStyles.Right)));
203 | this.propertyGrid1.Enabled = false;
204 | this.propertyGrid1.Location = new System.Drawing.Point(3, 3);
205 | this.propertyGrid1.Name = "propertyGrid1";
206 | this.propertyGrid1.Size = new System.Drawing.Size(219, 203);
207 | this.propertyGrid1.TabIndex = 0;
208 | this.propertyGrid1.Visible = false;
209 | //
210 | // panel1
211 | //
212 | this.panel1.AutoScroll = true;
213 | this.panel1.AutoSize = true;
214 | this.panel1.Controls.Add(this.pictureBox1);
215 | this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
216 | this.panel1.Location = new System.Drawing.Point(0, 0);
217 | this.panel1.Name = "panel1";
218 | this.panel1.Size = new System.Drawing.Size(445, 424);
219 | this.panel1.TabIndex = 0;
220 | //
221 | // pictureBox1
222 | //
223 | this.pictureBox1.Enabled = false;
224 | this.pictureBox1.Location = new System.Drawing.Point(0, 0);
225 | this.pictureBox1.Name = "pictureBox1";
226 | this.pictureBox1.Size = new System.Drawing.Size(441, 421);
227 | this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
228 | this.pictureBox1.TabIndex = 0;
229 | this.pictureBox1.TabStop = false;
230 | this.pictureBox1.Visible = false;
231 | //
232 | // pnlSubSystem
233 | //
234 | this.pnlSubSystem.AllowDrop = true;
235 | this.pnlSubSystem.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
236 | | System.Windows.Forms.AnchorStyles.Left)
237 | | System.Windows.Forms.AnchorStyles.Right)));
238 | this.pnlSubSystem.Location = new System.Drawing.Point(0, 24);
239 | this.pnlSubSystem.Name = "pnlSubSystem";
240 | this.pnlSubSystem.Size = new System.Drawing.Size(672, 424);
241 | this.pnlSubSystem.TabIndex = 5;
242 | this.pnlSubSystem.DragDrop += new System.Windows.Forms.DragEventHandler(this.pnlSubSystem_DragDrop);
243 | this.pnlSubSystem.DragEnter += new System.Windows.Forms.DragEventHandler(this.pnlSubSystem_DragEnter);
244 | //
245 | // MainForm
246 | //
247 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
248 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
249 | this.ClientSize = new System.Drawing.Size(672, 448);
250 | this.Controls.Add(this.pnlSubSystem);
251 | this.Controls.Add(this.splitContainer1);
252 | this.Controls.Add(this.menuStrip1);
253 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
254 | this.MainMenuStrip = this.menuStrip1;
255 | this.Name = "MainForm";
256 | this.Text = "Switch Layout Editor";
257 | this.Load += new System.EventHandler(this.Form1_Load);
258 | this.menuStrip1.ResumeLayout(false);
259 | this.menuStrip1.PerformLayout();
260 | this.splitContainer1.Panel1.ResumeLayout(false);
261 | this.splitContainer1.Panel2.ResumeLayout(false);
262 | this.splitContainer1.Panel2.PerformLayout();
263 | ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
264 | this.splitContainer1.ResumeLayout(false);
265 | this.splitContainer2.Panel1.ResumeLayout(false);
266 | this.splitContainer2.Panel2.ResumeLayout(false);
267 | this.splitContainer2.Panel2.PerformLayout();
268 | ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).EndInit();
269 | this.splitContainer2.ResumeLayout(false);
270 | ((System.ComponentModel.ISupportInitialize)(this.zoomSlider)).EndInit();
271 | this.panel1.ResumeLayout(false);
272 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
273 | this.ResumeLayout(false);
274 | this.PerformLayout();
275 |
276 | }
277 |
278 | #endregion
279 | private System.Windows.Forms.MenuStrip menuStrip1;
280 | private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
281 | private System.Windows.Forms.ToolStripMenuItem openBFLYTToolStripMenuItem;
282 | private System.Windows.Forms.SplitContainer splitContainer1;
283 | private System.Windows.Forms.SplitContainer splitContainer2;
284 | private System.Windows.Forms.TreeView treeView1;
285 | private System.Windows.Forms.PropertyGrid propertyGrid1;
286 | private System.Windows.Forms.TrackBar zoomSlider;
287 | private System.Windows.Forms.Panel panel1;
288 | private System.Windows.Forms.PictureBox pictureBox1;
289 | private System.Windows.Forms.Panel pnlSubSystem;
290 | private System.Windows.Forms.ToolStripMenuItem toolsToolStripMenuItem;
291 | private System.Windows.Forms.ToolStripMenuItem layoutDiffToolStripMenuItem;
292 | private System.Windows.Forms.ToolStripMenuItem checkUpdateToolStripMenuItem;
293 | private System.Windows.Forms.ToolStripMenuItem importJSONToolStripMenuItem;
294 | private System.Windows.Forms.ToolStripMenuItem bFLANToolStripMenuItem;
295 | private System.Windows.Forms.ToolStripMenuItem createSzsFromFolderToolStripMenuItem;
296 | }
297 | }
298 |
299 |
--------------------------------------------------------------------------------
/BflytPreview/MainForm.cs:
--------------------------------------------------------------------------------
1 | using SwitchThemes.Common;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.ComponentModel;
5 | using System.IO;
6 | using System.Windows.Forms;
7 | using Syroot.BinaryData;
8 | using System.Threading.Tasks;
9 | using SwitchThemes.Common.Bflyt;
10 | using SwitchThemes.Common.Bflan;
11 | using System.Text;
12 | using System.Linq;
13 | using SARCExt;
14 |
15 | namespace BflytPreview
16 | {
17 | public partial class MainForm : Form
18 | {
19 | public static void CheckForUpdates(bool showErrors)
20 | {
21 | try
22 | {
23 | var githubClient = new Octokit.GitHubClient(new Octokit.ProductHeaderValue("SwitchLayoutEditor"));
24 | var ver = githubClient.Repository.Release.GetAll("FuryBaguette", "SwitchLayoutEditor").GetAwaiter().GetResult();
25 | if (ver.Count > Program.AppRelease)
26 | {
27 | if (MessageBox.Show($"A new version has been found: {ver[0].Name}\r\n{ver[0].Body}\r\nOpen the github page ?", "", MessageBoxButtons.YesNo) == DialogResult.Yes)
28 | System.Diagnostics.Process.Start("https://github.com/FuryBaguette/SwitchLayoutEditor/releases/latest");
29 | }
30 | else if (showErrors)
31 | MessageBox.Show("You're running the latest version :)");
32 | }
33 | catch (Exception ex)
34 | {
35 | if (showErrors)
36 | MessageBox.Show("Error while searching for updates:\r\n" + ex.ToString());
37 | }
38 | }
39 |
40 | public MainForm(string[] args = null)
41 | {
42 | InitializeComponent();
43 |
44 | foreach (string s in args)
45 | if (File.Exists(s))
46 | OpenFileFromDisk(s);
47 | }
48 |
49 | private void openBFLYTToolStripMenuItem_Click(object sender, EventArgs e)
50 | {
51 | OpenFileDialog opn = new OpenFileDialog() { Filter = "Supported files (bflyt,szs,bflan)|*.bflyt;*.szs;*.bflan|All files|*.*" };
52 | if (opn.ShowDialog() != DialogResult.OK) return;
53 | OpenFileFromDisk(opn.FileName);
54 | }
55 |
56 | private void Form1_Load(object sender, System.EventArgs e)
57 | {
58 | this.Text += $" - Release {Program.AppRelease}";
59 | #if DEBUG
60 | this.Text += " - This is a debug build, auto updates are disabled.";
61 | createSzsFromFolderToolStripMenuItem.Visible = true;
62 | #else
63 | Task.Run(() => CheckForUpdates(false));
64 | createSzsFromFolderToolStripMenuItem.Visible = false;
65 | #endif
66 | //#if DEBUG
67 | // string AutoLaunch = @"RdtBase.bflyt";
68 | // if (!File.Exists(AutoLaunch)) return;
69 | // OpenFile(File.ReadAllBytes(AutoLaunch), AutoLaunch);
70 | //#endif
71 | }
72 |
73 | public void OpenForm(Form f)
74 | {
75 | this.IsMdiContainer = true;
76 | f.TopLevel = false;
77 | f.Parent = pnlSubSystem;
78 | f.Show();
79 | }
80 |
81 | public Form OpenFileFromDisk(string path) =>
82 | OpenFile(File.ReadAllBytes(path), new DiskFileProvider(path));
83 |
84 | public Form OpenFile(byte[] File, IFileWriter saveTo)
85 | {
86 | string Magic = Encoding.ASCII.GetString(File, 0, 4);
87 | Form result = null;
88 | if (Magic == "Yaz0")
89 | return OpenFile(ManagedYaz0.Decompress(File), saveTo);
90 | else if (Magic == "SARC")
91 | result = new EditorForms.SzsEditor(SARCExt.SARC.Unpack(File), saveTo, this);
92 | else if (Magic == "FLYT")
93 | result = new EditorView(new BflytFile(File), saveTo);
94 | else if (Magic == "FLAN")
95 | result = new BflanEditor(new BflanFile(File), saveTo);
96 |
97 | if (result != null)
98 | OpenForm(result);
99 |
100 | return result;
101 | }
102 |
103 | private void pnlSubSystem_DragEnter(object sender, DragEventArgs e)
104 | {if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy;}
105 |
106 | private void pnlSubSystem_DragDrop(object sender, DragEventArgs e)
107 | {
108 | string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
109 | foreach (string file in files)
110 | OpenFileFromDisk(file);
111 | }
112 |
113 | private void layoutDiffToolStripMenuItem_Click(object sender, EventArgs e)
114 | => new EditorForms.LayoutDiffForm().Show();
115 |
116 | private void checkUpdateToolStripMenuItem_Click(object sender, EventArgs e)
117 | {
118 | CheckForUpdates(true);
119 | }
120 |
121 | private void BFLANToolStripMenuItem_Click(object sender, EventArgs e)
122 | {
123 | try
124 | {
125 | var f = BflanEditor.OpenFromJson();
126 | if (f != null) OpenForm(f);
127 | }
128 | catch (Exception ex)
129 | {
130 | MessageBox.Show(
131 | "Error while opening the provided file: " + ex.Message + "\r\n" +
132 | "This often happens when trying to open a json file that doesn't contain animations. " +
133 | "If you want to open a json layout open the target szs first and then load it from the window that appears.\r\n\r\n" +
134 | "More details: " + ex.ToString());
135 | }
136 | }
137 |
138 | private void createSzsFromFolderToolStripMenuItem_Click(object sender, EventArgs e)
139 | {
140 | using var folderBrowser = new FolderBrowserDialog();
141 | if (folderBrowser.ShowDialog() == DialogResult.OK)
142 | {
143 | using var saveFileDialog = new SaveFileDialog
144 | {
145 | Filter = "szs files|*.szs",
146 | FileName = "new.szs"
147 | };
148 |
149 | if (saveFileDialog.ShowDialog() != DialogResult.OK)
150 | return;
151 |
152 | var root = folderBrowser.SelectedPath;
153 | var files = Directory.GetFiles(folderBrowser.SelectedPath, "*", SearchOption.AllDirectories)
154 | .Select(x => x.Remove(0, root.Length + 1))
155 | .ToArray();
156 |
157 | var szs = new SARCExt.SarcData();
158 | foreach (var file in files)
159 | {
160 | var name = file.Replace('\\', '/');
161 | var data = File.ReadAllBytes(Path.Combine(root, file));
162 | szs.Files.Add(name, data);
163 | }
164 |
165 | var s = SARC.Pack(szs);
166 | File.WriteAllBytes(saveFileDialog.FileName, ManagedYaz0.Compress(s.Item2, 3, s.Item1));
167 | }
168 | }
169 | }
170 |
171 | public class Vector3Converter : System.ComponentModel.TypeConverter
172 | {
173 | public override bool GetPropertiesSupported(ITypeDescriptorContext context) => true;
174 |
175 | public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, Type sourceType)
176 | {
177 | return sourceType == typeof(string);
178 | }
179 |
180 | public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
181 | {
182 | string[] tokens = ((string)value).Split(';');
183 | return new Vector3(
184 | float.Parse(tokens[0]),
185 | float.Parse(tokens[1]),
186 | float.Parse(tokens[2]));
187 | }
188 |
189 | public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
190 | {
191 | var v = (Vector3)value;
192 | return $"{v.X};{v.Y};{v.Z}";
193 | }
194 | }
195 |
196 | public class Vector2Converter : System.ComponentModel.TypeConverter
197 | {
198 | public override bool GetPropertiesSupported(ITypeDescriptorContext context) => true;
199 |
200 | public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, Type sourceType)
201 | {
202 | return sourceType == typeof(string);
203 | }
204 |
205 | public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
206 | {
207 | string[] tokens = ((string)value).Split(';');
208 | return new Vector2(
209 | float.Parse(tokens[0]),
210 | float.Parse(tokens[1]));
211 | }
212 |
213 | public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
214 | {
215 | var v = (Vector2)value;
216 | return $"{v.X};{v.Y}";
217 | }
218 | }
219 | }
220 |
--------------------------------------------------------------------------------
/BflytPreview/OpenTK.dll.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/BflytPreview/Program.cs:
--------------------------------------------------------------------------------
1 | using SwitchThemes.Common;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.ComponentModel;
5 | using System.Drawing.Design;
6 | using System.Linq;
7 | using System.Threading.Tasks;
8 | using System.Windows.Forms;
9 |
10 | namespace BflytPreview
11 | {
12 | static class Program
13 | {
14 | //Increase this by one for each release on github
15 | public const int AppRelease = 16;
16 |
17 | ///
18 | /// Punto di ingresso principale dell'applicazione.
19 | ///
20 | [STAThread]
21 | static void Main(params string[] args)
22 | {
23 | TypeDescriptor.AddAttributes(typeof(Vector3), new TypeConverterAttribute(typeof(Vector3Converter)));
24 | TypeDescriptor.AddAttributes(typeof(Vector2), new TypeConverterAttribute(typeof(Vector2Converter)));
25 |
26 | Application.EnableVisualStyles();
27 | Application.SetCompatibleTextRenderingDefault(false);
28 | Application.Run(new MainForm(args));
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/BflytPreview/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // Le informazioni generali relative a un assembly sono controllate dal seguente
6 | // set di attributi. Modificare i valori di questi attributi per modificare le informazioni
7 | // associate a un assembly.
8 | [assembly: AssemblyTitle("BflytPreview")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("BflytPreview")]
13 | [assembly: AssemblyCopyright("Copyright © 2018")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Se si imposta ComVisible su false, i tipi in questo assembly non saranno visibili
18 | // ai componenti COM. Se è necessario accedere a un tipo in questo assembly da
19 | // COM, impostare su true l'attributo ComVisible per tale tipo.
20 | [assembly: ComVisible(false)]
21 |
22 | // Se il progetto viene esposto a COM, il GUID seguente verrà utilizzato come ID della libreria dei tipi
23 | [assembly: Guid("d59c0348-7d8e-46df-8761-1ca9c5ff5556")]
24 |
25 | // Le informazioni sulla versione di un assembly sono costituite dai seguenti quattro valori:
26 | //
27 | // Versione principale
28 | // Versione secondaria
29 | // Numero di build
30 | // Revisione
31 | //
32 | // È possibile specificare tutti i valori oppure impostare valori predefiniti per i numeri relativi alla revisione e alla build
33 | // usando l'asterisco '*' come illustrato di seguito:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.16")]
36 | [assembly: AssemblyFileVersion("1.0.0.16")]
37 |
--------------------------------------------------------------------------------
/BflytPreview/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // Il codice è stato generato da uno strumento.
4 | // Versione runtime:4.0.30319.42000
5 | //
6 | // Le modifiche apportate a questo file possono provocare un comportamento non corretto e andranno perse se
7 | // il codice viene rigenerato.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace BflytPreview.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// Classe di risorse fortemente tipizzata per la ricerca di stringhe localizzate e così via.
17 | ///
18 | // Questa classe è stata generata automaticamente dalla classe StronglyTypedResourceBuilder.
19 | // tramite uno strumento quale ResGen o Visual Studio.
20 | // Per aggiungere o rimuovere un membro, modificare il file con estensione ResX ed eseguire nuovamente ResGen
21 | // con l'opzione /str oppure ricompilare il progetto VS.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Restituisce l'istanza di ResourceManager nella cache utilizzata da questa classe.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BflytPreview.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Esegue l'override della proprietà CurrentUICulture del thread corrente per tutte le
51 | /// ricerche di risorse eseguite utilizzando questa classe di risorse fortemente tipizzata.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/BflytPreview/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/BflytPreview/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // Il codice è stato generato da uno strumento.
4 | // Versione runtime:4.0.30319.42000
5 | //
6 | // Le modifiche apportate a questo file possono provocare un comportamento non corretto e andranno perse se
7 | // il codice viene rigenerato.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace BflytPreview.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.5.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/BflytPreview/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/BflytPreview/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // Il codice è stato generato da uno strumento.
4 | // Versione runtime:4.0.30319.42000
5 | //
6 | // Le modifiche apportate a questo file possono provocare un comportamento non corretto e andranno perse se
7 | // il codice viene rigenerato.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace BflytPreview {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.5.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 |
26 | [global::System.Configuration.UserScopedSettingAttribute()]
27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
28 | [global::System.Configuration.DefaultSettingValueAttribute("Black")]
29 | public global::System.Drawing.Color PaneColor {
30 | get {
31 | return ((global::System.Drawing.Color)(this["PaneColor"]));
32 | }
33 | set {
34 | this["PaneColor"] = value;
35 | }
36 | }
37 |
38 | [global::System.Configuration.UserScopedSettingAttribute()]
39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
40 | [global::System.Configuration.DefaultSettingValueAttribute("Red")]
41 | public global::System.Drawing.Color SelectedColor {
42 | get {
43 | return ((global::System.Drawing.Color)(this["SelectedColor"]));
44 | }
45 | set {
46 | this["SelectedColor"] = value;
47 | }
48 | }
49 |
50 | [global::System.Configuration.UserScopedSettingAttribute()]
51 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
52 | [global::System.Configuration.DefaultSettingValueAttribute("LightGreen")]
53 | public global::System.Drawing.Color OutlineColor {
54 | get {
55 | return ((global::System.Drawing.Color)(this["OutlineColor"]));
56 | }
57 | set {
58 | this["OutlineColor"] = value;
59 | }
60 | }
61 |
62 | [global::System.Configuration.UserScopedSettingAttribute()]
63 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
64 | [global::System.Configuration.DefaultSettingValueAttribute("")]
65 | public string BgFileName {
66 | get {
67 | return ((string)(this["BgFileName"]));
68 | }
69 | set {
70 | this["BgFileName"] = value;
71 | }
72 | }
73 |
74 | [global::System.Configuration.UserScopedSettingAttribute()]
75 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
76 | [global::System.Configuration.DefaultSettingValueAttribute("False")]
77 | public bool ShowImage {
78 | get {
79 | return ((bool)(this["ShowImage"]));
80 | }
81 | set {
82 | this["ShowImage"] = value;
83 | }
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/BflytPreview/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Black
7 |
8 |
9 | Red
10 |
11 |
12 | LightGreen
13 |
14 |
15 |
16 |
17 |
18 | False
19 |
20 |
21 |
--------------------------------------------------------------------------------
/BflytPreview/SettingsWindow.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace BflytPreview
2 | {
3 | partial class SettingsWindow
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SettingsWindow));
32 | this.label1 = new System.Windows.Forms.Label();
33 | this.pickColor = new System.Windows.Forms.Button();
34 | this.selectedColor = new System.Windows.Forms.Button();
35 | this.label2 = new System.Windows.Forms.Label();
36 | this.outlineColor = new System.Windows.Forms.Button();
37 | this.label3 = new System.Windows.Forms.Label();
38 | this.loadBackgroundImage = new System.Windows.Forms.Button();
39 | this.pictureBox1 = new System.Windows.Forms.PictureBox();
40 | this.showImg = new System.Windows.Forms.Button();
41 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
42 | this.SuspendLayout();
43 | //
44 | // label1
45 | //
46 | this.label1.AutoSize = true;
47 | this.label1.Location = new System.Drawing.Point(13, 13);
48 | this.label1.Name = "label1";
49 | this.label1.Size = new System.Drawing.Size(59, 13);
50 | this.label1.TabIndex = 0;
51 | this.label1.Text = "Pane Color";
52 | //
53 | // pickColor
54 | //
55 | this.pickColor.Location = new System.Drawing.Point(96, 8);
56 | this.pickColor.Name = "pickColor";
57 | this.pickColor.Size = new System.Drawing.Size(75, 23);
58 | this.pickColor.TabIndex = 1;
59 | this.pickColor.UseVisualStyleBackColor = true;
60 | this.pickColor.Click += new System.EventHandler(this.pickColor_Click);
61 | //
62 | // selectedColor
63 | //
64 | this.selectedColor.Location = new System.Drawing.Point(96, 37);
65 | this.selectedColor.Name = "selectedColor";
66 | this.selectedColor.Size = new System.Drawing.Size(75, 23);
67 | this.selectedColor.TabIndex = 2;
68 | this.selectedColor.UseVisualStyleBackColor = true;
69 | this.selectedColor.Click += new System.EventHandler(this.selectedColor_Click);
70 | //
71 | // label2
72 | //
73 | this.label2.AutoSize = true;
74 | this.label2.Location = new System.Drawing.Point(13, 43);
75 | this.label2.Name = "label2";
76 | this.label2.Size = new System.Drawing.Size(76, 13);
77 | this.label2.TabIndex = 3;
78 | this.label2.Text = "Selected Color";
79 | //
80 | // outlineColor
81 | //
82 | this.outlineColor.Location = new System.Drawing.Point(96, 67);
83 | this.outlineColor.Name = "outlineColor";
84 | this.outlineColor.Size = new System.Drawing.Size(75, 23);
85 | this.outlineColor.TabIndex = 4;
86 | this.outlineColor.UseVisualStyleBackColor = true;
87 | this.outlineColor.Click += new System.EventHandler(this.outlineColor_Click);
88 | //
89 | // label3
90 | //
91 | this.label3.AutoSize = true;
92 | this.label3.Location = new System.Drawing.Point(13, 72);
93 | this.label3.Name = "label3";
94 | this.label3.Size = new System.Drawing.Size(67, 13);
95 | this.label3.TabIndex = 5;
96 | this.label3.Text = "Outline Color";
97 | //
98 | // loadBackgroundImage
99 | //
100 | this.loadBackgroundImage.Location = new System.Drawing.Point(13, 102);
101 | this.loadBackgroundImage.Name = "loadBackgroundImage";
102 | this.loadBackgroundImage.Size = new System.Drawing.Size(158, 23);
103 | this.loadBackgroundImage.TabIndex = 6;
104 | this.loadBackgroundImage.Text = "Set Background Image";
105 | this.loadBackgroundImage.UseVisualStyleBackColor = true;
106 | this.loadBackgroundImage.Click += new System.EventHandler(this.loadBackgroundImage_Click);
107 | //
108 | // pictureBox1
109 | //
110 | this.pictureBox1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
111 | this.pictureBox1.Location = new System.Drawing.Point(177, 8);
112 | this.pictureBox1.Name = "pictureBox1";
113 | this.pictureBox1.Size = new System.Drawing.Size(206, 117);
114 | this.pictureBox1.TabIndex = 7;
115 | this.pictureBox1.TabStop = false;
116 | //
117 | // showImg
118 | //
119 | this.showImg.Location = new System.Drawing.Point(13, 132);
120 | this.showImg.Name = "showImg";
121 | this.showImg.Size = new System.Drawing.Size(158, 23);
122 | this.showImg.TabIndex = 8;
123 | this.showImg.Text = "Show Image";
124 | this.showImg.UseVisualStyleBackColor = true;
125 | this.showImg.Click += new System.EventHandler(this.showImg_Click);
126 | //
127 | // SettingsWindow
128 | //
129 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
130 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
131 | this.ClientSize = new System.Drawing.Size(393, 173);
132 | this.Controls.Add(this.showImg);
133 | this.Controls.Add(this.pictureBox1);
134 | this.Controls.Add(this.loadBackgroundImage);
135 | this.Controls.Add(this.label3);
136 | this.Controls.Add(this.outlineColor);
137 | this.Controls.Add(this.label2);
138 | this.Controls.Add(this.selectedColor);
139 | this.Controls.Add(this.pickColor);
140 | this.Controls.Add(this.label1);
141 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
142 | this.Name = "SettingsWindow";
143 | this.Text = "Settings";
144 | this.Load += new System.EventHandler(this.SettingsWindow_Load);
145 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
146 | this.ResumeLayout(false);
147 | this.PerformLayout();
148 |
149 | }
150 |
151 | #endregion
152 |
153 | private System.Windows.Forms.Label label1;
154 | private System.Windows.Forms.Button pickColor;
155 | private System.Windows.Forms.Button selectedColor;
156 | private System.Windows.Forms.Label label2;
157 | private System.Windows.Forms.Button outlineColor;
158 | private System.Windows.Forms.Label label3;
159 | private System.Windows.Forms.Button loadBackgroundImage;
160 | private System.Windows.Forms.PictureBox pictureBox1;
161 | private System.Windows.Forms.Button showImg;
162 | }
163 | }
--------------------------------------------------------------------------------
/BflytPreview/SettingsWindow.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 |
11 | namespace BflytPreview
12 | {
13 | public partial class SettingsWindow : Form
14 | {
15 | public SettingsWindow()
16 | {
17 | InitializeComponent();
18 | }
19 |
20 | private void SettingsWindow_Load(object sender, EventArgs e)
21 | {
22 | pickColor.BackColor = Settings.Default.PaneColor;
23 | selectedColor.BackColor = Settings.Default.SelectedColor;
24 | outlineColor.BackColor = Settings.Default.OutlineColor;
25 | Console.WriteLine(Settings.Default.BgFileName);
26 | if (!string.IsNullOrEmpty(Settings.Default.BgFileName))
27 | {
28 | pictureBox1.BackgroundImage = Image.FromFile(Settings.Default.BgFileName);
29 | EditorView.texture = EditorView.LoadBgImage(Settings.Default.BgFileName, false, true);
30 | }
31 | if (Settings.Default.ShowImage)
32 | showImg.Text = "Hide Image";
33 | }
34 |
35 | private void SettingsWindow_FormClosing(object sender, FormClosingEventArgs e)
36 | {
37 |
38 | Settings.Default.PaneColor = pickColor.BackColor;
39 | Settings.Default.SelectedColor = selectedColor.BackColor;
40 | Settings.Default.OutlineColor = outlineColor.BackColor;
41 | Settings.Default.OutlineColor = outlineColor.BackColor;
42 | Settings.Default.Save();
43 | }
44 |
45 | private void pickColor_Click(object sender, EventArgs e)
46 | {
47 | ColorDialog MyDialog = new ColorDialog();
48 | MyDialog.ShowHelp = true;
49 | MyDialog.Color = Settings.Default.PaneColor;
50 |
51 | if (MyDialog.ShowDialog() == DialogResult.OK)
52 | Settings.Default.PaneColor = pickColor.BackColor = MyDialog.Color;
53 | }
54 |
55 | private void selectedColor_Click(object sender, EventArgs e)
56 | {
57 | ColorDialog MyDialog = new ColorDialog();
58 | MyDialog.ShowHelp = true;
59 | MyDialog.Color = Settings.Default.SelectedColor;
60 |
61 | if (MyDialog.ShowDialog() == DialogResult.OK)
62 | Settings.Default.SelectedColor = selectedColor.BackColor = MyDialog.Color;
63 | }
64 |
65 | private void outlineColor_Click(object sender, EventArgs e)
66 | {
67 | ColorDialog MyDialog = new ColorDialog();
68 | MyDialog.ShowHelp = true;
69 | MyDialog.Color = Settings.Default.OutlineColor;
70 |
71 | if (MyDialog.ShowDialog() == DialogResult.OK)
72 | Settings.Default.OutlineColor = outlineColor.BackColor = MyDialog.Color;
73 | }
74 |
75 | private void loadBackgroundImage_Click(object sender, EventArgs e)
76 | {
77 | OpenFileDialog opn = new OpenFileDialog() { Filter = "Supported files (jpg,jpeg,png)|*.jpg;*.jpeg;*.png|All files|*.*" };
78 | if (opn.ShowDialog() != DialogResult.OK) return;
79 |
80 | pictureBox1.BackgroundImage = Image.FromFile(opn.FileName);
81 | Settings.Default.BgFileName = opn.FileName;
82 | EditorView.texture = EditorView.LoadBgImage(opn.FileName, false, true);
83 | }
84 |
85 | private void showImg_Click(object sender, EventArgs e)
86 | {
87 | if (!Settings.Default.ShowImage)
88 | {
89 | Settings.Default.ShowImage = true;
90 | showImg.Text = "Hide Image";
91 | }
92 | else
93 | {
94 | Settings.Default.ShowImage = false;
95 | showImg.Text = "Show Image";
96 | }
97 | }
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/BflytPreview/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FuryBaguette/SwitchLayoutEditor/139adf8fa2ae3f59eee61c4465f213c30527d8e6/BflytPreview/favicon.ico
--------------------------------------------------------------------------------
/BflytPreview/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FuryBaguette/SwitchLayoutEditor/139adf8fa2ae3f59eee61c4465f213c30527d8e6/BflytPreview/icon.ico
--------------------------------------------------------------------------------
/BflytPreview/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SwitchLayoutEditor
2 | This program can edit and render BFLYT and BFLAN files commonly used for layouts in Switch interfaces and games. It enables you to easily create/edit themes. As this is a work in progress, builds may get outdated quickly, you should check this page often.
3 |
4 | ## Usage / Wiki
5 | Just launch the exe and open a SZS/BFLYT/BFLAN file. \
6 | BFLYT/BFLAN files are commonly found in SZS archives, when opening a SZS file you can double click on the files in the list to edit them (if they're supported). \
7 | For a more in depth guide, [click here](https://github.com/FuryBaguette/SwitchLayoutEditor/wiki) to go to the wiki.
8 |
9 | ## Features
10 | - Layout loading, editing and saving
11 | - Rendering the bounding boxes of the components
12 | - SZS editing
13 | - Drag and drop
14 | - Simultaneous file editing
15 | - Import/Export JSON patch (Compatible with Switch themes)
16 | - Animations editing
17 |
18 | ## Support
19 | - Use the github issues to report problems/bugs **OR**
20 | - Join the [discord server](https://discord.gg/ap6yfR2) for support, news/announcements before anyone, be a tester or just talk.
21 |
22 | ## Screenshot
23 | This is using the original from the Switch's home menu:
24 | 
25 |
26 | Example of a custom layout:
27 | 
28 |
29 | ## Building
30 | To build you need the SwitchThemesCommon shared project from [this repo](https://github.com/exelix11/SwitchThemeInjector).
31 | In case of issues try using a version from commit from the same day as the last commit on this repo.
32 |
33 | ## Credits
34 | - [FuryBaguette](https://github.com/FuryBaguette) - Development
35 | - [exelix](https://github.com/exelix11) - Base of the editor & Continuous development
36 | - [Aboud](https://github.com/aboood40091) - [Sarc Tool](https://github.com/aboood40091/SARC-Tool)
37 | - [Syroot](https://gitlab.com/Syroot) - [Binary Data](https://gitlab.com/Syroot/BinaryData)
38 |
--------------------------------------------------------------------------------
/Screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FuryBaguette/SwitchLayoutEditor/139adf8fa2ae3f59eee61c4465f213c30527d8e6/Screenshot.png
--------------------------------------------------------------------------------
/Screenshots/Dragging.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FuryBaguette/SwitchLayoutEditor/139adf8fa2ae3f59eee61c4465f213c30527d8e6/Screenshots/Dragging.gif
--------------------------------------------------------------------------------
/Screenshots/EditorPreview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FuryBaguette/SwitchLayoutEditor/139adf8fa2ae3f59eee61c4465f213c30527d8e6/Screenshots/EditorPreview.png
--------------------------------------------------------------------------------
/Screenshots/Example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FuryBaguette/SwitchLayoutEditor/139adf8fa2ae3f59eee61c4465f213c30527d8e6/Screenshots/Example.png
--------------------------------------------------------------------------------
/Screenshots/LayoutEditing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FuryBaguette/SwitchLayoutEditor/139adf8fa2ae3f59eee61c4465f213c30527d8e6/Screenshots/LayoutEditing.png
--------------------------------------------------------------------------------
/Screenshots/MainMenu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FuryBaguette/SwitchLayoutEditor/139adf8fa2ae3f59eee61c4465f213c30527d8e6/Screenshots/MainMenu.png
--------------------------------------------------------------------------------
/Screenshots/PaneMenu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FuryBaguette/SwitchLayoutEditor/139adf8fa2ae3f59eee61c4465f213c30527d8e6/Screenshots/PaneMenu.png
--------------------------------------------------------------------------------
/Screenshots/PropertiesMenu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FuryBaguette/SwitchLayoutEditor/139adf8fa2ae3f59eee61c4465f213c30527d8e6/Screenshots/PropertiesMenu.png
--------------------------------------------------------------------------------
/Screenshots/SaveFile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FuryBaguette/SwitchLayoutEditor/139adf8fa2ae3f59eee61c4465f213c30527d8e6/Screenshots/SaveFile.png
--------------------------------------------------------------------------------
/Screenshots/Settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FuryBaguette/SwitchLayoutEditor/139adf8fa2ae3f59eee61c4465f213c30527d8e6/Screenshots/Settings.png
--------------------------------------------------------------------------------
/Screenshots/Szs-loading.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FuryBaguette/SwitchLayoutEditor/139adf8fa2ae3f59eee61c4465f213c30527d8e6/Screenshots/Szs-loading.png
--------------------------------------------------------------------------------
/Screenshots/SzsEditor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FuryBaguette/SwitchLayoutEditor/139adf8fa2ae3f59eee61c4465f213c30527d8e6/Screenshots/SzsEditor.png
--------------------------------------------------------------------------------
/SwitchLayoutEditor.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29020.237
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BflytPreview", "BflytPreview\BflytPreview.csproj", "{D59C0348-7D8E-46DF-8761-1CA9C5FF5556}"
7 | EndProject
8 | Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "SwitchThemesCommon", "..\SwitchThemeInjector\SwitchThemesCommon\SwitchThemesCommon.shproj", "{11174F92-402D-4064-B278-F52842A48251}"
9 | EndProject
10 | Global
11 | GlobalSection(SharedMSBuildProjectFiles) = preSolution
12 | ..\SwitchThemeInjector\SwitchThemesCommon\SwitchThemesCommon.projitems*{11174f92-402d-4064-b278-f52842a48251}*SharedItemsImports = 13
13 | ..\SwitchThemeInjector\SwitchThemesCommon\SwitchThemesCommon.projitems*{d59c0348-7d8e-46df-8761-1ca9c5ff5556}*SharedItemsImports = 4
14 | EndGlobalSection
15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
16 | Debug|Any CPU = Debug|Any CPU
17 | Release|Any CPU = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
20 | {D59C0348-7D8E-46DF-8761-1CA9C5FF5556}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {D59C0348-7D8E-46DF-8761-1CA9C5FF5556}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {D59C0348-7D8E-46DF-8761-1CA9C5FF5556}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {D59C0348-7D8E-46DF-8761-1CA9C5FF5556}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {69ED960A-80B0-4EEB-B308-2DD5CC30E367}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/docs/EditorAutoUpdate.xml:
--------------------------------------------------------------------------------
1 |
2 | -
3 | 1.0.1.0
4 | https://github.com/FuryBaguette/SwitchLayoutEditor/releases/download/v1.0.0-beta5/Release.zip
5 |
6 | https://git.io/fjZv0
7 | - Animations editor (.bflan files)
8 | - Group (grp panes) editing for bflyt files
9 | - Fix for a some crashes and some minor improvements
10 |
11 | false
12 |
13 |
--------------------------------------------------------------------------------
/dragdroptree.txt:
--------------------------------------------------------------------------------
1 | treeView1.AllowDrop = true;
2 | treeView1.ItemDrag += new ItemDragEventHandler(treeView1_ItemDrag);
3 | treeView1.DragEnter += new DragEventHandler(treeView1_DragEnter);
4 | treeView1.DragOver += new DragEventHandler(treeView1_DragOver);
5 | treeView1.DragDrop += new DragEventHandler(treeView1_DragDrop);
6 |
7 | #region Drag tree node
8 | private void treeView1_ItemDrag(object sender, ItemDragEventArgs e)
9 | {
10 | if (e.Button == MouseButtons.Left)
11 | {
12 | DoDragDrop(e.Item, DragDropEffects.Move);
13 | }
14 |
15 | else if (e.Button == MouseButtons.Right)
16 | {
17 | DoDragDrop(e.Item, DragDropEffects.Copy);
18 | }
19 | }
20 |
21 | private void treeView1_DragEnter(object sender, DragEventArgs e)
22 | {
23 | e.Effect = e.AllowedEffect;
24 | }
25 |
26 | private void treeView1_DragOver(object sender, DragEventArgs e)
27 | {
28 | Point targetPoint = treeView1.PointToClient(new Point(e.X, e.Y));
29 | treeView1.SelectedNode = treeView1.GetNodeAt(targetPoint);
30 | }
31 |
32 | private void treeView1_DragDrop(object sender, DragEventArgs e)
33 | {
34 | Point targetPoint = treeView1.PointToClient(new Point(e.X, e.Y));
35 | TreeNode targetNode = treeView1.GetNodeAt(targetPoint);
36 | TreeNode draggedNode = (TreeNode)e.Data.GetData(typeof(TreeNode));
37 |
38 | if (!draggedNode.Equals(targetNode) && !ContainsNode(draggedNode, targetNode))
39 | {
40 | if (e.Effect == DragDropEffects.Move)
41 | {
42 | draggedNode.Remove();
43 | targetNode.Nodes.Add(draggedNode);
44 | }
45 |
46 | else if (e.Effect == DragDropEffects.Copy)
47 | {
48 | targetNode.Nodes.Add((TreeNode)draggedNode.Clone());
49 | }
50 |
51 | targetNode.Expand();
52 | }
53 | }
54 |
55 | private bool ContainsNode(TreeNode node1, TreeNode node2)
56 | {
57 | if (node2.Parent == null) return false;
58 | if (node2.Parent.Equals(node1)) return true;
59 |
60 | return ContainsNode(node1, node2.Parent);
61 | }
62 | #endregion
--------------------------------------------------------------------------------