Skip to content

Commit 92fe8c6

Browse files
committed
v0.7 (Demo UI) - partitionTable with validation
1 parent 43b4873 commit 92fe8c6

5 files changed

Lines changed: 159 additions & 22 deletions

File tree

res/langs/en-US.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@
462462
"size": "Size of the partition in megabytes",
463463
"type": "Type of the partition (Primary, Extended, Logical, Recovery, EFI, MSR)"
464464
},
465-
"useRemainingSpace": "Enable to use all remaining disk space for the last partition in the table",
465+
"useRemainingSpace": "Enable to use all remaining disk space for the last partition in the table.\\nDisable to manually specify the size of the last partition.\\nSet the last partition's size to 0 MB to use all remaining space.",
466466
"wipeDisk": "Enable to wipe the entire disk before partitioning. This will delete all data."
467467
},
468468
"generalConfig": {

res/langs/pho-AnhHai.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@
461461
"size": "Kích thước của phân vùng tính bằng megabyte",
462462
"type": "Loại của phân vùng (Primary, Extended, Logical, Recovery, EFI, MSR)"
463463
},
464-
"useRemainingSpace": "Bật để sử dụng toàn bộ không gian còn lại cho phân vùng cuối cùng trong bảng",
464+
"useRemainingSpace": "Bật để sử dụng toàn bộ không gian còn lại cho phân vùng cuối cùng trong bảng.\\nTắt để chỉ định kích thước phân vùng cuối cùng theo cách thủ công.\\nĐặt kích thước phân vùng cuối cùng thành 0 MB để sử dụng toàn bộ không gian còn lại.",
465465
"wipeDisk": "Bật để xóa toàn bộ đĩa trước khi phân vùng. Điều này sẽ xóa tất cả dữ liệu."
466466
},
467467
"generalConfig": {

res/langs/vi-VN.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@
462462
"size": "Kích thước của phân vùng tính bằng megabyte",
463463
"type": "Loại của phân vùng (Primary, Extended, Logical, Recovery, EFI, MSR)"
464464
},
465-
"useRemainingSpace": "Bật để sử dụng toàn bộ không gian còn lại cho phân vùng cuối cùng trong bảng",
465+
"useRemainingSpace": "Bật để sử dụng toàn bộ không gian còn lại cho phân vùng cuối cùng trong bảng.\\nTắt để chỉ định kích thước phân vùng cuối cùng theo cách thủ công.\\nĐặt kích thước phân vùng cuối cùng thành 0 MB để sử dụng toàn bộ không gian còn lại.",
466466
"wipeDisk": "Bật để xóa toàn bộ đĩa trước khi phân vùng. Điều này sẽ xóa tất cả dữ liệu."
467467
},
468468
"generalConfig": {

src/config/DiskPartConfig.cs

Lines changed: 154 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ public class DiskPartConfig
104104
private List<ComboBox> cmbLetters = new List<ComboBox>();
105105
private List<ComboBox> cmbFormats = new List<ComboBox>();
106106
private List<Panel> toggleActives = new List<Panel>();
107+
private List<StatusRing> ringPartitionRows = new List<StatusRing>();
107108

108109
// Use Remaining Space
109110
private Label lblUseRemainingSpace = null!;
@@ -545,8 +546,9 @@ public Panel InitializeUI(Panel parentContainer, EventHandler onConfigChanged,
545546
txtName.Font = theme.GetFont("placeholder");
546547
txtName.ForeColor = theme.GetFontColor("placeholder");
547548
}
549+
// Validate when losing focus
550+
OnPartitionRowChanged(rowIndex);
548551
};
549-
txtName.TextChanged += (s, e) => OnPartitionRowChanged(rowIndex);
550552
txtName.TextChanged += onConfigChanged;
551553
txtNames.Add(txtName);
552554
currentX += colName + columnSpacing;
@@ -616,6 +618,15 @@ public Panel InitializeUI(Panel parentContainer, EventHandler onConfigChanged,
616618
toggleActive.Click += onConfigChanged;
617619
toggleActives.Add(toggleActive);
618620

621+
// Status Ring for the entire row (covers Type to Format)
622+
StatusRing ringRow = new StatusRing();
623+
int ringStartX = cmbType.Left - ui.GetValue("global.statusRing.borderWidth");
624+
int ringEndX = cmbFormat.Right + ui.GetValue("global.statusRing.borderWidth");
625+
ringRow.Location = new Point(ringStartX, rowY - ui.GetValue("global.statusRing.borderWidth"));
626+
ringRow.Size = new Size(ringEndX - ringStartX, ui.GlobalInputHeight + 2 * ui.GetValue("global.statusRing.borderWidth"));
627+
ringRow.Visible = false;
628+
ringPartitionRows.Add(ringRow);
629+
619630
currentY += ui.GlobalInputHeight + ui.GlobalSpacingY;
620631
}
621632

