I searched before posting but couldn't find anything close to my issue.
What I need to figure out is how to come with the optimal width and height of picture boxes (with a 4:3 ratio), given the required number of boxes to be displayed, and the available space.
Now, it's not as simple as a just dividing the available space by the number of required boxes, because the available space is not a uniform shape, but rather two rectangles of which size may vary (see this picture, it's the a+b space).
If fact, I have tried starting from there with the following code :
Private Sub LayoutSnapshots()
Dim lTotalSpace As Single, lSnapsize As Single, sXSize As Single, sYSize As Single
Dim I As Integer, J As Integer, X As Integer = 0, Y As Integer = 0, oPic As PictureBox
' bSnaps is the number of picture boxes to be displayed
If stSetting.bSnaps = 0 Then Exit Sub
' oSnaps is a List(Of PictureBoxe) to groupp the actual picture boxes
If oSnaps.Count > 0 Then
For Each oCtrl As PictureBox In oSnaps
Me.Controls.Remove(oCtrl)
Next
End If
oSnaps.Clear()
' Calculating the a+b space shown on the picture
lTotalSpace = ((Me.ClientSize.Height - MenuStrip1.Height) * Me.ClientSize.Width) - ((picPreview.Width + iMargin) * (picPreview.Height + iMargin))
If lTotalSpace < 1 Then
MsgBox("Window is too small. Please adjust one of these settings : Window size, Snapshots count, Live free view size.", MsgBoxStyle.ApplicationModal Or MsgBoxStyle.Exclamation Or MsgBoxStyle.OkOnly)
Exit Sub
End If
'calculating a single picture's size by dividing total space by the number of snaps
lSnapsize = Math.Truncate(lTotalSpace / stSetting.bSnaps)
'Calculating Height and Width, with 4:3 ratio
sXSize = Math.Truncate(Math.Sqrt((4 * lSnapsize) / 3))
sYSize = Math.Truncate(Math.Sqrt((3 * lSnapsize) / 4))
For I = 1 To stSetting.bSnaps
If oPic IsNot Nothing Then oPic = Nothing
oPic = New PictureBox
oPic.BackColor = Color.White
oPic.BorderStyle = BorderStyle.FixedSingle
oPic.Size = New Size(sXSize - 1, sYSize - 1)
oPic.Location = New Point(X * sXSize, (Y * sYSize) + MenuStrip1.Height)
oSnaps.Add(oPic)
' Layed them successively on screen, need to optimize this
If ((X + 2) * sXSize) > (Me.ClientSize.Width) Then
X = 0
Y += 1
Else
X += 1
End If
Next
For Each oCtrl As PictureBox In oSnaps
Me.Controls.Add(oCtrl)
Next
End Sub
But obviously with all the possibilities of windows resizing, I couldn't think of any practical way to optimize it.
I am pretty sure this has to do with "operation research", as I recall we did optimization problems like this back then when I was a student, but I'm not sure how to actually model this or even if it is solvable by linear programming.
I have figured this out. The solution is kind of a "brute force" technique, it doesn't always return the optimum BUT the error is merely a few pixels. I used the code below, it works but it might need further optimization in terms of spacing. I couldn't comment on everything since I have a time pressure right now, but still wanted to share the answer, so just take some time to analyze it :
P.S : Anyone please feel free to add more explanation to the code if you want.