#include "stdafx.h"
enum FinishType {Normal,Clean,Marbled};
void Button(WORD Left, WORD Top, WORD Width, WORD Height, bool Down=false, bool Highlight=false, WORD BorderWidth=8, FinishType Finish=Normal) {
ASSERT(Width >=BorderWidth);
ASSERT(Height>=BorderWidth);
WORD Middle=Height/2;
WORD ReflectionBottom=Middle+(Down ? BorderWidth/2 : BorderWidth);
double DblBorderWidth=2*BorderWidth;
for(WORD x=Width; x--; ) {
double t=(x>DblBorderWidth ? 1 : x/DblBorderWidth);
double Sides=t*t*(3-2*t);
double b=Width;
double a=b-DblBorderWidth;
t=((a==b)||(xDblBorderWidth ? 1 : y/DblBorderWidth);
double vTop=t*t*(3-2*t);
b=Height;
a=b-DblBorderWidth;
t=((a==b)||(y0.5 ? 1 : 2*Border); // Keeps only the dark half and spreads it to full range.
a=BorderWidth;
b=Height-BorderWidth;
double vGradient=((a==b)||(y0 ? ((Down ? 1.5 : 2)-Inner)*Outer : Outer); // Use the Inner Blur for inner glow or to remove the inner gradient depending on 'Down'
// Reflection:
a=Middle-BorderWidth;
b=ReflectionBottom;
double Reflection=Arch*(1-((a==b)||(y0.5 ? 1 : 5*Reflection-1.5)); // Threshold Reflection
Reflection*=1-0.75*(yReflectionBottom ? 1 : double(y-BorderWidth)/(ReflectionBottom-BorderWidth))); // Reflection Gradient starting at 25% white
if(!Down) Reflection=Reflection*Reflection*(3-2*Reflection);
if(Finish==Clean) Button=1-(0.1 + 0.9*(1-Reflection)) * (1-Button);
else{
// Noise:
double xNoise=Left+x/20.0;
double yNoise=Top+y/4.0;
DWORD T, X=Floor(xNoise), Y=Floor(yNoise);
T=(X-1)+57*(Y-1); T=(T<<13)^T; a =2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T=(X+1)+57*(Y-1); T=(T<<13)^T; a+=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T=(X+1)+57*(Y+1); T=(T<<13)^T; a+=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T=(X-1)+57*(Y+1); T=(T<<13)^T; a+=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T=(X-1)+57* Y ; T=(T<<13)^T; b =2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T=(X+1)+57* Y ; T=(T<<13)^T; b+=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T= X +57*(Y-1); T=(T<<13)^T; b+=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T= X +57*(Y+1); T=(T<<13)^T; b+=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T= X +57* Y ; T=(T<<13)^T; t=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
double a1=a/16+b/8+t/4;
++X;
T=(X-1)+57*(Y-1); T=(T<<13)^T; a =2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T=(X+1)+57*(Y-1); T=(T<<13)^T; a+=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T=(X+1)+57*(Y+1); T=(T<<13)^T; a+=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T=(X-1)+57*(Y+1); T=(T<<13)^T; a+=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T=(X-1)+57* Y ; T=(T<<13)^T; b =2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T=(X+1)+57* Y ; T=(T<<13)^T; b+=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T= X +57*(Y-1); T=(T<<13)^T; b+=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T= X +57*(Y+1); T=(T<<13)^T; b+=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T= X +57* Y ; T=(T<<13)^T; t=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
double b1=a/16+b/8+t/4;
--X;
double a2=a1+(b1-a1)*(xNoise-X);
++Y;
T=(X-1)+57*(Y-1); T=(T<<13)^T; a =2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T=(X+1)+57*(Y-1); T=(T<<13)^T; a+=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T=(X+1)+57*(Y+1); T=(T<<13)^T; a+=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T=(X-1)+57*(Y+1); T=(T<<13)^T; a+=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T=(X-1)+57* Y ; T=(T<<13)^T; b =2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T=(X+1)+57* Y ; T=(T<<13)^T; b+=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T= X +57*(Y-1); T=(T<<13)^T; b+=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T= X +57*(Y+1); T=(T<<13)^T; b+=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T= X +57* Y ; T=(T<<13)^T; t=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
a1=a/16+b/8+t/4;
++X;
T=(X-1)+57*(Y-1); T=(T<<13)^T; a =2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T=(X+1)+57*(Y-1); T=(T<<13)^T; a+=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T=(X+1)+57*(Y+1); T=(T<<13)^T; a+=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T=(X-1)+57*(Y+1); T=(T<<13)^T; a+=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T=(X-1)+57* Y ; T=(T<<13)^T; b =2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T=(X+1)+57* Y ; T=(T<<13)^T; b+=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T= X +57*(Y-1); T=(T<<13)^T; b+=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T= X +57*(Y+1); T=(T<<13)^T; b+=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
T= X +57* Y ; T=(T<<13)^T; t=2*(((T*(T*T*15731+789221)+1376312589)&LONG_MAX)/double(LONG_MAX))-1;
b1=a/16+b/8+t/4;
--X; --Y;
double b2=a1+(b1-a1)*(xNoise-X);
t=1-fabs(a2+(b2-a2)*(yNoise-Y));
if(Finish==Marbled) Button*=Reflection*(1-Button) + Button*fabs((1-Button)-(1-fabs(Noise::InterpolatedNoise((Left+x)/20.0, (Top+y)/4.0)))); // Marble Button and surface
else Button=Button<0.5 ? Button*(1-Reflection + 2*Reflection*t) : 1-(1-Reflection + 2*Reflection*(1-t)) * (1-Button); // Normal Noisy Reflection
}
// Highlight:
double Line=gFilters::Ramp(Border, 0.1, 0.3) // Antialiased line around button.
*(1-gFilters::Ramp(Border, 0.3, 0.4))/2;
double Mask=gFilters::Ramp(Border, 0.2, 0.5) // Antialiased line around button used to highlight the button.
*(1-gFilters::Ramp(Border, 0.5, 0.7));
Button=(1-(Mask+Line))*Button + Line/2+(Highlight ? Mask : Mask*(1-vGradient)/2); // Work on the Button Parameter masking out the Line, then adding a little of the line back in.
// Render:
SetLevel(Left+x, Top+y, BYTE(Round(255*Button))); // Turn the parameter into a Greyscale Level.
} }
}