vb.net - Optimal sizes to display X picture boxes in an given space -
i searched before posting couldn't find close issue.
what need figure out how come optimal width , height of picture boxes (with 4:3 ratio), given required number of boxes displayed, , available space.
now, it's not simple dividing available space number of required boxes, because available space not uniform shape, rather 2 rectangles of size may vary (see picture, it's a+b space).
if fact, have tried starting there following code :
private sub layoutsnapshots() dim ltotalspace single, lsnapsize single, sxsize single, sysize single dim integer, j integer, x integer = 0, y integer = 0, opic picturebox ' bsnaps number of picture boxes displayed if stsetting.bsnaps = 0 exit sub ' osnaps list(of pictureboxe) groupp actual picture boxes if osnaps.count > 0 each octrl picturebox in osnaps me.controls.remove(octrl) next end if osnaps.clear() ' calculating a+b space shown on picture ltotalspace = ((me.clientsize.height - menustrip1.height) * me.clientsize.width) - ((picpreview.width + imargin) * (picpreview.height + imargin)) if ltotalspace < 1 msgbox("window small. please adjust 1 of these settings : window size, snapshots count, live free view size.", msgboxstyle.applicationmodal or msgboxstyle.exclamation or msgboxstyle.okonly) exit sub end if 'calculating single picture's size dividing total space number of snaps lsnapsize = math.truncate(ltotalspace / stsetting.bsnaps) 'calculating height , width, 4:3 ratio sxsize = math.truncate(math.sqrt((4 * lsnapsize) / 3)) sysize = math.truncate(math.sqrt((3 * lsnapsize) / 4)) = 1 stsetting.bsnaps if opic isnot nothing 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 optimize if ((x + 2) * sxsize) > (me.clientsize.width) x = 0 y += 1 else x += 1 end if next each octrl picturebox in osnaps me.controls.add(octrl) next end sub
but possibilities of windows resizing, couldn't think of practical way optimize it.
i pretty sure has "operation research", recall did optimization problems when student, i'm not sure how model or if solvable linear programming.
i have figured out. solution kind of "brute force" technique, doesn't return optimum error merely few pixels. used code below, works might need further optimization in terms of spacing. couldn't comment on since have time pressure right now, still wanted share answer, take time analyze :
private sub layoutsnapshots() dim sa single, sb single, stotal single, ssnap single, swidth single, sheight single dim icount integer = stsetting.bsnaps, ifit integer, ix integer, iy integer, iyg integer, integer dim ra rectangle, rb rectangle, opic picturebox, lploc new list(of point), ploc new point static bwarn boolean dim gpic graphics ' bsnaps number of picture boxes displayed if stsetting.bsnaps = 0 exit sub ' if controls on form, remove them , start form scratch if osnaps.count > 0 each octrl picturebox in osnaps me.controls.remove(octrl) next end if ' osnaps list(of picturebox) grooping picture boxes. clear osnaps.clear() 'sa, sb sizes of spaces , b respectively sa = (me.clientsize.width * (me.clientsize.height - (menustrip1.height + picpreview.height + imargin))) sb = ((me.clientsize.width - (picpreview.width + imargin)) * (picpreview.height + imargin)) ' total free space stotal = sa + sb ' condition important. ensures there @ least 1 solution ' before entering loops bellow. otherwise might stuck in infinite loop if (stotal < (stsetting.bsnaps * stsetting.bsnaps)) ' bwarn static boolean. since sub called form_resize event, ' want warn user once when there no space. ' otherwise becomes annoying. if bwarn msgbox("window small. please adjust 1 of these settings : window size, snapshots count, live free view size.", msgboxstyle.applicationmodal or msgboxstyle.exclamation or msgboxstyle.okonly) bwarn = false exit sub end if bwarn = true me.usewaitcursor = true 'ra, rb bounding rectangles of spaces , b respectively ra = new rectangle(0, menustrip1.height, me.clientsize.width, me.clientsize.height - (menustrip1.height + picpreview.height + imargin)) rb = new rectangle(0, picpreview.top, me.clientsize.width - (picpreview.width + imargin), picpreview.height + imargin) ' single box's size ssnap = math.truncate(stotal / icount) ' width , height 4:3 aspect ratio. swidth = math.truncate(math.sqrt((4 * ssnap) / 3)) sheight = math.truncate(math.sqrt((3 * ssnap) / 4)) ' ifit keeps track of how many boxes fit in total ifit = 0 iyg = 0 lploc.clear() ' bit long explain next block of code , have deadline meet ' i'll comenting on later ix = 0 iy = 0 while (ra.height >= ((sheight * (iy + 1)) + 1)) if (((ix + 1) * swidth) + 1) <= ra.width ifit += 1 lploc.add(new point(ra.x + ((ix * swidth) + 1), ra.y + ((iyg * sheight) + 1))) ix += 1 else ix = 0 iy += 1 iyg += 1 end if loop 'add unused space b. rb.height = rb.height + (ra.height - ((iyg * sheight) + 1)) ix = 0 iy = 0 while (rb.height >= ((sheight * (iy + 1)) + 1)) if (((ix + 1) * swidth) + 1) <= rb.width ifit += 1 lploc.add(new point(rb.x + ((ix * swidth) + 1), ra.y + ((iyg * sheight) + 1))) ix += 1 else ix = 0 iy += 1 iyg += 1 end if loop application.doevents() icount += 1 loop while ifit < stsetting.bsnaps ' add controls form. lay them 1 next each other. ix = 0 iy = 0 = 1 stsetting.bsnaps if opic isnot nothing opic = nothing opic = new picturebox opic.backcolor = color.cyan opic.borderstyle = borderstyle.fixedsingle opic.size = new size(swidth - 1, sheight - 1) opic.location = lploc(i - 1) ' debugging, displays index of each box inside it. opic.image = new bitmap(opic.width, opic.height) gpic = graphics.fromimage(opic.image) gpic.drawstring(i, new font("arial", 10, fontstyle.regular), brushes.red, new point(0, 0)) osnaps.add(opic) me.controls.add(osnaps.last) next 'catch ex exception 'finally me.usewaitcursor = false 'end try end sub
p.s : please feel free add more explanation code if want.
Comments
Post a Comment