Skip to content

Commit 45aae77

Browse files
committed
add grid based layout for onsetslice
1 parent 7ae1528 commit 45aae77

File tree

3 files changed

+66
-21
lines changed

3 files changed

+66
-21
lines changed

ReacomaExtension/Components/ReacomaSegmented.cpp

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,28 @@ namespace iplug {
44
namespace igraphics {
55
ReacomaSegmented::ReacomaSegmented(
66
const IRECT &bounds, int paramIdx,
7-
const std::vector<std::string> &segmentLabels, const ReacomaTheme &theme)
8-
: IControl(bounds, paramIdx), mSegmentLabels(segmentLabels), mTheme(theme) {
7+
const std::vector<std::string> &segmentLabels, const ReacomaTheme &theme,
8+
int itemsPerRow)
9+
: IControl(bounds, paramIdx), mSegmentLabels(segmentLabels), mTheme(theme),
10+
mItemsPerRow(itemsPerRow) {
911
CalculateSegmentRects();
1012
}
1113

1214
void ReacomaSegmented::CalculateSegmentRects() {
1315
mSegmentRects.clear();
1416
if (mSegmentLabels.empty())
1517
return;
16-
for (size_t i = 0; i < mSegmentLabels.size(); ++i) {
17-
mSegmentRects.push_back(
18-
mRECT.SubRectHorizontal(mSegmentLabels.size(), i));
18+
19+
int numItems = static_cast<int>(mSegmentLabels.size());
20+
int nCols = mItemsPerRow > 0 ? mItemsPerRow : numItems;
21+
int nRows = (numItems + nCols - 1) / nCols;
22+
23+
for (int i = 0; i < numItems; ++i) {
24+
int row = i / nCols;
25+
int col = i % nCols;
26+
27+
IRECT rowRect = mRECT.SubRectVertical(nRows, row);
28+
mSegmentRects.push_back(rowRect.SubRectHorizontal(nCols, col));
1929
}
2030
}
2131

@@ -52,10 +62,20 @@ void ReacomaSegmented::Draw(IGraphics &g) {
5262

5363
// 2. Draw the main border and dividers over everything for a clean look
5464
g.DrawRoundRect(mTheme.border, mRECT, mTheme.cornerRadius);
55-
for (size_t i = 0; i < mSegmentLabels.size() - 1; ++i) {
56-
const IRECT &segmentRect = mSegmentRects[i];
57-
g.DrawLine(mTheme.border, segmentRect.R, segmentRect.T, segmentRect.R,
58-
segmentRect.B);
65+
66+
if (mItemsPerRow <= 0 ||
67+
mSegmentLabels.size() <= static_cast<size_t>(mItemsPerRow)) {
68+
// Single row - use vertical dividers
69+
for (size_t i = 0; i < mSegmentLabels.size() - 1; ++i) {
70+
const IRECT &segmentRect = mSegmentRects[i];
71+
g.DrawLine(mTheme.border, segmentRect.R, segmentRect.T,
72+
segmentRect.R, segmentRect.B);
73+
}
74+
} else {
75+
// Multi-row - draw borders for each segment to form a grid
76+
for (size_t i = 0; i < mSegmentLabels.size(); ++i) {
77+
g.DrawRect(mTheme.border, mSegmentRects[i]);
78+
}
5979
}
6080

6181
// 3. Draw the text labels on top
@@ -103,9 +123,11 @@ int ReacomaSegmented::GetSegmentForPos(float x, float y) {
103123
if (mSegmentLabels.empty() || !mRECT.Contains(x, y))
104124
return -1;
105125

106-
float segmentWidth = mRECT.W() / mSegmentLabels.size();
107-
int segmentIdx = static_cast<int>((x - mRECT.L) / segmentWidth);
108-
return std::clamp(segmentIdx, 0, (int)mSegmentLabels.size() - 1);
126+
for (int i = 0; i < static_cast<int>(mSegmentRects.size()); ++i) {
127+
if (mSegmentRects[i].Contains(x, y))
128+
return i;
129+
}
130+
return -1;
109131
}
110132
} // namespace igraphics
111133
} // namespace iplug

ReacomaExtension/Components/ReacomaSegmented.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class ReacomaSegmented : public IControl {
1111
public:
1212
ReacomaSegmented(const IRECT &bounds, int paramIdx,
1313
const std::vector<std::string> &segmentLabels,
14-
const ReacomaTheme &theme);
14+
const ReacomaTheme &theme, int itemsPerRow = 0);
1515
virtual ~ReacomaSegmented() = default;
1616

1717
void Draw(IGraphics &g) override;
@@ -25,6 +25,7 @@ class ReacomaSegmented : public IControl {
2525
ReacomaTheme mTheme;
2626

2727
int mHoveredSegment = -1;
28+
int mItemsPerRow = 0;
2829

2930
void CalculateSegmentRects();
3031
int GetSegmentForPos(float x, float y);

ReacomaExtension/ReacomaExtension.cpp

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -255,25 +255,47 @@ void ReacomaExtension::SetupAlgorithmParameters(IGraphics *pGraphics,
255255

256256
int globalParamIdx = mCurrentActiveAlgorithmPtr->GetGlobalParamIdx(i);
257257
IParam *pParam = GetParam(globalParamIdx);
258-
IRECT controlCellRect =
259-
currentLayoutBounds.GetFromTop(theme.controlVisualHeight);
260258

261259
if (pParam->Type() == IParam::kTypeDouble ||
262260
pParam->Type() == IParam::kTypeInt) {
261+
IRECT controlCellRect =
262+
currentLayoutBounds.GetFromTop(theme.controlVisualHeight);
263263
pGraphics->AttachControl(new ReacomaParamTextControl(
264264
controlCellRect.GetVPadded(-5.f), globalParamIdx, theme));
265+
currentLayoutBounds.T = controlCellRect.B + theme.verticalSpacing;
265266
} else if (pParam->Type() == IParam::kTypeEnum &&
266267
pParam->GetMax() > 0) {
267268
std::vector<std::string> labels;
268-
for (int val = 0; val <= pParam->GetMax(); ++val)
269+
int numItems = pParam->GetMax() + 1;
270+
for (int val = 0; val < numItems; ++val)
269271
labels.push_back(pParam->GetDisplayTextAtIdx(val));
270272

271-
if (!labels.empty())
272-
pGraphics->AttachControl(new ReacomaSegmented(
273-
controlCellRect, globalParamIdx, labels, theme));
274-
}
273+
if (!labels.empty()) {
274+
int itemsPerRow = 0;
275+
int numRows = 1;
276+
277+
// If more than 4 items, wrap them to 3 per row to give more
278+
// space for text
279+
if (numItems > 4) {
280+
itemsPerRow = 3;
281+
numRows = (numItems + itemsPerRow - 1) / itemsPerRow;
282+
}
283+
284+
float height = theme.controlVisualHeight * numRows;
285+
286+
if (currentLayoutBounds.H() < height)
287+
break;
288+
289+
IRECT controlCellRect = currentLayoutBounds.GetFromTop(height);
290+
291+
pGraphics->AttachControl(
292+
new ReacomaSegmented(controlCellRect, globalParamIdx,
293+
labels, theme, itemsPerRow));
275294

276-
currentLayoutBounds.T = controlCellRect.B + theme.verticalSpacing;
295+
currentLayoutBounds.T =
296+
controlCellRect.B + theme.verticalSpacing;
297+
}
298+
}
277299
}
278300
}
279301

0 commit comments

Comments
 (0)