@@ -726,6 +737,7 @@ public Panel InitializeUI(Panel parentContainer, EventHandler onConfigChanged,
726737
pnlDiskPartConfigContent.Controls.Add(cmbLetters[i]);
727738
pnlDiskPartConfigContent.Controls.Add(cmbFormats[i]);
728739
pnlDiskPartConfigContent.Controls.Add(toggleActives[i]);
740+
pnlDiskPartConfigContent.Controls.Add(ringPartitionRows[i]);
729741
}
730742

731743
pnlDiskPartConfigContent.Controls.Add(lblUseRemainingSpace);
@@ -1255,6 +1267,10 @@ private void OnToggleUseRemainingSpace()
12551267
bool newState = !currentState;
12561268
theme.UpdateToggleSwitchState(toggleUseRemainingSpace, newState);
12571269
UseRemainingSpace = newState;
1270+
1271+
// Re-validate all partition rows since size validation depends on UseRemainingSpace
1272+
ValidateAllPartitionRows();
1273+
12581274
_onConfigChanged?.Invoke(this, EventArgs.Empty);
12591275
}
12601276

@@ -1286,6 +1302,18 @@ private void OnPartitionRowChanged(int rowIndex)
12861302
// Update toggle active state for this row
12871303
UpdatePartitionRowToggleState(rowIndex);
12881304

1305+
// Validate this partition row
1306+
ValidatePartitionRow(rowIndex);
1307+
1308+
// Validate all other rows too (in case of duplicate names/letters)
1309+
for (int i = 0; i < partitionRows; i++)
1310+
{
1311+
if (i != rowIndex && HasPartitionRowData(i))
1312+
{
1313+
ValidatePartitionRow(i);
1314+
}
1315+
}
1316+
12891317
// Validate InstallToPartitionID since partition count may have changed
12901318
ValidateInstallToPartitionID();
12911319

@@ -1532,6 +1560,7 @@ private void ResetPartitionTableControls()
15321560
cmbLetters.Clear();
15331561
cmbFormats.Clear();
15341562
toggleActives.Clear();
1563+
ringPartitionRows.Clear();
15351564
lblIDs.Clear();
15361565
}
15371566

@@ -2002,6 +2031,7 @@ public void ValidateAllUIFields()
20022031
ValidateDiskID();
20032032
ValidatePartitionLayout();
20042033
ValidateInstallToPartitionID();
2034+
ValidateAllPartitionRows();
20052035
}
20062036

20072037
/// <summary>
@@ -2069,6 +2099,129 @@ private void ValidateInstallToPartitionID()
20692099
ringInstallToPartitionID.SetStatus(ValidationStatus.Valid);
20702100
}
20712101

2102+
/// <summary>
2103+
/// Validates a specific partition table row and updates its status ring
2104+
/// </summary>
2105+
private void ValidatePartitionRow(int rowIndex)
2106+
{
2107+
if (rowIndex < 0 || rowIndex >= partitionRows) return;
2108+
if (ringPartitionRows[rowIndex] == null) return;
2109+
2110+
// Only validate rows that have data
2111+
if (!HasPartitionRowData(rowIndex))
2112+
{
2113+
ringPartitionRows[rowIndex].Visible = false;
2114+
return;
2115+
}
2116+
2117+
bool isValid = true;
2118+
ThemeManager theme = ThemeManager.Instance;
2119+
2120+
// Validate Type: must have value from list (not "-- Select --")
2121+
if (cmbTypes[rowIndex].SelectedIndex <= 0)
2122+
{
2123+
isValid = false;
2124+
}
2125+
2126+
// Validate Name: must have value and be unique
2127+
if (isValid)
2128+
{
2129+
string name = txtNames[rowIndex].Text;
2130+
if (string.IsNullOrWhiteSpace(name) || IsPlaceholderText(txtNames[rowIndex]))
2131+
{
2132+
isValid = false;
2133+
}
2134+
else
2135+
{
2136+
// Check for duplicates
2137+
for (int i = 0; i < partitionRows; i++)
2138+
{
2139+
if (i != rowIndex && HasPartitionRowData(i))
2140+
{
2141+
string otherName = txtNames[i].Text;
2142+
if (!IsPlaceholderText(txtNames[i]) &&
2143+
name.Equals(otherName, StringComparison.OrdinalIgnoreCase))
2144+
{
2145+
isValid = false;
2146+
break;
2147+
}
2148+
}
2149+
}
2150+
}
2151+
}
2152+
2153+
// Validate Size: only check if UseRemainingSpace is On
2154+
if (isValid && UseRemainingSpace)
2155+
{
2156+
// Find the last partition with data
2157+
int lastPartitionIndex = -1;
2158+
for (int i = partitionRows - 1; i >= 0; i--)
2159+
{
2160+
if (HasPartitionRowData(i))
2161+
{
2162+
lastPartitionIndex = i;
2163+
break;
2164+
}
2165+
}
2166+
2167+
// If this is the last partition, size must be 0
2168+
if (rowIndex == lastPartitionIndex && nudSizes[rowIndex].Value != 0)
2169+
{
2170+
isValid = false;
2171+
}
2172+
}
2173+
2174+
// Validate Letter: if has value, must be unique; empty is acceptable
2175+
if (isValid)
2176+
{
2177+
// Only validate if a letter is selected (not empty/default)
2178+
if (cmbLetters[rowIndex].SelectedIndex > 0)
2179+
{
2180+
// Check for duplicate letters
2181+
string letter = cmbLetters[rowIndex].SelectedItem?.ToString() ?? "";
2182+
for (int i = 0; i < partitionRows; i++)
2183+
{
2184+
if (i != rowIndex && HasPartitionRowData(i))
2185+
{
2186+
string otherLetter = cmbLetters[i].SelectedItem?.ToString() ?? "";
2187+
if (cmbLetters[i].SelectedIndex > 0 && letter == otherLetter)
2188+
{
2189+
isValid = false;
2190+
break;
2191+
}
2192+
}
2193+
}
2194+
}
2195+
}
2196+
2197+
// Validate Format: must have value from list (not "-- Select --")
2198+
if (isValid && cmbFormats[rowIndex].SelectedIndex <= 0)
2199+
{
2200+
isValid = false;
2201+
}
2202+
2203+
// Update status ring
2204+
if (isValid)
2205+
{
2206+
ringPartitionRows[rowIndex].SetStatus(ValidationStatus.Valid);
2207+
}
2208+
else
2209+
{
2210+
ringPartitionRows[rowIndex].SetStatus(ValidationStatus.Invalid);
2211+
}
2212+
}
2213+
2214+
/// <summary>
2215+
/// Validates all partition table rows
2216+
/// </summary>
2217+
private void ValidateAllPartitionRows()
2218+
{
2219+
for (int i = 0; i < partitionRows; i++)
2220+
{
2221+
ValidatePartitionRow(i);
2222+
}
2223+
}
2224+
20722225
/// <summary>
20732226
/// Validates the DiskPart configuration and returns list of validation errors
20742227
/// </summary>

