Skip to content

Commit c90daff

Browse files
committed
Merge pull request livecode#3512 from livecodeali/bugfix-16770
[[ Icon Picker ]] Calculate layout in a better way
2 parents 5a917a7 + 37f001e commit c90daff

2 files changed

Lines changed: 88 additions & 41 deletions

File tree

extensions/widgets/iconpicker/iconpicker.lcb

Lines changed: 78 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,13 @@ property selectedIcon get mSelectedElement set setSelectedElement
6363
property showFrameBorder get mFrameBorder set setFrameBorder
6464

6565
constant kIconColor is [0,0,0]
66-
constant kIconPadding is 10
6766

68-
constant kNumRows is 5
69-
constant kNumCols is 5
67+
constant kIconSize is 65
68+
constant kIconPaddingRatio is 0.25
69+
constant kMinCols is 3
70+
constant kMinRows is 3
7071

7172
public handler OnCreate()
72-
73-
put kNumRows into mNumRows
74-
put kNumCols into mNumCols
75-
7673
put iconList() into mDataList
7774
put the empty array into mPaths
7875
put 1 into mFirstDataItem
@@ -119,7 +116,7 @@ private handler drawFrame()
119116
variable tPath as Path
120117
// Draw the frame
121118
if mFrameBorder is true then
122-
put rectangle path of rectangle [0.5,0.5,mViewWidth-0.5,mRowHeight + mViewHeight-0.5] into tPath
119+
put rectangle path of rectangle [0.5,0.5,my width-0.5,my height-0.5] into tPath
123120
set the paint of this canvas to getPaint("frame","stroke")
124121
stroke tPath on this canvas
125122
end if
@@ -128,8 +125,10 @@ end handler
128125
private handler drawTitleBar()
129126
variable tPath as Path
130127

128+
variable tTopRowHeight as Number
129+
put topRowHeight() into tTopRowHeight
131130
// Draw the title line
132-
put line path from point [0.5,mRowHeight] to point [mViewWidth-0.5, mRowHeight] into tPath
131+
put line path from point [0.5,tTopRowHeight] to point [my width-0.5, tTopRowHeight] into tPath
133132
set the paint of this canvas to getPaint("frame","stroke")
134133
stroke tPath on this canvas
135134

@@ -142,14 +141,17 @@ private handler drawTitleBar()
142141
set the bold of tFont to true
143142
set the font of this canvas to tFont
144143

144+
variable tLeft as Number
145+
put kIconSize * kIconPaddingRatio into tLeft
146+
145147
if mSelectedElement is nothing then
146-
put rectangle [0,0,mViewWidth,mRowHeight] into tTextRect
147-
fill text "No icon selected" at center of tTextRect on this canvas
148+
put rectangle [tLeft + mColWidth,0,mViewWidth,tTopRowHeight] into tTextRect
149+
fill text "No icon selected" at left of tTextRect on this canvas
148150
else
149-
put rectangle [mViewWidth / mNumCols,0,mViewWidth,mRowHeight] into tTextRect
150-
fill text mSelectedElement at center of tTextRect on this canvas
151+
put rectangle [tLeft + mColWidth,0,mViewWidth,tTopRowHeight] into tTextRect
152+
fill text mSelectedElement at left of tTextRect on this canvas
151153
variable tIconRect as Rectangle
152-
put rectangle [0, 0, mViewWidth / mNumCols, mRowHeight] into tIconRect
154+
put rectangle [tLeft, kIconSize * kIconPaddingRatio, tLeft + kIconSize, tTopRowHeight - (kIconSize * kIconPaddingRatio)] into tIconRect
153155
if mSelectedElement is not among the keys of mPaths then
154156
put path iconSVGPathFromName(mSelectedElement) into tPath
155157
else
@@ -199,7 +201,7 @@ public handler OnMouseMove() returns nothing
199201

200202
ensureViewTopPosition()
201203
updateFirstDataItem()
202-
updateScrollbar(mViewWidth, mViewHeight, mDataHeight, mViewTopPosition, mRowHeight)
204+
updateScrollbar(mViewWidth, mViewHeight, mDataHeight, mViewTopPosition, topRowHeight())
203205
redraw all
204206
end if
205207
end handler
@@ -262,7 +264,7 @@ public handler OnMouseScroll(in pDeltaX as Real, in pDeltaY as Real) returns not
262264
end if
263265

264266
updateFirstDataItem()
265-
updateScrollbar(mViewWidth, mViewHeight, mDataHeight, mViewTopPosition, mRowHeight)
267+
updateScrollbar(mViewWidth, mViewHeight, mDataHeight, mViewTopPosition, topRowHeight())
266268

