22
33#include < algorithm>
44#include < array>
5+ #include < chrono>
56#include < cmath>
67#include < cstdio>
78#include < string>
@@ -18,6 +19,7 @@ enum ParameterIndex : uint32_t {
1819 kParamFadeDurMax ,
1920 kParamBias ,
2021 kParamMute ,
22+ kParamSeed ,
2123 kParameterCount
2224};
2325
@@ -123,6 +125,9 @@ class PMixUI : public UI
123125 values_[index] = value;
124126 repaint ();
125127 }
128+ if (index == kParamSeed && value == 0 .0f ) {
129+ triggerNewSeed ();
130+ }
126131 }
127132
128133 void onNanoDisplay () override
@@ -162,6 +167,11 @@ class PMixUI : public UI
162167 return true ;
163168 }
164169
170+ if (seedButtonRect_.contains (x, y)) {
171+ triggerNewSeed ();
172+ return true ;
173+ }
174+
165175 for (std::size_t i = 0 ; i < sliderRects_.size (); ++i) {
166176 if (sliderRects_[i].contains (x, y)) {
167177 draggingSlider_ = static_cast <int >(i);
@@ -202,6 +212,7 @@ class PMixUI : public UI
202212 std::array<float , kParameterCount > values_ {};
203213 std::array<Rect, kSliders .size()> sliderRects_ {};
204214 Rect muteButtonRect_ {};
215+ Rect seedButtonRect_ {};
205216 int draggingSlider_ = -1 ;
206217
207218 void drawBackground (const float width, const float height)
@@ -260,11 +271,14 @@ class PMixUI : public UI
260271
261272 const float innerX = x + 22 .0f ;
262273 const float buttonY = y + 52 .0f ;
263- muteButtonRect_ = {innerX, buttonY, w - 44 .0f , 40 .0f };
274+ const float innerW = w - 44 .0f ;
275+ const float halfW = (innerW - 12 .0f ) * 0 .5f ;
276+ muteButtonRect_ = {innerX, buttonY, halfW, 40 .0f };
277+ seedButtonRect_ = {innerX + halfW + 12 .0f , buttonY, halfW, 40 .0f };
264278 drawToggleButton (kMuteButton , muteButtonRect_, values_[kParamMute ] >= 0 .5f );
279+ drawSeedButton (seedButtonRect_);
265280
266281 const float innerY = buttonY + 62 .0f ;
267- const float innerW = w - 44 .0f ;
268282 const float rowGap = 18 .0f ;
269283 const float rowH = 56 .0f ;
270284 const float colGap = 18 .0f ;
@@ -499,6 +513,47 @@ class PMixUI : public UI
499513 commitParameter (kParamMute , next);
500514 }
501515
516+ void triggerNewSeed ()
517+ {
518+ using Clock = std::chrono::high_resolution_clock;
519+ const auto ticks = static_cast <uint64_t >(Clock::now ().time_since_epoch ().count ());
520+ auto s = static_cast <uint32_t >(ticks ^ (ticks >> 32 ));
521+ if (s == 0u ) s = 0xDEADBEEFu ;
522+ float newSeed = static_cast <float >(s) / static_cast <float >(0xFFFFFFFFu );
523+ if (newSeed <= 0 .0f ) newSeed = 1 .0f / static_cast <float >(0xFFFFFFFFu );
524+ commitParameter (kParamSeed , newSeed);
525+ }
526+
527+ void drawSeedButton (const Rect& r)
528+ {
529+ beginPath ();
530+ roundedRect (r.x , r.y , r.w , r.h , 8 .0f );
531+ fillColor (28 , 48 , 68 , 255 );
532+ fill ();
533+ closePath ();
534+
535+ beginPath ();
536+ roundedRect (r.x , r.y , r.w , r.h , 8 .0f );
537+ strokeColor (72 , 118 , 162 , 255 );
538+ strokeWidth (1 .0f );
539+ stroke ();
540+ closePath ();
541+
542+ fontSize (13 .0f );
543+ textAlign (ALIGN_LEFT | ALIGN_MIDDLE );
544+ fillColor (200 , 220 , 240 , 255 );
545+ text (r.x + 14 .0f , r.y + r.h * 0 .5f + 1 .0f , " Seed" , nullptr );
546+
547+ const auto s = static_cast <uint32_t >(values_[kParamSeed ] * static_cast <float >(0xFFFFFFFFu ));
548+ char buf[12 ];
549+ std::snprintf (buf, sizeof (buf), " #%06X" , s & 0x00FFFFFFu );
550+
551+ fontSize (11 .0f );
552+ textAlign (ALIGN_RIGHT | ALIGN_MIDDLE );
553+ fillColor (90 , 155 , 215 , 255 );
554+ text (r.x + r.w - 14 .0f , r.y + r.h * 0 .5f + 1 .0f , buf, nullptr );
555+ }
556+
502557 void commitParameter (uint32_t index, float value)
503558 {
504559 editParameter (index, true );
0 commit comments