Skip to content

Commit

Permalink
Merge pull request #1164 from OpenBCI/development
Browse files Browse the repository at this point in the history
GUI Patch v5.2.1
  • Loading branch information
retiutut authored Jul 11, 2023
2 parents 7bf88ed + 9ef8bc9 commit 5547183
Show file tree
Hide file tree
Showing 15 changed files with 367 additions and 124 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
branches:
only:
- master
- development
#- development

before_install:
- if [ "$TRAVIS_OS_NAME" = osx ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then openssl aes-256-cbc -K $encrypted_2f5d2771e3cb_key -iv $encrypted_2f5d2771e3cb_iv -in release_script/mac_only/Certificates.p12.enc -out release_script/mac_only/Certificates.p12 -d; fi
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# v5.2.1

### Improvements

- Add ability to map channels to EMG Joystick Inputs #1156
- Fix alignment of UI objects in popup windows and EMG settings UI #1157
- Rename "smoothing" to "window" in EMG settings UI #1158
- Add EMG Joystick settings to Session Settings #1159

# v5.2.0

### Bug Fixes
Expand Down
4 changes: 2 additions & 2 deletions OpenBCI_GUI/EmgSettings.pde
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ class EmgSettings {
}
Gson gson = new Gson();
EmgSettingsValues tempValues = gson.fromJson(fileContents.toString(), EmgSettingsValues.class);
if (tempValues.smoothing.length != channelCount) {
if (tempValues.window.length != channelCount) {
outputError("Emg Settings: Loaded EMG Settings file has different number of channels than the current board.");
return false;
}
//Explicitely copy values over to avoid reference issues
//(e.g. values = tempValues "nukes" the old values object)
values.smoothing = tempValues.smoothing;
values.window = tempValues.window;
values.uvLimit = tempValues.uvLimit;
values.creepIncreasing = tempValues.creepIncreasing;
values.creepDecreasing = tempValues.creepDecreasing;
Expand Down
4 changes: 2 additions & 2 deletions OpenBCI_GUI/EmgSettingsEnums.pde
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ interface EmgSettingsEnum {
public String getString();
}

public enum EmgSmoothing implements EmgSettingsEnum
public enum EmgWindow implements EmgSettingsEnum
{
ONE_HUNDREDTH_SECOND (0, "0.01 s", .01f),
ONE_TENTH_SECOND (1, "0.1 s", .1f),
Expand All @@ -18,7 +18,7 @@ public enum EmgSmoothing implements EmgSettingsEnum
private String name;
private float value;

EmgSmoothing(int index, String name, float value) {
EmgWindow(int index, String name, float value) {
this.index = index;
this.name = name;
this.value = value;
Expand Down
102 changes: 34 additions & 68 deletions OpenBCI_GUI/EmgSettingsUI.pde
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
////////////////////////////////////////////////////////////
// EmgSettingsUI.pde //
// EmgSettingsUI.pde //
// Display the Emg Settings UI as a popup //
// Note: This window is never resized. //
// //
////////////////////////////////////////////////////////////

Expand All @@ -14,7 +15,7 @@ class EmgSettingsUI extends PApplet implements Runnable {
private ControlP5 emgCp5;
private int x, y, w, h;
private final int HEADER_HEIGHT = 55;
private final int FOOTER_PADDING = 80;
private final int FOOTER_PADDING = 90;
private final int PADDING_3 = 3;
private final int PADDING_12 = 12;
private final int NUM_CONTROL_BUTTONS = 3;
Expand All @@ -29,7 +30,7 @@ class EmgSettingsUI extends PApplet implements Runnable {
private final int NUM_FOOTER_OBJECTS = 3;
private final int FOOTER_OBJECT_WIDTH = 45;
private final int FOOTER_OBJECT_HEIGHT = 26;
private int footerObjY = 0;
private int footerObjY;
private int[] footerObjX = new int[NUM_FOOTER_OBJECTS];

private final color HEADER_COLOR = OPENBCI_BLUE;
Expand All @@ -42,14 +43,14 @@ class EmgSettingsUI extends PApplet implements Runnable {
public EmgSettingsValues emgSettingsValues;

private TextBox channelColumnLabel;
private TextBox smoothLabel;
private TextBox windowLabel;
private TextBox uvLimitLabel;
private TextBox creepIncLabel;
private TextBox creepDecLabel;
private TextBox minDeltaUvLabel;
private TextBox lowLimitLabel;

private ScrollableList[] smoothLists;
private ScrollableList[] windowLists;
private ScrollableList[] uvLimitLists;
private ScrollableList[] creepIncLists;
private ScrollableList[] creepDecLists;
Expand Down Expand Up @@ -118,9 +119,11 @@ class EmgSettingsUI extends PApplet implements Runnable {
scene();

// Draw header
pushStyle();
noStroke();
fill(HEADER_COLOR);
rect(0, 0, width, HEADER_HEIGHT);
popStyle();

emgSettingsValues = dataProcessing.emgSettings.values;

Expand All @@ -129,7 +132,7 @@ class EmgSettingsUI extends PApplet implements Runnable {

//Draw column labels
channelColumnLabel.draw();
smoothLabel.draw();
windowLabel.draw();
uvLimitLabel.draw();
creepIncLabel.draw();
creepDecLabel.draw();
Expand All @@ -139,56 +142,19 @@ class EmgSettingsUI extends PApplet implements Runnable {
drawChannelLabels();

//Draw cp5 objects on top of everything
emgCp5.draw();
}

private void screenResized() {
x = 0;
y = 0;
w = width;
h = height;

emgCp5.setGraphics(ourApplet, 0, 0);

int colWidth = (width / NUM_COLUMNS);
int colOffset = colWidth / 2;
int labelY = y + HEADER_HEIGHT / 2;
channelColumnLabel.setPosition(x + colOffset, labelY);
smoothLabel.setPosition(x + colOffset + colWidth, labelY);
uvLimitLabel.setPosition(x + colOffset + colWidth*2, labelY);
creepIncLabel.setPosition(x + colOffset + colWidth*3, labelY);
creepDecLabel.setPosition(x + colOffset + colWidth*4, labelY);
minDeltaUvLabel.setPosition(x + colOffset + colWidth*5, labelY);
lowLimitLabel.setPosition(x + colOffset + colWidth*6, labelY);

resizeDropdowns();
try {
emgCp5.draw();
} catch (ConcurrentModificationException e) {
e.printStackTrace();
outputError("EMG Settings UI: Unable to draw cp5 objects.");
}
}

private void scene() {
// Draw background
background(BACKGROUND_COLOR);
}

@Override
public void keyReleased() {

}

@Override
public void keyPressed() {

}

@Override
public void mousePressed() {

}

@Override
public void mouseReleased() {

}

@Override
public void exit() {
dispose();
Expand Down Expand Up @@ -229,23 +195,23 @@ class EmgSettingsUI extends PApplet implements Runnable {

for (int i = 0; i < channelCount; i++) {
String channelLabel = channelCount > channelLabels.length ? "Channel " + Integer.toString(i + 1) : channelLabels[i];
text(channelLabel, x + colOffset, dropdownYPositions[i] + (DROPDOWN_HEIGHT / 2));
text(channelLabel, x + colOffset, dropdownYPositions[i] + (DROPDOWN_HEIGHT / 2) - 2);
}

popStyle();
}

private void resizeDropdowns() {
dropdownWidth = int((w - (DROPDOWN_SPACER * (NUM_COLUMNS + 1))) / NUM_COLUMNS);
final int MAX_HEIGHT_ITEMS = channelCount == 4 ? 8 : 5;
final int MAX_HEIGHT_ITEMS = 6;

for (int i = 0; i < channelCount; i++) {
int dropdownX = x + DROPDOWN_SPACER * 2 + dropdownWidth;
dropdownYPositions[i] = HEADER_HEIGHT + int(y + ((ROW_HEIGHT) * i) + (((ROW_HEIGHT) - DROPDOWN_HEIGHT) / 2));
final int buttonXIncrement = DROPDOWN_SPACER + dropdownWidth;

smoothLists[i].setPosition(dropdownX, dropdownYPositions[i]);
smoothLists[i].setSize(dropdownWidth, MAX_HEIGHT_ITEMS * DROPDOWN_HEIGHT);
windowLists[i].setPosition(dropdownX, dropdownYPositions[i]);
windowLists[i].setSize(dropdownWidth, MAX_HEIGHT_ITEMS * DROPDOWN_HEIGHT);

dropdownX += buttonXIncrement;
uvLimitLists[i].setPosition(dropdownX, dropdownYPositions[i]);
Expand All @@ -270,7 +236,8 @@ class EmgSettingsUI extends PApplet implements Runnable {
}

private void createAllUIObjects() {
footerObjY = y + h - FOOTER_PADDING + PADDING_3;
final int HALF_FOOTER_HEIGHT = (FOOTER_PADDING + (DROPDOWN_SPACER * 2)) / 2;
footerObjY = y + h - HALF_FOOTER_HEIGHT - (FOOTER_OBJECT_HEIGHT / 2);
int middle = x + w / 2;
int halfObjWidth = FOOTER_OBJECT_WIDTH / 2;
footerObjX[0] = middle - halfObjWidth - PADDING_12 - FOOTER_OBJECT_WIDTH;
Expand All @@ -291,13 +258,13 @@ class EmgSettingsUI extends PApplet implements Runnable {
int colWidth = (w / NUM_COLUMNS);
int colOffset = colWidth / 2;
int labelY = y + HEADER_HEIGHT / 2;
channelColumnLabel = new TextBox("Channel", x + colOffset, labelY, labelTxt, labelBG, 12, h3, CENTER, TOP);
smoothLabel = new TextBox("Smooth", x + colOffset + colWidth, labelY, labelTxt, labelBG, 12, h3, CENTER, TOP);
uvLimitLabel = new TextBox("uV Limit", x + colOffset + colWidth*2, labelY, labelTxt, labelBG, 12, h3, CENTER, TOP);
creepIncLabel = new TextBox("Creep +", x + colOffset + colWidth*3, labelY, labelTxt, labelBG, 12, h3, CENTER, TOP);
creepDecLabel = new TextBox("Creep -", x + colOffset + colWidth*4, labelY, labelTxt, labelBG, 12, h3, CENTER, TOP);
minDeltaUvLabel = new TextBox("Min \u0394uV", x + colOffset + colWidth*5, labelY, labelTxt, labelBG, 12, h3, CENTER, TOP);
lowLimitLabel = new TextBox("Low Limit", x + colOffset + colWidth*6, labelY, labelTxt, labelBG, 12, h3, CENTER, TOP);
channelColumnLabel = new TextBox("Channel", x + colOffset, labelY, labelTxt, labelBG, 14, h4, CENTER, CENTER);
windowLabel = new TextBox("Window", x + colOffset + colWidth, labelY, labelTxt, labelBG, 14, h4, CENTER, CENTER);
uvLimitLabel = new TextBox("uV Limit", x + colOffset + colWidth*2, labelY, labelTxt, labelBG, 14, h4, CENTER, CENTER);
creepIncLabel = new TextBox("Creep +", x + colOffset + colWidth*3, labelY, labelTxt, labelBG, 14, h4, CENTER, CENTER);
creepDecLabel = new TextBox("Creep -", x + colOffset + colWidth*4, labelY, labelTxt, labelBG, 14, h4, CENTER, CENTER);
minDeltaUvLabel = new TextBox("Min \u0394uV", x + colOffset + colWidth*5, labelY, labelTxt, labelBG, 14, h4, CENTER, CENTER);
lowLimitLabel = new TextBox("Low Limit", x + colOffset + colWidth*6, labelY, labelTxt, labelBG, 14, h4, CENTER, CENTER);

createAllDropdowns();
}
Expand All @@ -306,7 +273,7 @@ class EmgSettingsUI extends PApplet implements Runnable {
//the size and space of these buttons are dependendant on the size of the screen and full ChannelController
verbosePrint("EmgChannelSettingsUI: Creating EMG channel setting UI objects...");

smoothLists = new ScrollableList[channelCount];
windowLists = new ScrollableList[channelCount];
uvLimitLists = new ScrollableList[channelCount];
creepIncLists = new ScrollableList[channelCount];
creepDecLists = new ScrollableList[channelCount];
Expand All @@ -318,7 +285,7 @@ class EmgSettingsUI extends PApplet implements Runnable {
//Init dropdowns in reverse so that chan 1 draws on top of chan 2, etc.
for (int i = channelCount - 1; i >= 0; i--) {
int exgChannel = i;
smoothLists[i] = createDropdown(exgChannel, "smooth_ch_"+(i+1), emgSettingsValues.smoothing[exgChannel].values(), emgSettingsValues.smoothing[exgChannel]);
windowLists[i] = createDropdown(exgChannel, "smooth_ch_"+(i+1), emgSettingsValues.window[exgChannel].values(), emgSettingsValues.window[exgChannel]);
uvLimitLists[i] = createDropdown(exgChannel, "uvLimit_ch_"+(i+1), emgSettingsValues.uvLimit[exgChannel].values(), emgSettingsValues.uvLimit[exgChannel]);
creepIncLists[i] = createDropdown(exgChannel, "creep_inc_ch_"+(i+1), emgSettingsValues.creepIncreasing[exgChannel].values(), emgSettingsValues.creepIncreasing[exgChannel]);
creepDecLists[i] = createDropdown(exgChannel, "creep_dec_ch_"+(i+1), emgSettingsValues.creepDecreasing[exgChannel].values(), emgSettingsValues.creepDecreasing[exgChannel]);
Expand Down Expand Up @@ -386,9 +353,8 @@ class EmgSettingsUI extends PApplet implements Runnable {
EmgSettingsEnum myEnum = (EmgSettingsEnum)bob.get("value");
verbosePrint("EmgSettings: " + (theEvent.getController()).getName() + " == " + myEnum.getString());

if (myEnum instanceof EmgSmoothing) {
//verbosePrint("HardwareSettings: previousVal == " + emgSettingsValues.previousValues.gain[channel]);
emgSettingsValues.smoothing[channel] = (EmgSmoothing)myEnum;
if (myEnum instanceof EmgWindow) {
emgSettingsValues.window[channel] = (EmgWindow)myEnum;
} else if (myEnum instanceof EmgUVLimit) {
emgSettingsValues.uvLimit[channel] = (EmgUVLimit)myEnum;
} else if (myEnum instanceof EmgCreepIncreasing) {
Expand Down Expand Up @@ -437,15 +403,15 @@ class EmgSettingsUI extends PApplet implements Runnable {
private void updateCp5Objects() {
for (int i = 0; i < channelCount; i++) {
//Fetch values from the EmgSettingsValues object
EmgSmoothing updateSmoothing = emgSettingsValues.smoothing[i];
EmgWindow updateSmoothing = emgSettingsValues.window[i];
EmgUVLimit updateUVLimit = emgSettingsValues.uvLimit[i];
EmgCreepIncreasing updateCreepIncreasing = emgSettingsValues.creepIncreasing[i];
EmgCreepDecreasing updateCreepDecreasing = emgSettingsValues.creepDecreasing[i];
EmgMinimumDeltaUV updateMinimumDeltaUV = emgSettingsValues.minimumDeltaUV[i];
EmgLowerThresholdMinimum updateLowerThresholdMinimum = emgSettingsValues.lowerThresholdMinimum[i];

//Update the ScrollableLists
smoothLists[i].getCaptionLabel().setText(updateSmoothing.getString());
windowLists[i].getCaptionLabel().setText(updateSmoothing.getString());
uvLimitLists[i].getCaptionLabel().setText(updateUVLimit.getString());
creepIncLists[i].getCaptionLabel().setText(updateCreepIncreasing.getString());
creepDecLists[i].getCaptionLabel().setText(updateCreepDecreasing.getString());
Expand Down
8 changes: 4 additions & 4 deletions OpenBCI_GUI/EmgSettingsValues.pde
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
class EmgSettingsValues {

//These values can be changed via dropdowns
public EmgSmoothing[] smoothing;
public EmgWindow[] window;
public EmgUVLimit[] uvLimit;
public EmgCreepIncreasing[] creepIncreasing;
public EmgCreepDecreasing[] creepDecreasing;
Expand All @@ -27,7 +27,7 @@ class EmgSettingsValues {

channelCount = currentBoard.getNumEXGChannels();

smoothing = new EmgSmoothing[channelCount];
window = new EmgWindow[channelCount];
uvLimit = new EmgUVLimit[channelCount];
creepIncreasing = new EmgCreepIncreasing[channelCount];
creepDecreasing = new EmgCreepDecreasing[channelCount];
Expand All @@ -39,7 +39,7 @@ class EmgSettingsValues {
lowerThreshold = new float[channelCount];
averageuV = new float[channelCount];

Arrays.fill(smoothing, EmgSmoothing.ONE_SECOND);
Arrays.fill(window, EmgWindow.ONE_SECOND);
Arrays.fill(uvLimit, EmgUVLimit.TWO_HUNDRED_UV);
Arrays.fill(creepIncreasing, EmgCreepIncreasing.POINT_9);
Arrays.fill(creepDecreasing, EmgCreepDecreasing.POINT_99999);
Expand All @@ -55,7 +55,7 @@ class EmgSettingsValues {
public void process(float[][] data_forDisplay_uV) {
//looping over channels and analyzing input data
for (int i = 0; i < channelCount; i++) {
float averagePeriod = currentBoard.getSampleRate() * smoothing[i].getValue();
float averagePeriod = currentBoard.getSampleRate() * window[i].getValue();
int _uvLimit = uvLimit[i].getValue();
float creepSpeedIncreasing = creepIncreasing[i].getValue();
float creepSpeedDecreasing = creepDecreasing[i].getValue();
Expand Down
4 changes: 2 additions & 2 deletions OpenBCI_GUI/Info.plist.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<key>CFBundleShortVersionString</key>
<string>5</string>
<key>CFBundleVersion</key>
<string>5.2.0</string>
<string>5.2.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>NSHumanReadableCopyright</key>
Expand All @@ -32,7 +32,7 @@
Copyright © 2023 OpenBCI
</string>
<key>CFBundleGetInfoString</key>
<string>June 2023</string>
<string>July 2023</string>
<!-- End of the set that can be customized -->

@@jvm_runtime@@
Expand Down
4 changes: 2 additions & 2 deletions OpenBCI_GUI/OpenBCI_GUI.pde
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
// Global Variables & Instances
//------------------------------------------------------------------------
//Used to check GUI version in TopNav.pde and displayed on the splash screen on startup
String localGUIVersionString = "v5.2.0";
String localGUIVersionDate = "June 2023";
String localGUIVersionString = "v5.2.1";
String localGUIVersionDate = "July 2023";
String guiLatestVersionGithubAPI = "https://api.github.com/repos/OpenBCI/OpenBCI_GUI/releases/latest";
String guiLatestReleaseLocation = "https://github.com/OpenBCI/OpenBCI_GUI/releases/latest";
Boolean guiIsUpToDate;
Expand Down
2 changes: 1 addition & 1 deletion OpenBCI_GUI/PopupMessage.pde
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class PopupMessage extends PApplet implements Runnable {
textFont(p0, 24);
fill(WHITE);
textAlign(LEFT, CENTER);
text(headerMessage, (width - w)/2 + padding, (height - h)/2, w, headerHeight);
text(headerMessage, (width - w)/2 + padding, headerHeight/2);

//draw message
textFont(p3, 16);
Expand Down
Loading

0 comments on commit 5547183

Please sign in to comment.