267269
redraw all
268270
end if
@@ -278,20 +280,20 @@ private handler indexToSectorRect(in pIndex as Integer) returns Rectangle
278280

279281
variable tRow as Integer
280282
variable tCol as Integer
281-
put the floor of ((pIndex - 1) / mNumRows) + 1 into tRow
283+
put the floor of ((pIndex - 1) / mNumCols) + 1 into tRow
282284
put pIndex wrap mNumCols into tCol
283285

284286
put (tCol - 1) * mViewWidth / mNumCols into tLeft
285287
put tCol * mViewWidth / mNumCols into tRight
286-
put (tRow - 1) * mViewHeight / mNumRows + mRowHeight into tTop
287-
put tRow * mViewHeight / mNumRows + mRowHeight into tBottom
288+
put (tRow - 1) * mViewHeight / mNumRows + topRowHeight() into tTop
289+
put tRow * mViewHeight / mNumRows + topRowHeight() into tBottom
288290

289291
return rectangle [tLeft, tTop, tRight, tBottom]
290292
end handler
291293

292294
private handler mousePosToIconNumber(in pMouse as Point) returns Integer
293295
variable tRow as Integer
294-
put the floor of ((the y of pMouse - mRowHeight) / mRowHeight) + 1 into tRow
296+
put the floor of ((the y of pMouse - topRowHeight()) / mRowHeight) + 1 into tRow
295297

296298
variable tCol as Integer
297299
put the floor of (the x of pMouse / mColWidth) + 1 into tCol
@@ -309,7 +311,7 @@ end handler
309311

310312
public handler OnGeometryChanged()
311313
// Only resizing necessitates a recalculation
312-
if my height is not mViewHeight + mRowHeight or my width is not mViewWidth then
314+
if my height is not mViewHeight + topRowHeight() or my width is not mViewWidth + kScrollbarWidth then
313315
variable tFirstDataItem as Number
314316
put mFirstDataItem into tFirstDataItem
315317
updateParameters()
@@ -333,44 +335,69 @@ private handler ensureViewTopPosition()
333335
end handler
334336

335337
private handler updateFirstDataItem()
336-
put the floor of (mViewTopPosition / mRowHeight) * mNumCols + 1 into mFirstDataItem
338+
put the floor of ((mViewTopPosition - topRowHeight()) / mRowHeight) * (mNumRows) into mFirstDataItem
337339
if mFirstDataItem < 1 then
338340
put 1 into mFirstDataItem
339341
end if
340342
end handler
341343

344+
private handler topRowHeight() returns Number
345+
return kIconSize * (1 + kIconPaddingRatio * 2)
346+
end handler
347+
348+
private handler minContentHeight() returns Number
349+
return kIconSize * (kMinRows + (kMinRows + 1) * kIconPaddingRatio)
350+
end handler
351+
352+
private handler minContentWidth() returns Number
353+
return kIconSize * (kMinCols + (kMinCols + 1) * kIconPaddingRatio)
354+
end handler
355+
342356
private handler updateParameters() returns nothing
343-
put my height into mViewHeight
357+
variable tHeight as Number
358+
put my height into tHeight
344359

345-
if mViewHeight < 250 then
346-
put 250 into mViewHeight
360+
variable tMinHeight
361+
put minContentHeight() + topRowHeight() into tMinHeight
362+
if tHeight < tMinHeight then
363+
put tMinHeight into tHeight
347364
end if
348365

349-
put my width into mViewWidth
366+
variable tWidth as Number
367+
put my width into tWidth
368+
369+
variable tMinWidth
370+
put minContentWidth() + 2 * kScrollbarWidth into tMinWidth
350371

351-
if mViewWidth < 200 then
352-
put 200 into mViewWidth
372+
if tWidth < tMinWidth then
373+
put tMinWidth into tWidth
353374
end if
354375

355-
put mViewHeight / (mNumRows + 1) into mRowHeight
356-
subtract mRowHeight from mViewHeight
376+
put (tHeight - topRowHeight()) into mViewHeight
377+
put the floor of (mViewHeight / (kIconSize * (1 + kIconPaddingRatio))) into mNumRows
378+
379+
put tWidth - kScrollbarWidth into mViewWidth
380+
put the floor of (mViewWidth / (kIconSize * (1 + kIconPaddingRatio))) into mNumCols
381+
382+
put mViewHeight / mNumRows into mRowHeight
357383
put mViewWidth / mNumCols into mColWidth
384+
358385

359386
put the number of elements in mDataList into mDataCount
360-
put mRowHeight * the ceiling of (mDataCount / mNumCols) into mDataHeight
387+
put mRowHeight * the ceiling of (mDataCount / mNumRows) into mDataHeight
361388

