/***
* Dial Class by Yahir
* Full Guide and Attribute list at: https://www.yahir360.com/gui
*
* Class for creating GUI Dials
* Version 2
* February 2019
***/
class Dial {
final float startAngle; // Angle used to align dial correctly
boolean showValue; // Toggle displaying numerical value within dial
boolean showValueMarkers; // Toggle displaying the value markers
color dialActiveColor; // Color on active (mouse over)
color dialColor; // Color of the main dial
color nameTextColor; // Color of the dial name text
color valueMarkerColor; // Color of the value marker when value is less than value marker (fixed marker)
color valueMarkerFillColor; // Color of value marker when value is greater or equal to value marker (active)
color valueTextColor; // Color of the dial value text
float dialMin; // Minimum value of the dial range
float dialMax; // Maximum value of the dial range
float dialX; // The x position of the dial
float dialY; // The y position of the dial
float value; // The current value of the dial
int dialSize; // The diameter size of the dial
int dialValueLineSize; // The line marker on the dial representing the value size
int markerDiam; // The diameter size of the markers from center of dial
int markerSize; // The diameter size of the marker ellipses
int nameClearance; // The gap from the dial name text to the dial edge
int nameTextSize; // Text size of the dial name being displayed
int numValueMarkers; // The number of markers around dial to track value
int roundValTo; // Round value to dicimal place (-1 = whole number)
int valueTextSize; // Text size of the value being displayed
String dialName; // The name describing dial
String theme; // The color theme of the dial
/**
* Constructor 1 used for setting dial name, position, and value to be adjusted
*
* @PARAM sName: String name of the dial
* @PARAM sX: float value of the dial x position
* @PARAM sY: float value of the dial y position
* @PARAM sValue: float value of the variable being adjusted by dial
**/
Dial(String sName, float sX, float sY, float sValue) {
setDialName(sName);
setXPos(sX);
setYPos(sY);
setDialValue(sValue);
setShowValue(true);
setShowValueMarkers(true);
setDialMin(0);
setDialMax(100);
setDialSize(80);
setMarkerDiam(getDialSize() - 30);
setMarkerSize(6);
setNumValueMarkers(10);
startAngle = 145;
dialValueLineSize = 10;
setTheme("DARK");
nameClearance = 15;
nameTextSize = 14;
valueTextSize = 20;
roundValTo = -1;
}
/**
* Constructor 2 used for setting dial name, position, value to be adjusted, min and max values
*
* @PARAM sName: String name of the dial
* @PARAM sX: Integer value of the dial x position
* @PARAM sY: Integer value of the dial y position
* @PARAM sValue: Float value of the variable being manipulated by dial
* @PARAM sMin: Integer value of the dial minimum value
* @PARAM sMax: Integer value of the dial maximum value
**/
Dial(String sName, float sX, float sY, float sValue, int sMin, int sMax) {
setDialName(sName);
setXPos(sX);
setYPos(sY);
setDialValue(sValue);
setDialMin(sMin);
setDialMax(sMax);
setShowValue(true);
setShowValueMarkers(true);
setDialSize(80);
setMarkerDiam(getDialSize() - 30);
setMarkerSize(6);
setNumValueMarkers(10);
startAngle = 145;
dialValueLineSize = 10;
setTheme("DARK");
nameClearance = 10;
nameTextSize = 14;
valueTextSize = 20;
roundValTo = -1;
}
/**
* Setter methods
**/
void setShowValue(boolean tShow) {
showValue = tShow;
}
void setShowValueMarkers(boolean tShow) {
showValueMarkers = tShow;
}
void setDialMin(float tMin) {
dialMin = tMin;
}
void setDialMax(float tMax) {
dialMax = tMax;
}
void setXPos(float tX) {
dialX = tX;
}
void setYPos(float tY) {
dialY = tY;
}
void setDialValue(float tValue) {
value = tValue;
}
void setDialSize(int tSize) {
dialSize = tSize;
}
void setMarkerDiam(int tSize) {
markerDiam = tSize;
}
void setMarkerSize(int tSize) {
markerSize = tSize;
}
void setNumValueMarkers(int tNum) {
numValueMarkers = tNum;
}
void setDialName(String tName) {
dialName = tName;
}
void setTheme(String sTheme) {
theme = sTheme;
switch (theme) {
case "LIGHT":
dialActiveColor = color(225, 235, 240);
dialColor = color(207, 216, 220);
nameTextColor = color(207, 216, 220);
valueMarkerColor = color(69, 90, 100);
valueMarkerFillColor = color(207, 216, 220);
valueTextColor = color(69, 90, 100);
break;
case "DARK":
default:
dialActiveColor = color(96, 125, 139);
dialColor = color(69, 90, 100);
nameTextColor = color(69, 90, 100);
valueMarkerColor = color(207, 216, 220);
valueMarkerFillColor = color(69, 90, 100);
valueTextColor = color(207, 216, 220);
break;
}
}
/**
* Getter methods
**/
boolean getShowValue() {
return showValue;
}
boolean getShowValueMarkers() {
return showValueMarkers;
}
float getDialMin() {
return dialMin;
}
float getDialMax() {
return dialMax;
}
float getXPos() {
return dialX;
}
float getYPos() {
return dialY;
}
float getDialValue() {
return value;
}
int getDialSize() {
return dialSize;
}
int getMarkerDiam() {
return markerDiam;
}
int getMarkerSize() {
return markerSize;
}
int getNumValueMarkers() {
return numValueMarkers;
}
String getDialName() {
return dialName;
}
String getTheme() {
return theme;
}
/**
* Method for displaying the dial and all features
** This method should be called within the draw method of the sketch
**/
void display() {
preShow();
showDial();
showValueMarkers();
showText();
postShow();
}
/**
* Method for updating the dial value
** This method should be placed withing the mouseDragged method of the sketch
**/
void update() {
if (abs(dist(mouseX, mouseY, dialX, dialY)) < (dialSize/2) + 1) {
float angleToValue = map(mouseY, (dialY - (dialSize / 2)), (dialY + (dialSize / 2)), -215.0, 35.0);
value = map(angleToValue, -215.0, 35.0, dialMin, dialMax);
}
}
/**
* Method for insuring elements align and are set appropriately
* prior to displaying dial
**/
void preShow() {
ellipseMode(CENTER);
}
/**
* Method for returning the changed settings back to default to
* prevent alterations to remaining sketch
**/
void postShow() {
textAlign(LEFT);
strokeWeight(1);
textSize(12);
}
/**
* Method for displaying the main dial elements
**/
void showDial() {
// Create main dial
if(active()) {
fill(dialActiveColor);
} else {
fill(dialColor);
}
noStroke();
// outer dial
ellipse(dialX, dialY, dialSize, dialSize);
//Line dial indicator
pushMatrix();
translate(dialX, dialY);
rotate(radians(startAngle + ((value - dialMin) * (250 /(dialMax - dialMin)))));
stroke(valueMarkerColor);
strokeWeight(4);
line(0, 0, dialSize/2 - 1, 0);
popMatrix();
// Inner dial
noStroke();
if(active()) {
fill(dialActiveColor);
} else {
fill(dialColor);
}
ellipse(dialX, dialY, dialSize - dialValueLineSize, dialSize - dialValueLineSize);
}
/**
* Method for displaying the dial value markers around the dial
**/
void showValueMarkers() {
if(showValueMarkers) {
pushMatrix();
// Create fixed point markers using for loop
float incAngle = radians(145);
for(int i = 0; i <= numValueMarkers; i++) {
fill(valueMarkerColor);
noStroke();
ellipse(dialX +(markerDiam * cos(incAngle)),
dialY + (markerDiam * sin(incAngle)),
markerSize, markerSize);
incAngle += radians(250) / numValueMarkers;
}
// Create highlight point makers by mapping temporary value
//float tempValue = (numPoints - ((dialMax - (value - dialMin)) / (dialMax / numPoints))); // old
float tempValue = map(value, dialMin, dialMax, 0, numValueMarkers);
for(int v = 0; v <= tempValue; v++) {
noStroke();
if(active()) {
fill(dialActiveColor);
} else {
fill(valueMarkerFillColor);
}
// Insure value is greater than zero before highlighting marker
if (value > 0) {
ellipse(dialX +(markerDiam * cos(radians(145) + ((radians(250) / numValueMarkers)) * v)),
dialY + (markerDiam * sin(radians(145) + ((radians(250) / numValueMarkers)) * v)),
markerSize, markerSize);
}
}
popMatrix();
}
}
/**
* Method for displaying the text for the dial
* Dial name and dial value
**/
void showText() {
//Dial name and value text
fill(nameTextColor);
textAlign(CENTER, CENTER);
textSize(nameTextSize);
text(dialName, dialX, dialY + (dialSize / 2) + nameClearance);
if (showValue) {
fill(valueTextColor);
textSize(valueTextSize);
text(nf(value, 0, roundValTo), dialX, dialY);
}
}
/**
* Check mouse position is within dial
**/
boolean active() {
if (abs(dist(mouseX, mouseY, dialX, dialY)) < (dialSize/2) + 1) {
return true;
} else {
return false;
}
}
}