G4P V4.3.10 is now available at Sourceforge. It might be a few days before it is available via Contributions Manager, it depends on how often Processing checks for updates.
There are a couple of issues with the last code you posted which might cause problems when you try and export application. For instance the class file you had
package g4p_controls;
and you did this to access certain attributes higher in the class hierarchy. This is now solved in G4P V4.3.10
The working code is now
Main sketch tab
import g4p_controls.*;
GEncoderKnob eknob;
// Visuals
int BackgroundColor = 230;
//------------------------------------------------------------------------------------------------------------------------
public void setup() {
// surface.setResizable(true);
surface.setAlwaysOnTop(true);
size(400, 500, JAVA2D);
background(BackgroundColor); // Set background
eknob = new GEncoderKnob(this, 50, 25, 300, 300, 0.8);
eknob.addEventHandler(this, "eknob_turn");
}
//---------------------------------------------------------------------------------------------------------------------------
public void draw() {
background(BackgroundColor);
rect(15, 373, 372, 120);
fill(0);
textSize(20);
textAlign(CENTER, CENTER);
text("ENCODER STEPS DECIMAL : "+ nf(eknob.getEncoderTicksF(), 0, 2), 30, 375, 370, 75);
text("ENCODER STEPS ROUNDED : "+ nf(eknob.getEncoderTicksI()), 30, 405, 370, 75);
// Show direction
if (eknob.getEncoderTicksI() > 0)
{
fill(100, 250, 100); // Green for forewards
} else {
fill(250, 100, 100); // Red for backwards
}
}
//------------------------------------------------------------------------------------------------------------------
public void eknob_turn(GEncoderKnob encoderknob, GEvent event) {
System.out.println(" Encoder steps count : " + nf(eknob.getEncoderTicksF(), 0, 0));
}
GEncoderKnob.java tab
import g4p_controls.*;
import processing.core.*;
import processing.event.*;
public class GEncoderKnob extends GKnob {
public GEncoderKnob(PApplet theApplet, float p0, float p1, float p2, float p3, float gripAmount) {
super(theApplet, p0, p1, p2, p3, gripAmount); // call ctor in GKnob
showTicks = false; // Hide the two start and end angle ticks.
setTurnMode(CTRL_ANGULAR); // Always use angular.
}
protected float parametricTargetF = 0.5f;
protected float fltEncoderTicks = 0;
protected float EncoderWheelSpeed = 2.5f; // For later use if wheel speed is a thing...
public int getEncoderTicksI() {
return Math.round(fltEncoderTicks);
}
public float getEncoderTicksF() {
return fltEncoderTicks;
}
public void mouseEvent(MouseEvent event) {
if (!visible || !enabled || !available)
return;
calcTransformedOrigin(winApp.mouseX, winApp.mouseY);
currSpot = whichHotSpot(ox, oy);
manageToolTip();
// Normalise ox and oy to the centre of the knob
ox -= width / 2;
oy -= height / 2;
// currSpot == 1 for text display area
if (currSpot >= 0 || focusIsWith == this)
cursorIsOver = this;
else if (cursorIsOver == this)
cursorIsOver = null;
switch (event.getAction()) {
case MouseEvent.PRESS:
if (focusIsWith != this && currSpot > -1 && z > focusObjectZ()) {
startMouseX = ox;
startMouseY = oy;
lastMouseAngle = mouseAngle = getAngleFromUser(ox, oy);
offset = scaleValueToAngle(parametricTarget) - mouseAngle;
takeFocus();
}
break;
case MouseEvent.WHEEL:
if (currSpot > -1 && z >= focusObjectZ()) {
fltEncoderTicks=-1*event.getCount()*EncoderWheelSpeed; // Make ticks avail for outside world
// Replacing the calculation of the position to pure wheeldelta spinnings
if (getEncoderTicksF()<0)
parametricTargetF = parametricTargetF - (wheelDelta*EncoderWheelSpeed);
if (getEncoderTicksF()>0)
parametricTargetF= parametricTargetF + (wheelDelta*EncoderWheelSpeed);
parametricTarget = parametricTargetF;
}
break;
case MouseEvent.RELEASE:
if (focusIsWith == this) {
loseFocus(parent);
}
// Correct for sticky ticks if needed
if (stickToTicks)
parametricTarget = findNearestTickValueTo(parametricTarget);
parametricTargetF = parametricTarget; // Make sure that last wheel turn by mouse movement is stored to ensure correct starting position when switching to scroll wheel;
dragging = false;
break;
case MouseEvent.DRAG:
if (focusIsWith == this) {
mouseAngle = getAngleFromUser(ox, oy);
if (mouseAngle != lastMouseAngle) {
float deltaMangle= mouseAngle - lastMouseAngle;
//float deltaMangle = mouseAngle - lastMouseAngle;
// correct when we go over zero degree position
if (deltaMangle < -180)
deltaMangle += 360;
else if (deltaMangle > 180)
deltaMangle -= 360;
// Calculate and adjust new encoder position, enabling full rotation
angleTarget = angleTarget + deltaMangle;
parametricTarget = calcAngletoValue(angleTarget);
// Update offset for use with angular mouse control
offset += (angleTarget - lastAngleTarget - deltaMangle);
// Remember target needle and mouse angles
lastAngleTarget = angleTarget;
lastMouseAngle = mouseAngle;
fltEncoderTicks = deltaMangle; // Make tikcs avail for outside world
}
}
break;
}
}
protected void updateBuffer() {
double a, sina, cosa;
float tickLength;
if (bufferInvalid) {
bufferInvalid = false;
buffer.beginDraw();
buffer.ellipseMode(PApplet.CENTER);
// Background colour
if (opaque == true)
buffer.background(palette[6].getRGB());
else
buffer.background(buffer.color(255, 0));
buffer.translate(width / 2, height / 2);
buffer.noStroke();
float anglePos = scaleValueToAngle(parametricPos);
if (bezelWidth > 0) {
// Draw bezel
buffer.noStroke();
buffer.fill(palette[5].getRGB());
if (drawArcOnly)
buffer.arc(0, 0, 2 * bezelRadius, 2 * bezelRadius, PApplet.radians(startAng),
PApplet.radians(endAng));
else
buffer.ellipse(0, 0, 2 * bezelRadius, 2 * bezelRadius);
// Draw ticks?
if (showTicks) {
buffer.noFill();
buffer.strokeWeight(1.6f);
buffer.stroke(palette[3].getRGB());
float deltaA = (endAng - startAng) / (nbrTicks - 1);
for (int t = 0; t < nbrTicks; t++) {
tickLength = gripRadius + ((t == 0 || t == nbrTicks - 1) ? bezelWidth : bezelWidth * 0.8f);
a = Math.toRadians(startAng + t * deltaA);
sina = Math.sin(a);
cosa = Math.cos(a);
buffer.line((float) (gripRadius * cosa), (float) (gripRadius * sina),
(float) (tickLength * cosa), (float) (tickLength * sina));
}
}
// Draw track?
if (showTrack) {
buffer.noStroke();
buffer.fill(palette[14].getRGB());
// Changed the arc from 0, to line position into a floating small arc at and of line
buffer.arc(0, 0, 2 * (gripRadius + bezelWidth * 0.5f), 2 * (gripRadius + bezelWidth * 0.5f),
PApplet.radians(anglePos-15), PApplet.radians(anglePos+15));
}
}
// draw grip (inner) part of knob
buffer.strokeWeight(1.6f);
buffer.stroke(palette[2].getRGB());
buffer.fill(palette[2].getRGB());
if (drawArcOnly)
buffer.arc(0, 0, 2 * gripRadius, 2 * gripRadius, PApplet.radians(startAng), PApplet.radians(endAng));
else
buffer.ellipse(0, 0, 2 * gripRadius, 2 * gripRadius);
buffer.endDraw();
}
}
}
This works when I export application on my iMac but I have not tested it in Windows.