362389
put mDataHeight - mViewHeight into mDataTravel
363390
if mDataTravel < 0 then
364391
put 0 into mDataTravel
365392
end if
366393

367-
updateIconRects(mRowHeight)
394+
updateIconRects(topRowHeight())
368395

369396
ensureViewTopPosition()
370397
updateFirstDataItem()
371398

372399
// Calculate scrollbar dimensions
373-
updateScrollbar(mViewWidth, mViewHeight, mDataHeight, mViewTopPosition, mRowHeight)
400+
updateScrollbar(mViewWidth, mViewHeight, mDataHeight, mViewTopPosition, topRowHeight())
374401

375402
put false into mRecalculate
376403
end handler
@@ -388,11 +415,11 @@ private handler updateIconRects(in pTopOffset as Real)
388415
variable tCol as Integer
389416
repeat with tRow from 1 up to mNumRows
390417
repeat with tCol from 1 up to mNumCols
391-
put (tCol - 1) * mViewWidth / mNumCols + kIconPadding into tLeft
392-
put tCol * mViewWidth / mNumCols - kIconPadding into tRight
418+
put (tCol - 1) * mViewWidth / mNumCols + kIconSize * kIconPaddingRatio into tLeft
419+
put tCol * mViewWidth / mNumCols - kIconSize * kIconPaddingRatio into tRight
393420

394-
put (tRow - 1) * mViewHeight / mNumRows + kIconPadding + pTopOffset into tTop
395-
put tRow * mViewHeight / mNumRows - kIconPadding + pTopOffset into tBottom
421+
put (tRow - 1) * mViewHeight / mNumRows + kIconSize * kIconPaddingRatio + pTopOffset into tTop
422+
put tRow * mViewHeight / mNumRows - kIconSize * kIconPaddingRatio + pTopOffset into tBottom
396423

397424
push rectangle [tLeft, tTop, tRight, tBottom] onto tRects
398425
end repeat
@@ -512,8 +539,18 @@ end handler
512539
--
513540
--------------------------------------------------------------------------------
514541

542+
constant kPreferredCols is 5
543+
constant kPreferredRows is 5
544+
515545
public handler getPreferredSize() returns List
516-
return [150 * mNumCols, 150 * mNumRows + mRowHeight]
546+
variable tWidth
547+
put kIconSize * kPreferredCols * (1 + kIconPaddingRatio) into tWidth
548+
add 2 * kScrollbarWidth to tWidth
549+
550+
variable tHeight
551+
put kIconSize * kPreferredRows * (1 + kIconPaddingRatio) into tHeight
552+
add topRowHeight() to tHeight
553+
return [tWidth, tHeight]
517554
end handler
518555

519556
public handler setFrameBorder(in pValue as Boolean)
@@ -540,7 +577,7 @@ end handler
540577
private handler scrollToIndex(in pIndex as Number)
541578
put the floor of ((pIndex - 1) / mNumCols) * mRowHeight into mViewTopPosition
542579
updateFirstDataItem()
543-
updateScrollbar(mViewWidth, mViewHeight, mDataHeight, mViewTopPosition, mRowHeight)
580+
updateScrollbar(mViewWidth, mViewHeight, mDataHeight, mViewTopPosition, topRowHeight())
544581
put true into mRecalculate
545582
redraw all
546583
end handler
@@ -632,7 +669,7 @@ private handler updateScrollbar(in pViewWidth as Real, in pViewHeight as Real, i
632669
put scrollbarYFromView(pViewHeight, pDataHeight, pTopPosition) into tScrollbarY
633670

634671
variable tRect as Rectangle
635-
put rectangle [pViewWidth - 10, pViewOffset, pViewWidth - 10 + kScrollbarWidth, pViewOffset + mScrollbarHeight] into tRect
672+
put rectangle [pViewWidth - kScrollbarWidth, pViewOffset, pViewWidth, pViewOffset + mScrollbarHeight] into tRect
636673
put rounded rectangle path of tRect with radius 3 into mScrollbarPath
637674

638675
put 0 into mScrollbarY
@@ -681,4 +718,4 @@ private handler scrollRatio(in pViewHeight as Real)
681718
return mScrollbarY / tScrollbarSpace
682719
end handler
683720

684-
end widget
721+
end widget
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Layout calculations
2+
3+
The icon size of the icon picker is now fixed at 65 pixels. The number
4+
of rows/columns therefore now depends on the height/width. The widget
5+
will clip instead of reducing the number of rows or columns to below 3.
6+
7+
The `preferredSize` of the icon picker is now calculated as the minimum
8+
size to display 5 rows and columns of icons in the view.
9+
10+
# [16770] Popup Icon Picker at reasonable size

0 commit comments

Comments
 (0)