/// <summary> /// Iterates all the data archives, extracting and BLT encoding all files /// <para>Patches are applied where applicable to get the most up-to-date variant of each file.</para> /// </summary> /// <param name="archives"></param> public void EnumerateDataArchives(IEnumerable <string> archives, bool applyTags = false) { Log.WriteLine("Exporting Data Archive files"); foreach (var archivename in archives) { using var mpq = new MpqArchive(archivename, FileAccess.Read); Log.WriteLine(" Exporting " + Path.GetFileName(mpq.FilePath)); if (TryGetListFile(mpq, out var files)) { mpq.AddPatchArchives(PatchArchives); ExportFiles(mpq, files, applyTags).Wait(); mpq.Dispose(); } else if (TryReadAlpha(mpq, archivename)) { mpq.Dispose(); } else { throw new FormatException(Path.GetFileName(archivename) + " HAS NO LISTFILE!"); } } }
private static void CloseArchive() { _archive.Dispose(); _archive = null; _archiveInput.Enabled = true; _archiveInputBrowseButton.Enabled = true; _openCloseArchiveButton.Text = "Open archive"; _adaptAllButton.Enabled = false; _saveAsButton.Enabled = false; _targetPatchesComboBox.Enabled = false; _originPatch = null; _fileListSorter.Reset(); for (var i = 0; i < _fileList.Items.Count; i++) { var item = _fileList.Items[i].GetTag(); item.OriginalFileStream?.Dispose(); item.AdaptResult?.AdaptedFileStream?.Dispose(); } _fileList.Items.Clear(); _diagnosticsDisplay.Text = string.Empty; GC.Collect(); }
void BuildArchive() { File.Delete(ArchivePath); var otherFiles = Directory.GetFiles(UmswePath); var handle = IntPtr.Zero; SFileCreateArchive(ArchivePath, 0, (uint)(DataFiles.Length + otherFiles.Length), out handle); SFileCloseArchive(handle); using (var mpq = new MpqArchive(ArchivePath, FileAccess.ReadWrite)) { mpq.AddListFile(""); for (int i = 0; i < DataFiles.Length; i++) { var file = DataFiles[i]; mpq.AddFileFromDisk($"{TempFolder}\\{file}", $"UI\\{file}"); } for (int i = 0; i < otherFiles.Length; i++) { var file = otherFiles[i]; mpq.AddFileFromDisk(file, Path.GetFileName(file)); } mpq.Dispose(); } }
public void Close() { if (mpqArchivePath != null) { mpqArchivePath = null; } originalMpqArchive?.Dispose(); }
private static void CloseArchive() { _archive.Dispose(); _archive = null; _archiveInput.Enabled = true; _archiveInputBrowseButton.Enabled = true; _openCloseArchiveButton.Text = "Open archive"; _saveAsButton.Enabled = false; _targetScriptLanguagesComboBox.Enabled = false; _targetScriptLanguagesComboBox.SelectedIndex = -1; _targetScriptLanguagesComboBox.Items.Clear(); // _originScriptLanguage = null; }
private static void CloseArchive() { _archive.Dispose(); _archive = null; _map = null; _archiveInput.Enabled = true; _archiveInputBrowseButton.Enabled = true; _openCloseArchiveButton.Text = "Open archive"; _saveAsButton.Enabled = false; _autoDetectFilesToDecompileButton.Enabled = false; foreach (var checkBox in _filesToDecompileCheckBoxes) { checkBox.Enabled = false; } }
/// <summary> /// Iterates all the patch archives, extracting and BLT encoding all new files /// NOTE: Looks like stormlib handles this automatically with AddPatchArchive(s) /// </summary> public void EnumeratePatchArchives() { if (PatchArchives.Count == 0) { return; } Log.WriteLine("Exporting Patch Archive files"); while (PatchArchives.Count > 0) { using var mpq = new MpqArchive(PatchArchives.Dequeue(), FileAccess.Read); Log.WriteLine(" Exporting " + Path.GetFileName(mpq.FilePath)); if (!TryGetListFile(mpq, out var files)) { throw new Exception(Path.GetFileName(mpq.FilePath) + " MISSING LISTFILE"); } mpq.AddPatchArchives(PatchArchives); ExportFiles(mpq, files).Wait(); mpq.Dispose(); } }
private static void Main(string[] args) { var configuration = new ConfigurationBuilder() .AddJsonFile("appsettings.json") .Build(); _appSettings = new AppSettings { TargetPatches = configuration.GetSection(nameof(AppSettings.TargetPatches)).GetChildren().Select(targetPatch => new TargetPatch { Patch = Enum.Parse <GamePatch>(targetPatch.GetSection(nameof(TargetPatch.Patch)).Value), GameDataPath = targetPatch.GetSection(nameof(TargetPatch.GameDataPath)).Value, }).ToList(), }; _watcher = new FileSystemWatcher(); _watcher.Created += OnWatchedFileEvent; _watcher.Renamed += OnWatchedFileEvent; _watcher.Deleted += OnWatchedFileEvent; var form = new Form(); form.Size = new Size(1280, 720); form.MinimumSize = new Size(400, 300); form.Text = Title; var splitContainer = new SplitContainer { Dock = DockStyle.Fill, }; _archiveInput = new TextBox { PlaceholderText = "Input map or campaign...", }; _openCloseArchiveButton = new Button { Text = "Open archive", Enabled = false, }; _diagnosticsDisplay = new TextBox { Multiline = true, ReadOnly = true, Dock = DockStyle.Fill, ScrollBars = ScrollBars.Vertical, }; _progressBar = new TextProgressBar { Dock = DockStyle.Bottom, Style = ProgressBarStyle.Continuous, VisualMode = TextProgressBar.ProgressBarDisplayMode.CustomText, Visible = false, }; _openArchiveWorker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = false, }; _openArchiveWorker.DoWork += OpenArchiveBackgroundWork; _openArchiveWorker.ProgressChanged += OpenArchiveProgressChanged; _openArchiveWorker.RunWorkerCompleted += OpenArchiveCompleted; _saveArchiveWorker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = false, }; _saveArchiveWorker.DoWork += SaveArchiveBackgroundWork; _saveArchiveWorker.ProgressChanged += SaveArchiveProgressChanged; _saveArchiveWorker.RunWorkerCompleted += SaveArchiveCompleted; _adaptAllButton = new Button { Text = "Adapt all", }; _adaptAllButton.Size = _adaptAllButton.PreferredSize; _adaptAllButton.Enabled = false; _saveAsButton = new Button { Text = "Save As...", }; _saveAsButton.Size = _saveAsButton.PreferredSize; _saveAsButton.Enabled = false; _targetPatchesComboBox = new ComboBox { Enabled = false, DropDownStyle = ComboBoxStyle.DropDownList, Width = 120, }; _targetPatchesComboBox.Items.AddRange(_appSettings.TargetPatches.OrderByDescending(targetPatch => targetPatch.Patch).Select(targetPatch => (object)targetPatch.Patch).ToArray()); if (_targetPatchesComboBox.Items.Count == 1) { _targetPatchesComboBox.SelectedIndex = 0; } _targetPatchesComboBox.SelectedIndexChanged += (s, e) => { _targetPatch = (GamePatch?)_targetPatchesComboBox.SelectedItem; _adaptAllButton.Enabled = _targetPatch.HasValue && _fileList.Items.Count > 0; }; _targetPatchesComboBox.FormattingEnabled = true; _targetPatchesComboBox.Format += (s, e) => { if (e.ListItem is GamePatch gamePatch) { e.Value = gamePatch.ToString().Replace('_', '.'); } }; _archiveInput.TextChanged += OnArchiveInputTextChanged; _archiveInputBrowseButton = new Button { Text = "Browse", }; _archiveInputBrowseButton.Size = _archiveInputBrowseButton.PreferredSize; _archiveInputBrowseButton.Click += (s, e) => { var openFileDialog = new OpenFileDialog { CheckFileExists = false, }; openFileDialog.Filter = string.Join('|', new[] { "Warcraft III archive|*.w3m;*.w3x;*.w3n", "Warcraft III map|*.w3m;*.w3x", "Warcraft III campaign|*.w3n", "All files|*.*", }); var openFileDialogResult = openFileDialog.ShowDialog(); if (openFileDialogResult == DialogResult.OK) { _archiveInput.Text = openFileDialog.FileName; } }; _fileList = new ListView { Dock = DockStyle.Fill, }; _fileListSorter = new FileListSorter(_fileList); _fileList.ListViewItemSorter = _fileListSorter; _fileList.ColumnClick += _fileListSorter.Sort; _fileList.View = View.Details; _fileList.Columns.AddRange(new[] { new ColumnHeader { Text = "Status", Width = 102 }, new ColumnHeader { Text = "FileName", Width = 300 }, new ColumnHeader { Text = "FileType", Width = 130 }, new ColumnHeader { Text = "Archive", Width = 87 }, }); _fileList.FullRowSelect = true; _fileList.MultiSelect = true; _fileList.HeaderStyle = ColumnHeaderStyle.Clickable; _fileList.SmallImageList = new ImageList(); var statusColors = new Dictionary <MapFileStatus, Color> { { MapFileStatus.Adapted, Color.LimeGreen }, { MapFileStatus.AdapterError, Color.Red }, { MapFileStatus.Compatible, Color.ForestGreen }, { MapFileStatus.ConfigError, Color.DarkSlateBlue }, { MapFileStatus.Incompatible, Color.Yellow }, { MapFileStatus.Locked, Color.OrangeRed }, { MapFileStatus.Modified, Color.Blue }, { MapFileStatus.ParseError, Color.Maroon }, { MapFileStatus.Pending, Color.LightSkyBlue }, { MapFileStatus.Removed, Color.DarkSlateGray }, { MapFileStatus.Unadaptable, Color.IndianRed }, { MapFileStatus.Unknown, Color.DarkViolet }, }; foreach (var status in Enum.GetValues(typeof(MapFileStatus))) { _fileList.SmallImageList.Images.Add(new Bitmap(16, 16).WithSolidColor(statusColors[(MapFileStatus)status])); } var fileListContextMenu = new ContextMenuStrip { }; _editContextButton = new ToolStripButton("Edit"); _editContextButton.Enabled = false; _editContextButton.Click += OnClickEditSelected; _adaptContextButton = new ToolStripButton("Adapt"); _adaptContextButton.Enabled = false; _adaptContextButton.Click += OnClickAdaptSelected; _removeContextButton = new ToolStripButton("Remove"); _removeContextButton.Enabled = false; _removeContextButton.Click += OnClickRemoveSelected; fileListContextMenu.Items.AddRange(new[] { _adaptContextButton, _editContextButton, _removeContextButton, }); _fileList.ContextMenuStrip = fileListContextMenu; _openCloseArchiveButton.Size = _openCloseArchiveButton.PreferredSize; _openCloseArchiveButton.Click += OnClickOpenCloseMap; _adaptAllButton.Click += (s, e) => { _targetPatchesComboBox.Enabled = false; var parentsToUpdate = new HashSet <ItemTag>(); for (var i = 0; i < _fileList.Items.Count; i++) { var item = _fileList.Items[i]; var tag = item.GetTag(); var adapter = tag.Adapter; if (adapter != null && (tag.Status == MapFileStatus.Pending || tag.Status == MapFileStatus.Modified)) { tag.CurrentStream.Position = 0; var adaptResult = adapter.AdaptFile(tag.CurrentStream, GetTargetPatch(_targetPatch.Value), tag.GetOriginPatch(_originPatch.Value)); tag.UpdateAdaptResult(adaptResult); if (tag.Parent != null) { parentsToUpdate.Add(tag.Parent); } } } foreach (var parent in parentsToUpdate) { parent.ListViewItem.Update(); } UpdateDiagnosticsDisplay(); }; _fileList.KeyDown += (s, e) => { if (e.KeyCode == Keys.Delete) { OnClickRemoveSelected(s, e); } }; _fileList.SelectedIndexChanged += OnFileSelectionChanged; _fileList.ItemActivate += OnClickEditSelected; _saveAsButton.Click += (s, e) => { var saveFileDialog = new SaveFileDialog { OverwritePrompt = true, CreatePrompt = false, }; var saveFileDialogResult = saveFileDialog.ShowDialog(); if (saveFileDialogResult == DialogResult.OK) { SaveArchive(saveFileDialog.FileName); } }; var flowLayout = new FlowLayoutPanel { Dock = DockStyle.Top, FlowDirection = FlowDirection.TopDown, Width = 640, }; var inputArchiveFlowLayout = new FlowLayoutPanel { FlowDirection = FlowDirection.LeftToRight, }; var buttonsFlowLayout = new FlowLayoutPanel { FlowDirection = FlowDirection.LeftToRight, }; var targetPatchLabel = new Label { Text = "Target patch", TextAlign = ContentAlignment.BottomRight, }; inputArchiveFlowLayout.AddControls(_archiveInput, _archiveInputBrowseButton, _openCloseArchiveButton); buttonsFlowLayout.AddControls(_adaptAllButton, _saveAsButton, targetPatchLabel, _targetPatchesComboBox); flowLayout.AddControls(inputArchiveFlowLayout, buttonsFlowLayout); splitContainer.Panel1.AddControls(_diagnosticsDisplay, flowLayout); splitContainer.Panel2.AddControls(_fileList); form.AddControls(splitContainer, _progressBar); targetPatchLabel.Size = targetPatchLabel.PreferredSize; splitContainer.Panel1.SizeChanged += (s, e) => { var width = splitContainer.Panel1.Width; _archiveInput.Width = (width > 360 ? 360 : width) - 10; inputArchiveFlowLayout.Size = inputArchiveFlowLayout.GetPreferredSize(new Size(width, 0)); buttonsFlowLayout.Size = buttonsFlowLayout.GetPreferredSize(new Size(width, 0)); flowLayout.Height = inputArchiveFlowLayout.Margin.Top + inputArchiveFlowLayout.Height + inputArchiveFlowLayout.Margin.Bottom + buttonsFlowLayout.Margin.Top + buttonsFlowLayout.Height + buttonsFlowLayout.Margin.Bottom; }; splitContainer.SplitterDistance = 640 - splitContainer.SplitterWidth; splitContainer.Panel1MinSize = 200; form.FormClosing += (s, e) => { _archive?.Dispose(); _openArchiveWorker?.Dispose(); _saveArchiveWorker?.Dispose(); _fileSelectionChangedEventTimer?.Dispose(); }; form.ShowDialog(); }
private static void Main(string[] args) { _watcher = new FileSystemWatcher(); _watcher.Created += OnWatchedFileEvent; _watcher.Renamed += OnWatchedFileEvent; _watcher.Deleted += OnWatchedFileEvent; var form = new Form(); form.Text = Title; _archiveInput = new TextBox { PlaceholderText = "Input map...", }; _openCloseArchiveButton = new Button { Text = "Open archive", Enabled = false, }; _saveAsButton = new Button { Text = "Save As...", }; _saveAsButton.Size = _saveAsButton.PreferredSize; _saveAsButton.Enabled = false; _autoDetectFilesToDecompileButton = new Button { Text = "Detect files to decompile", }; _autoDetectFilesToDecompileButton.Size = _autoDetectFilesToDecompileButton.PreferredSize; _autoDetectFilesToDecompileButton.Enabled = false; _filesToDecompileCheckBoxes = new[] { new MapFileCheckBox(MapFiles.Sounds, MapSounds.FileName), new MapFileCheckBox(MapFiles.Cameras, MapCameras.FileName), new MapFileCheckBox(MapFiles.Regions, MapRegions.FileName), new MapFileCheckBox(MapFiles.Triggers, MapSounds.FileName), new MapFileCheckBox(MapFiles.Units, MapUnits.FileName), }; foreach (var checkBox in _filesToDecompileCheckBoxes) { checkBox.Size = checkBox.PreferredSize; checkBox.Enabled = false; checkBox.CheckedChanged += (s, e) => { _saveAsButton.Enabled = _filesToDecompileCheckBoxes.Any(checkBox => checkBox.Checked); }; } _archiveInput.TextChanged += OnArchiveInputTextChanged; _archiveInputBrowseButton = new Button { Text = "Browse", }; _archiveInputBrowseButton.Size = _archiveInputBrowseButton.PreferredSize; _archiveInputBrowseButton.Click += (s, e) => { var openFileDialog = new OpenFileDialog { CheckFileExists = false, }; openFileDialog.Filter = string.Join('|', new[] { "Warcraft III map|*.w3m;*.w3x", "All files|*.*", }); var openFileDialogResult = openFileDialog.ShowDialog(); if (openFileDialogResult == DialogResult.OK) { _archiveInput.Text = openFileDialog.FileName; } }; _openCloseArchiveButton.Size = _openCloseArchiveButton.PreferredSize; _openCloseArchiveButton.Click += OnClickOpenCloseMap; _saveAsButton.Click += (s, e) => { var saveFileDialog = new SaveFileDialog { OverwritePrompt = true, CreatePrompt = false, }; var saveFileDialogResult = saveFileDialog.ShowDialog(); if (saveFileDialogResult == DialogResult.OK) { _progressBar.CustomText = "Starting..."; _progressBar.Value = 0; _openCloseArchiveButton.Enabled = false; _saveAsButton.Enabled = false; _autoDetectFilesToDecompileButton.Enabled = false; foreach (var checkBox in _filesToDecompileCheckBoxes) { checkBox.Enabled = false; } _progressBar.Visible = true; _worker.RunWorkerAsync(saveFileDialog.FileName); } }; _autoDetectFilesToDecompileButton.Click += (s, e) => { var filesToDecompile = MapDecompiler.AutoDetectMapFilesToDecompile(_map); foreach (var checkBox in _filesToDecompileCheckBoxes) { checkBox.Checked = filesToDecompile.HasFlag(checkBox.MapFile); } }; _progressBar = new TextProgressBar { Dock = DockStyle.Bottom, Style = ProgressBarStyle.Continuous, VisualMode = TextProgressBar.ProgressBarDisplayMode.CustomText, Visible = false, }; _worker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true, }; _worker.DoWork += DecompileMapBackgroundWork; _worker.ProgressChanged += DecompileMapProgressChanged; _worker.RunWorkerCompleted += DecompileMapCompleted; // Initialize parser JassSyntaxFactory.ParseCompilationUnit(string.Empty); var flowLayout = new FlowLayoutPanel { Dock = DockStyle.Fill, FlowDirection = FlowDirection.TopDown, WrapContents = false, }; var inputArchiveFlowLayout = new FlowLayoutPanel { FlowDirection = FlowDirection.LeftToRight, }; var buttonsFlowLayout = new FlowLayoutPanel { FlowDirection = FlowDirection.LeftToRight, }; var checkBoxesFlowLayout = new FlowLayoutPanel { FlowDirection = FlowDirection.TopDown, WrapContents = false, }; inputArchiveFlowLayout.AddControls(_archiveInput, _archiveInputBrowseButton, _openCloseArchiveButton); buttonsFlowLayout.AddControls(_saveAsButton, _autoDetectFilesToDecompileButton); checkBoxesFlowLayout.AddControls(_filesToDecompileCheckBoxes); checkBoxesFlowLayout.Size = checkBoxesFlowLayout.PreferredSize; flowLayout.AddControls(inputArchiveFlowLayout, buttonsFlowLayout, checkBoxesFlowLayout); form.AddControls(flowLayout, _progressBar); form.SizeChanged += (s, e) => { var width = form.Width; _archiveInput.Width = (width > 360 ? 360 : width) - 10; inputArchiveFlowLayout.Size = inputArchiveFlowLayout.GetPreferredSize(new Size(width, 0)); buttonsFlowLayout.Size = buttonsFlowLayout.GetPreferredSize(new Size(width, 0)); flowLayout.Height = inputArchiveFlowLayout.Margin.Top + inputArchiveFlowLayout.Height + inputArchiveFlowLayout.Margin.Bottom + buttonsFlowLayout.Margin.Top + buttonsFlowLayout.Height + buttonsFlowLayout.Margin.Bottom; }; form.Size = new Size(400, 400); form.MinimumSize = new Size(400, 300); form.FormClosing += (s, e) => { _archive?.Dispose(); _worker?.Dispose(); }; form.ShowDialog(); }
/** * Runs the program */ private void Run(String[] args) { // Verify argument count if (!CheckArguments(args)) { return; } // Retrieve argument values and listfile, and check for existence String operationName = args[0]; String mpqName = args[1]; String listfileName = "listfile.txt"; if (!File.Exists(mpqName)) { Console.WriteLine("MPQ file does not exist: " + mpqName); return; } if (!File.Exists(listfileName)) { Console.WriteLine("Listfile does not exist: " + listfileName); return; } // Determine what operation the user wanted Boolean extract; if (operationName.Equals("ext") || operationName.Equals("exp") || operationName.Equals("export") || operationName.Equals("extract")) { extract = true; } else if (operationName.Equals("imp") || operationName.Equals("import")) { extract = false; } else { Console.WriteLine("Invalid operation: " + operationName); return; } // For every entered file, we either perform import/export using (MpqArchive archive = new MpqArchive(mpqName, FileAccess.ReadWrite)) { // Add listfile.txt as external listfile int retval = archive.AddListFile(listfileName); Console.WriteLine("Added listfile: " + retval + " (0 is ok)"); for (int i = 2; i < args.Length; i++) { if (extract) { Extract(args[i], archive); } else { Import(args[i], archive); } } Console.WriteLine("All desired operations completed. Flushing & closing."); // Close out resources archive.Compact(listfileName); archive.Flush(); archive.Dispose(); } }
private static void Main(string[] args) { _watcher = new FileSystemWatcher(); _watcher.Created += OnWatchedFileEvent; _watcher.Renamed += OnWatchedFileEvent; _watcher.Deleted += OnWatchedFileEvent; var form = new Form(); form.Text = Title; _archiveInput = new TextBox { PlaceholderText = "Input map...", }; _openCloseArchiveButton = new Button { Text = "Open archive", Enabled = false, }; _saveAsButton = new Button { Text = "Save As...", }; _saveAsButton.Size = _saveAsButton.PreferredSize; _saveAsButton.Enabled = false; _targetScriptLanguagesComboBox = new ComboBox { Enabled = false, DropDownStyle = ComboBoxStyle.DropDownList, Width = 120, }; _targetScriptLanguagesComboBox.SelectedIndexChanged += (s, e) => { _targetScriptLanguage = (ScriptLanguage?)_targetScriptLanguagesComboBox.SelectedItem; _saveAsButton.Enabled = _targetScriptLanguage.HasValue; }; _targetScriptLanguagesComboBox.FormattingEnabled = true; _targetScriptLanguagesComboBox.Format += (s, e) => { if (e.ListItem is ScriptLanguage scriptLanguage) { e.Value = scriptLanguage.ToString(); } }; _archiveInput.TextChanged += OnArchiveInputTextChanged; _archiveInputBrowseButton = new Button { Text = "Browse", }; _archiveInputBrowseButton.Size = _archiveInputBrowseButton.PreferredSize; _archiveInputBrowseButton.Click += (s, e) => { var openFileDialog = new OpenFileDialog { CheckFileExists = false, }; openFileDialog.Filter = string.Join('|', new[] { "Warcraft III map|*.w3m;*.w3x", "All files|*.*", }); var openFileDialogResult = openFileDialog.ShowDialog(); if (openFileDialogResult == DialogResult.OK) { _archiveInput.Text = openFileDialog.FileName; } }; _openCloseArchiveButton.Size = _openCloseArchiveButton.PreferredSize; _openCloseArchiveButton.Click += OnClickOpenCloseMap; _saveAsButton.Click += (s, e) => { var saveFileDialog = new SaveFileDialog { OverwritePrompt = true, CreatePrompt = false, }; var saveFileDialogResult = saveFileDialog.ShowDialog(); if (saveFileDialogResult == DialogResult.OK) { _progressStepIndex = 0; _progressBar.CustomText = _progressBarSteps[_progressStepIndex]; _progressBar.Value = 0; _openCloseArchiveButton.Enabled = false; _saveAsButton.Enabled = false; _targetScriptLanguagesComboBox.Enabled = false; _progressBar.Visible = true; _worker.RunWorkerAsync(saveFileDialog.FileName); } }; _progressBar = new TextProgressBar { Dock = DockStyle.Bottom, Style = ProgressBarStyle.Continuous, VisualMode = TextProgressBar.ProgressBarDisplayMode.CustomText, Visible = false, }; _worker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = false, }; _worker.DoWork += TranspileMapBackgroundWork; _worker.ProgressChanged += TranspileMapProgressChanged; _worker.RunWorkerCompleted += TranspileMapCompleted; // Initialize parser JassSyntaxFactory.ParseCompilationUnit(string.Empty); var flowLayout = new FlowLayoutPanel { Dock = DockStyle.Fill, FlowDirection = FlowDirection.TopDown, }; var inputArchiveFlowLayout = new FlowLayoutPanel { FlowDirection = FlowDirection.LeftToRight, }; var buttonsFlowLayout = new FlowLayoutPanel { FlowDirection = FlowDirection.LeftToRight, }; var targetScriptLanguageLabel = new Label { Text = "Transpile to", TextAlign = ContentAlignment.BottomRight, }; inputArchiveFlowLayout.AddControls(_archiveInput, _archiveInputBrowseButton, _openCloseArchiveButton); buttonsFlowLayout.AddControls(_saveAsButton, targetScriptLanguageLabel, _targetScriptLanguagesComboBox); flowLayout.AddControls(inputArchiveFlowLayout, buttonsFlowLayout); form.AddControls(flowLayout, _progressBar); targetScriptLanguageLabel.Size = targetScriptLanguageLabel.PreferredSize; form.SizeChanged += (s, e) => { var width = form.Width; _archiveInput.Width = (width > 360 ? 360 : width) - 10; inputArchiveFlowLayout.Size = inputArchiveFlowLayout.GetPreferredSize(new Size(width, 0)); buttonsFlowLayout.Size = buttonsFlowLayout.GetPreferredSize(new Size(width, 0)); flowLayout.Height = inputArchiveFlowLayout.Margin.Top + inputArchiveFlowLayout.Height + inputArchiveFlowLayout.Margin.Bottom + buttonsFlowLayout.Margin.Top + buttonsFlowLayout.Height + buttonsFlowLayout.Margin.Bottom; }; form.Size = new Size(400, 300); form.MinimumSize = new Size(400, 200); form.FormClosing += (s, e) => { _archive?.Dispose(); _worker?.Dispose(); }; form.ShowDialog(); }