src/lib/template.xml

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
</MetaData>
2424
</InstallFrom>
2525
<InstallTo>
26-
<DiskID>0</DiskID>
27-
<PartitionID>3</PartitionID>
26+
<DiskID>{{DiskID}}</DiskID>
27+
<PartitionID>{{InstallToPartitionID}}</PartitionID>
2828
</InstallTo>
2929
<WillShowUI>Never</WillShowUI>
3030
</OSImage>
@@ -76,22 +76,6 @@
7676
<Path>reg.exe add "HKLM\SYSTEM\Setup\LabConfig" /v "BypassDiskCheck" /t REG_DWORD /d {{BypassDisk}} /f</Path>
7777
<Description>Add BypassDiskCheck</Description>
7878
</RunSynchronousCommand>
79-
<RunSynchronousCommand wcm:action="add">
80-
<Order>7</Order>
81-
<Path>cmd.exe /c "&gt;&gt;"X:\diskpart.txt" (echo:SELECT DISK=0&amp;echo:CLEAN&amp;echo:CONVERT GPT&amp;echo:CREATE PARTITION EFI SIZE=300&amp;echo:FORMAT QUICK FS=FAT32 LABEL=^"System^"&amp;echo:ASSIGN LETTER=S&amp;echo:CREATE PARTITION MSR SIZE=16&amp;echo:CREATE PARTITION PRIMARY)"</Path>
82-
</RunSynchronousCommand>
83-
<RunSynchronousCommand wcm:action="add">
84-
<Order>8</Order>
85-
<Path>cmd.exe /c "&gt;&gt;"X:\diskpart.txt" (echo:SHRINK MINIMUM=1000&amp;echo:FORMAT QUICK FS=NTFS LABEL=^"Windows^"&amp;echo:ASSIGN LETTER=C&amp;echo:CREATE PARTITION PRIMARY&amp;echo:FORMAT QUICK FS=NTFS LABEL=^"Recovery^"&amp;echo:ASSIGN LETTER=R)"</Path>
86-
</RunSynchronousCommand>
87-
<RunSynchronousCommand wcm:action="add">
88-
<Order>9</Order>
89-
<Path>cmd.exe /c "&gt;&gt;"X:\diskpart.txt" (echo:SET ID=^"de94bba4-06d1-4d40-a16a-bfd50179d6ac^"&amp;echo:GPT ATTRIBUTES=0x8000000000000001)"</Path>
90-
</RunSynchronousCommand>
91-
<RunSynchronousCommand wcm:action="add">
92-
<Order>10</Order>
93-
<Path>cmd.exe /c "diskpart.exe /s "X:\diskpart.txt" &gt;&gt;"X:\diskpart.log" || ( type "X:\diskpart.log" &amp; echo diskpart encountered an error. &amp; pause &amp; exit /b 1 )"</Path>
94-
</RunSynchronousCommand>
9579
</RunSynchronous>
9680
</component>
9781
</settings>

0 commit comments

Comments
 (0)