diff --git a/.travis.yml b/.travis.yml
index c81e354aa..b25d3eea6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,7 @@ jobs:
branches:
only:
- master
+ - 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
@@ -68,4 +69,4 @@ after_success:
notifications:
email:
on_success: never
- on_failure: always
\ No newline at end of file
+ on_failure: always
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 468107c26..4336d8ffd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,15 @@
+# v5.0.7
+
+### Improvements
+* Show info in footer when a new version of the GUI is available #992
+* Further improvements to GUI Update Button logic
+* Add GUI-wide settings class to keep certain settings across sessions and app starts #997
+* Remove 30 second window option from Focus widget
+
+### Bug Fixes
+* Fix GUI not running on some Macs due to high-dpi screen code #987 #990 #1001
+* Fix streaming multiple data types over LSL #971
+
# v5.0.6
### Improvements
diff --git a/Networking-Test-Kit/LSL/lslStreamTest.py b/Networking-Test-Kit/LSL/lslStreamTest.py
index 6fce85048..d7cb303b5 100644
--- a/Networking-Test-Kit/LSL/lslStreamTest.py
+++ b/Networking-Test-Kit/LSL/lslStreamTest.py
@@ -9,7 +9,7 @@
# create a new inlet to read from the stream
inlet = StreamInlet(streams[0])
-duration = 2
+duration = 5
sleep(1)
@@ -18,17 +18,18 @@ def testLSLSamplingRate():
totalNumSamples = 0
validSamples = 0
numChunks = 0
+ print( "Testing Sampling Rates..." )
while time.time() <= start + duration:
# get chunks of samples
- samples, timestamp = inlet.pull_chunk()
- if samples:
+ chunk, timestamp = inlet.pull_chunk()
+ if chunk:
numChunks += 1
- print( len(samples) )
- totalNumSamples += len(samples)
- # print(samples);
- for sample in samples:
- print(sample)
+ # print( len(chunk) )
+ totalNumSamples += len(chunk)
+ # print(chunk);
+ for sample in chunk:
+ # print(sample)
validSamples += 1
print( "Number of Chunks and Samples == {} , {}".format(numChunks, totalNumSamples) )
diff --git a/Networking-Test-Kit/LSL/lslStreamTest_3Streams.py b/Networking-Test-Kit/LSL/lslStreamTest_3Streams.py
index bca94ade1..73d7ed21b 100644
--- a/Networking-Test-Kit/LSL/lslStreamTest_3Streams.py
+++ b/Networking-Test-Kit/LSL/lslStreamTest_3Streams.py
@@ -10,43 +10,51 @@
import time
numStreams = 3
+duration_seconds = 20
# first resolve an EEG stream on the lab network
print("looking for an EEG stream...")
-stream1 = resolve_stream('type', 'EEG')
-stream2 = resolve_stream('type', 'AUX')
-stream3 = resolve_stream('type', 'FFT')
+stream_1 = resolve_stream('type', 'EEG')
+stream_2 = resolve_stream('type', 'AUX')
+stream_3 = resolve_stream('type', 'FOCUS')
# create a new inlet to read from the stream
-inlet = StreamInlet(stream1[0])
-inlet2 = StreamInlet(stream2[0])
-inlet3 = StreamInlet(stream3[0])
+inlet = StreamInlet(stream_1[0])
+intlet_2 = StreamInlet(stream_2[0])
+intlet_3 = StreamInlet(stream_3[0])
def testLSLSamplingRates():
- print( "Testing Sampling Rates..." )
+ print( "Testing Sampling Rates for {} seconds".format(duration_seconds) )
start = time.time()
- numSamples1 = 0
- numSamples2 = 0
- numSamples3 = 0
- while time.time() < start + 5:
+ num_samples_1 = 0
+ num_samples_2 = 0
+ num_samples_3 = 0
+ while time.time() < start + duration_seconds:
# get a new sample (you can also omit the timestamp part if you're not
# interested in it)
for i in range(numStreams):
if i == 0:
chunk, timestamps = inlet.pull_chunk()
if timestamps:
- numSamples1 += 1
+ for sample in chunk:
+ if sample:
+ num_samples_1 += 1
+ #print(sample)
elif i == 1:
- chunk, timestamps2 = inlet2.pull_chunk()
- if timestamps2:
- numSamples2 += 1
+ chunk, timestamps_2 = intlet_2.pull_chunk()
+ if timestamps_2:
+ for sample in chunk:
+ num_samples_2 += 1
+ #print(sample)
elif i == 2:
- chunk, timestamps3 = inlet3.pull_chunk()
- if timestamps3:
- numSamples3 += 1
+ chunk, timestamps_3 = intlet_3.pull_chunk()
+ if timestamps_3:
+ for sample in chunk:
+ num_samples_3 += 1
+ #print(sample)
#print("Stream", i + 1, " == ", chunk)
- print( "Stream 1 Sampling Rate == ", numSamples1, " | Type : EEG")
- print( "Stream 2 Sampling Rate == ", numSamples2, " | Type : AUX")
- print( "Stream 3 Sampling Rate == ", numSamples3, " | Type : FFT")
+ print( "Stream 1 Sampling Rate == ", num_samples_1 / duration_seconds, " | Type : EEG")
+ print( "Stream 2 Sampling Rate == ", num_samples_2 / duration_seconds, " | Type : AUX")
+ print( "Stream 3 Sampling Rate == ", num_samples_3 / duration_seconds, " | Type : FOCUS")
testLSLSamplingRates()
\ No newline at end of file
diff --git a/Networking-Test-Kit/LSL/lslStreamTest_FFTplot.py b/Networking-Test-Kit/LSL/lslStreamTest_FFTplot.py
index f2a2a715f..6a072d35a 100644
--- a/Networking-Test-Kit/LSL/lslStreamTest_FFTplot.py
+++ b/Networking-Test-Kit/LSL/lslStreamTest_FFTplot.py
@@ -11,16 +11,17 @@
last_print = time.time()
fps_counter = deque(maxlen=150)
+duration = 5
# first resolve an EEG stream on the lab network
print("looking for an EEG stream...")
-streams = resolve_stream('type', 'EEG')
+streams = resolve_stream('type', 'FFT')
# create a new inlet to read from the stream
inlet = StreamInlet(streams[0])
channel_data = {}
-for i in range(5): # how many iterations. Eventually this would be a while True
+for i in range(duration): # how many iterations. Eventually this would be a while True
for i in range(16): # each of the 16 channels here
sample, timestamp = inlet.pull_sample()
diff --git a/OpenBCI_GUI/ADS1299SettingsController.pde b/OpenBCI_GUI/ADS1299SettingsController.pde
index 687701c66..1e8edb284 100644
--- a/OpenBCI_GUI/ADS1299SettingsController.pde
+++ b/OpenBCI_GUI/ADS1299SettingsController.pde
@@ -138,7 +138,7 @@ class ADS1299SettingsController {
}
}
- boolean showCustomCommandUI = settings.expertModeToggle;
+ boolean showCustomCommandUI = guiSettings.getExpertModeBoolean();
//Draw background behind command buttons
pushStyle();
diff --git a/OpenBCI_GUI/ControlPanel.pde b/OpenBCI_GUI/ControlPanel.pde
index 144fb7c85..d3c3bfc45 100644
--- a/OpenBCI_GUI/ControlPanel.pde
+++ b/OpenBCI_GUI/ControlPanel.pde
@@ -2778,7 +2778,6 @@ class InitBox {
}
} else {
//if system is already active ... stop session and flip button state back
- outputInfo("Learn how to use this application and more at openbci.github.io/Documentation/");
setInitSessionButtonText("START SESSION");
topNav.setLockTopLeftSubNavCp5Objects(false); //Unlock top left subnav buttons
//creates new data file name so that you don't accidentally overwrite the old one
diff --git a/OpenBCI_GUI/CustomCp5Classes.pde b/OpenBCI_GUI/CustomCp5Classes.pde
index f8f6490a1..6159b5b1a 100644
--- a/OpenBCI_GUI/CustomCp5Classes.pde
+++ b/OpenBCI_GUI/CustomCp5Classes.pde
@@ -90,7 +90,8 @@ class ButtonHelpText{
}
public void draw(){
- if (!isVisible || settings.expertModeToggle) {
+ //When using expert mode, disable help text over UI objects
+ if (!isVisible || guiSettings.getExpertModeBoolean()) {
return;
}
diff --git a/OpenBCI_GUI/Debugging.pde b/OpenBCI_GUI/Debugging.pde
index 2892c5cd6..9d1412bf0 100644
--- a/OpenBCI_GUI/Debugging.pde
+++ b/OpenBCI_GUI/Debugging.pde
@@ -54,7 +54,7 @@ class HelpWidget {
int padding;
//current text shown in help widget, based on most recent command
- String currentOutput = "Learn how to use this application and more at openbci.github.io/Documentation/";
+ String currentOutput = "Learn how to use this application and more at docs.openbci.com";
OutputLevel curOutputLevel = OutputLevel.INFO;
HelpWidget(float _xPos, float _yPos, float _width, float _height) {
diff --git a/OpenBCI_GUI/FocusEnums.pde b/OpenBCI_GUI/FocusEnums.pde
index e6bfe7dd7..accf680ed 100644
--- a/OpenBCI_GUI/FocusEnums.pde
+++ b/OpenBCI_GUI/FocusEnums.pde
@@ -14,8 +14,7 @@ public enum FocusXLim implements FocusEnum
{
FIVE (0, 5, "5 sec"),
TEN (1, 10, "10 sec"),
- TWENTY (2, 20, "20 sec"),
- THIRTY (3, 30, "30 sec");
+ TWENTY (2, 20, "20 sec");
private int index;
private int value;
diff --git a/OpenBCI_GUI/GuiSettings.pde b/OpenBCI_GUI/GuiSettings.pde
new file mode 100644
index 000000000..8215c34d6
--- /dev/null
+++ b/OpenBCI_GUI/GuiSettings.pde
@@ -0,0 +1,116 @@
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import java.io.*;
+
+
+interface GuiSettingsEnum {
+ public String getName();
+}
+
+enum ExpertModeEnum implements GuiSettingsEnum {
+ ON("Active", true),
+ OFF("Inactive", false);
+
+ private String name;
+ private boolean val;
+
+ ExpertModeEnum(String _name, boolean _val) {
+ this.name = _name;
+ this.val = _val;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ public boolean getBooleanValue() {
+ return val;
+ }
+}
+
+public class GuiSettingsValues {
+ private ExpertModeEnum expertMode = ExpertModeEnum.OFF;
+
+ public GuiSettingsValues() {
+ }
+}
+
+class GuiSettings {
+
+ public GuiSettingsValues values;
+ private String filename;
+
+ GuiSettings(String settingsDirectory) {
+
+ values = new GuiSettingsValues();
+
+ StringBuilder settingsFilename = new StringBuilder(settingsDirectory);
+ settingsFilename.append("GuiWideSettings.json");
+ filename = settingsFilename.toString();
+ File fileToCheck = new File(filename);
+ boolean fileExists = fileToCheck.exists();
+ if (fileExists) {
+ loadSettingsValues();
+ println("OpenBCI_GUI::Settings: Found and loaded existing GUI-wide Settings from file.");
+ } else {
+ println("OpenBCI_GUI::Settings: Creating new GUI-wide Settings file.");
+ saveToFile();
+ }
+ }
+
+ public boolean loadSettingsValues() {
+ try {
+ File file = new File(filename);
+ StringBuilder fileContents = new StringBuilder((int)file.length());
+ Scanner scanner = new Scanner(file);
+ while(scanner.hasNextLine()) {
+ fileContents.append(scanner.nextLine() + System.lineSeparator());
+ }
+ Gson gson = new Gson();
+ values = gson.fromJson(fileContents.toString(), GuiSettingsValues.class);
+ return true;
+ } catch (IOException e) {
+ e.printStackTrace();
+ outputWarn("OpenBCI_GUI::Settings: Error loading GUI-wide settings from file. Attempting to create a new one.");
+ //If there is an error, attempt to overwrite the file or create a new one
+ saveToFile();
+ return false;
+ }
+ }
+
+ public String getJson() {
+ Gson gson = new GsonBuilder().setPrettyPrinting().create();
+ return gson.toJson(values);
+ }
+
+ public boolean saveToFile() {
+ String json = getJson();
+ try {
+ FileWriter writer = new FileWriter(filename);
+ writer.write(json);
+ writer.close();
+ println("OpenBCI_GUI::Settings: Successfully saved GUI-wide settings to file!");
+ return true;
+ } catch (IOException e) {
+ e.printStackTrace();
+ outputWarn("OpenBCI_GUI::Settings: Error saving GUI-wide settings to file. Please make an issue on GitHub.");
+ return false;
+ }
+ }
+
+ //Call this method at the end of GUI main Setup in OpenBCI_GUI.pde to make sure everything exists
+ //Has to be in this class to make sure other classes exist
+ public void applySettings() {
+ topNav.configSelector.toggleExpertModeFrontEnd(getExpertModeBoolean());
+ }
+
+ public void setExpertMode(ExpertModeEnum val) {
+ values.expertMode = val;
+ saveToFile();
+ }
+
+ public boolean getExpertModeBoolean() {
+ return values.expertMode.getBooleanValue();
+ }
+}
\ No newline at end of file
diff --git a/OpenBCI_GUI/Info.plist.tmpl b/OpenBCI_GUI/Info.plist.tmpl
index 9aad9c08c..936cc6a2d 100644
--- a/OpenBCI_GUI/Info.plist.tmpl
+++ b/OpenBCI_GUI/Info.plist.tmpl
@@ -23,7 +23,7 @@
CFBundleShortVersionString
5
CFBundleVersion
- 5.0.6
+ 5.0.7
CFBundleSignature
????
NSHumanReadableCopyright
@@ -32,7 +32,7 @@
Copyright © 2021 OpenBCI
CFBundleGetInfoString
- July 2021
+ September 2021
@@jvm_runtime@@
diff --git a/OpenBCI_GUI/Interactivity.pde b/OpenBCI_GUI/Interactivity.pde
index 6cfa6ceb4..614f8b378 100644
--- a/OpenBCI_GUI/Interactivity.pde
+++ b/OpenBCI_GUI/Interactivity.pde
@@ -31,7 +31,7 @@ synchronized void keyPressed() {
boolean anyActiveTextfields = isNetworkingTextActive() || textFieldIsActive;
if(!controlPanel.isOpen && !anyActiveTextfields){ //don't parse the key if the control panel is open
- if (settings.expertModeToggle || key == ' ') { //Check if Expert Mode is On or Spacebar has been pressed
+ if (guiSettings.getExpertModeBoolean() || key == ' ') { //Check if Expert Mode is On or Spacebar has been pressed
if ((int(key) >=32) && (int(key) <= 126)) { //32 through 126 represent all the usual printable ASCII characters
parseKey(key);
}
diff --git a/OpenBCI_GUI/OpenBCI_GUI.pde b/OpenBCI_GUI/OpenBCI_GUI.pde
index c7084707e..662590055 100644
--- a/OpenBCI_GUI/OpenBCI_GUI.pde
+++ b/OpenBCI_GUI/OpenBCI_GUI.pde
@@ -60,10 +60,11 @@ import http.requests.*;
// Global Variables & Instances
//------------------------------------------------------------------------
//Used to check GUI version in TopNav.pde and displayed on the splash screen on startup
-String localGUIVersionString = "v5.0.6";
-String localGUIVersionDate = "July 2021";
+String localGUIVersionString = "v5.0.7";
+String localGUIVersionDate = "September 2021";
String guiLatestVersionGithubAPI = "https://api.github.com/repos/OpenBCI/OpenBCI_GUI/releases/latest";
String guiLatestReleaseLocation = "https://github.com/OpenBCI/OpenBCI_GUI/releases/latest";
+Boolean guiIsUpToDate;
PApplet ourApplet;
@@ -279,8 +280,9 @@ static CustomOutputStream outputStream;
public final static String stopButton_pressToStop_txt = "Stop Data Stream";
public final static String stopButton_pressToStart_txt = "Start Data Stream";
-SessionSettings settings;
DirectoryManager directoryManager;
+SessionSettings settings;
+GuiSettings guiSettings;
final int navBarHeight = 32;
TopNav topNav;
@@ -288,6 +290,9 @@ TopNav topNav;
ddf.minim.analysis.FFT[] fftBuff = new ddf.minim.analysis.FFT[nchan]; //from the minim library
boolean isFFTFiltered = true; //yes by default ... this is used in dataProcessing.pde to determine which uV array feeds the FFT calculation
+StringBuilder globalScreenResolution;
+StringBuilder globalScreenDPI;
+
//------------------------------------------------------------------------
// Global Functions
//------------------------------------------------------------------------
@@ -308,18 +313,18 @@ void settings() {
win_h = 580;
}
size(win_w, win_h, P2D);
-}
-void setup() {
- StringBuilder sb_res = new StringBuilder("Screen Resolution: ");
- sb_res.append(displayWidth);
- sb_res.append(" X ");
- sb_res.append(displayHeight);
+ globalScreenResolution = new StringBuilder("Screen Resolution: ");
+ globalScreenResolution.append(displayWidth);
+ globalScreenResolution.append(" X ");
+ globalScreenResolution.append(displayHeight);
//Account for high-dpi displays on Mac, Windows, and Linux Machines Fixes #968
pixelDensity(displayDensity());
- StringBuilder sb_dpi = new StringBuilder("High-DPI Screen Detected: ");
- sb_dpi.append(displayDensity() == 2);
+ globalScreenDPI = new StringBuilder("High-DPI Screen Detected: ");
+ globalScreenDPI.append(displayDensity() == 2);
+}
+void setup() {
frameRate(120);
copyPaste = new CopyPaste();
@@ -381,15 +386,16 @@ void setup() {
}
println("Console Log Started at Local Time: " + directoryManager.getFileNameDateTime());
- println(sb_res.toString());
- println(sb_dpi.toString());
+ println(globalScreenResolution.toString());
+ println(globalScreenDPI.toString());
println(osName.toString());
println("Welcome to the Processing-based OpenBCI GUI!"); //Welcome line.
- println("For more information, please visit: https://openbci.github.io/Documentation/docs/06Software/01-OpenBCISoftware/GUIDocs");
+ println("For more information, please visit: https://docs.openbci.com/Software/OpenBCISoftware/GUIDocs/");
// Copy sample data to the Users' Documents folder + create Recordings folder
directoryManager.init();
settings = new SessionSettings();
+ guiSettings = new GuiSettings(directoryManager.getSettingsPath());
userPlaybackHistoryFile = directoryManager.getSettingsPath()+"UserPlaybackHistory.json";
//open window
@@ -443,6 +449,9 @@ void delayedSetup() {
setupComplete = true; // signal that the setup thread has finished
println("OpenBCI_GUI::Setup: Setup is complete!");
}
+
+ //Apply GUI-wide settings to front end at the end of setup
+ guiSettings.applySettings();
}
//====================== END-OF-SETUP ==========================//
@@ -644,8 +653,9 @@ void initSystem() {
settings.init();
settings.initCheckPointFive();
} else if (eegDataSource == DATASOURCE_GALEA) {
- //After TopNav has been instantiated, default to Expert mode for Galea
- topNav.configSelector.toggleExpertMode(true);
+ //After TopNav has been instantiated, force Expert mode for Galea by default
+ topNav.configSelector.toggleExpertModeFrontEnd(true);
+ guiSettings.setExpertMode(ExpertModeEnum.ON);
}
//Make sure topNav buttons draw in the correct spot
diff --git a/OpenBCI_GUI/SessionSettings.pde b/OpenBCI_GUI/SessionSettings.pde
index a6fb91bfa..735e73d1a 100644
--- a/OpenBCI_GUI/SessionSettings.pde
+++ b/OpenBCI_GUI/SessionSettings.pde
@@ -25,9 +25,6 @@
// -- read the comments
// -- once you find the right place to add your setting, you can copy the surrounding style
// -- uses JSON keys
-// -- Example: Expert Mode is a global boolean, so we include it under kJSONKeySettings
-// -- We use one variable to load from JSON: loadExpertModeToggle
-// -- And another variable to use in the GUI and with saving to JSON: expertModeToggle
// -- Example2: GUI version and settings version
// -- Requires new JSON key 'version` and settingsVersion
//
@@ -252,8 +249,6 @@ class SessionSettings {
int loadFramerate;
int loadDatasource;
boolean dataSourceError = false;
- //used globally to track and determine if expertMode is on or off
- public boolean expertModeToggle = false;
String saveDialogName; //Used when Save button is pressed
String loadDialogName; //Used when Load button is pressed
@@ -366,7 +361,6 @@ class SessionSettings {
//Make a second JSON object within our JSONArray to store Global settings for the GUI
JSONObject saveGlobalSettings = new JSONObject();
- saveGlobalSettings.setBoolean("Expert Mode", expertModeToggle);
saveGlobalSettings.setInt("Current Layout", currentLayout);
saveGlobalSettings.setInt("Notch", dataProcessing.bsRange.getIndex());
saveGlobalSettings.setInt("Bandpass Filter", dataProcessing.bpRange.getIndex());
@@ -587,7 +581,6 @@ class SessionSettings {
//Load more global settings after this line, if needed
int loadNotchSetting = loadGlobalSettings.getInt("Notch");
int loadBandpassSetting = loadGlobalSettings.getInt("Bandpass Filter");
- Boolean loadExpertModeToggle = loadGlobalSettings.getBoolean("Expert Mode");
Boolean loadDataSmoothingSetting = (currentBoard instanceof SmoothingCapableBoard) ? loadGlobalSettings.getBoolean("Data Smoothing") : null;
//get the FFT settings
@@ -763,10 +756,6 @@ class SessionSettings {
topNav.updateSmoothingButtonText();
}
- //Apply Expert Mode toggle
- //This should not be loaded with other session settings - RW Jan 2021
- //topNav.configSelector.toggleExpertMode(loadExpertModeToggle);
-
//Load and apply all of the settings that are in dropdown menus. It's a bit much, so it has it's own function below.
loadApplyWidgetDropdownText();
diff --git a/OpenBCI_GUI/TopNav.pde b/OpenBCI_GUI/TopNav.pde
index 448dec2b9..0bf18568e 100644
--- a/OpenBCI_GUI/TopNav.pde
+++ b/OpenBCI_GUI/TopNav.pde
@@ -533,21 +533,35 @@ class TopNav {
updateGuiVersionButton = createTNButton("updateGuiVersionButton", text, _x, _y, _w, _h, font, _fontSize, _bg, _textColor);
//Attempt to compare local and remote GUI versions when TopNav is instantiated
//This will also set the description/help-text for this cp5 button
- final Boolean upToDate = guiVersionIsUpToDate();
+ //Do this check on app start and store as a global variable
+ guiIsUpToDate = guiVersionIsUpToDate();
+
updateGuiVersionButton.onRelease(new CallbackListener() {
public void controlEvent(CallbackEvent theEvent) {
- if (upToDate == null) {
+ //Perform check again when button is pressed. User may have connected to internet by now!
+ guiIsUpToDate = guiVersionIsUpToDate();
+
+ if (guiIsUpToDate == null) {
+ outputError("Update GUI: Unable to check for new version of GUI. Try again when connected to the internet.");
return;
}
- if (!upToDate) {
+ if (!guiIsUpToDate) {
openURLInBrowser(guiLatestReleaseLocation);
- outputInfo("Update GUI: Opening latest Github release page using default browser");
+ outputInfo("Update GUI: Opening latest GUI release page using default browser");
} else {
outputSuccess("Update GUI: Local OpenBCI GUI is up-to-date!");
}
}
});
+
+ if (guiIsUpToDate == null) {
+ return;
+ }
+
+ if (!guiIsUpToDate) {
+ outputWarn("Update Available! Press the \"Update\" button at the top of the GUI to download the latest version.");
+ }
}
private void createTopNavSettingsButton(String text, int _x, int _y, int _w, int _h, PFont font, int _fontSize, color _bg, color _textColor) {
@@ -928,11 +942,13 @@ class ConfigSelector {
expertMode.onRelease(new CallbackListener() {
public void controlEvent(CallbackEvent theEvent) {
toggleVisibility();
- toggleExpertMode(!settings.expertModeToggle);
- String outputMsg = settings.expertModeToggle ?
+ boolean isActive = !guiSettings.getExpertModeBoolean();
+ toggleExpertModeFrontEnd(isActive);
+ String outputMsg = isActive ?
"Expert Mode ON: All keyboard shortcuts and features are enabled!" :
"Expert Mode OFF: Use spacebar to start/stop the data stream.";
output(outputMsg);
+ guiSettings.setExpertMode(isActive ? ExpertModeEnum.ON : ExpertModeEnum.OFF);
}
});
expertMode.setDescription("Expert Mode enables advanced keyboard shortcuts and access to all GUI features.");
@@ -960,7 +976,7 @@ class ConfigSelector {
loadSessionSettings.setDescription("Expert Mode enables advanced keyboard shortcuts and access to all GUI features.");
}
- private void createDefaultSettingsButton(String name, String text, int _x, int _y, int _w, int _h) {
+ private void createDefaultSettingsButton(String name, String text, int _x, int _y, int _w, int _h) {
defaultSessionSettings = createButton(settings_cp5, name, text, _x, _y, _w, _h);
defaultSessionSettings.onRelease(new CallbackListener() {
public void controlEvent(CallbackEvent theEvent) {
@@ -971,7 +987,7 @@ class ConfigSelector {
defaultSessionSettings.setDescription("Expert Mode enables advanced keyboard shortcuts and access to all GUI features.");
}
- private void createClearAllSettingsButton(String name, String text, int _x, int _y, int _w, int _h) {
+ private void createClearAllSettingsButton(String name, String text, int _x, int _y, int _w, int _h) {
clearAllGUISettings = createButton(settings_cp5, name, text, _x, _y, _w, _h, p5, 12, BUTTON_CAUTIONRED, WHITE);
clearAllGUISettings.onRelease(new CallbackListener() {
public void controlEvent(CallbackEvent theEvent) {
@@ -985,7 +1001,7 @@ class ConfigSelector {
clearAllGUISettings.setDescription("This will clear all user settings and playback history. You will be asked to confirm.");
}
- private void createClearSettingsNoButton(String name, String text, int _x, int _y, int _w, int _h) {
+ private void createClearSettingsNoButton(String name, String text, int _x, int _y, int _w, int _h) {
clearAllSettingsNo = createButton(settings_cp5, name, text, _x, _y, _w, _h);
clearAllSettingsNo.onRelease(new CallbackListener() {
public void controlEvent(CallbackEvent theEvent) {
@@ -998,7 +1014,7 @@ class ConfigSelector {
});
}
- private void createClearSettingsYesButton(String name, String text, int _x, int _y, int _w, int _h) {
+ private void createClearSettingsYesButton(String name, String text, int _x, int _y, int _w, int _h) {
clearAllSettingsYes = createButton(settings_cp5, name, text, _x, _y, _w, _h);
clearAllSettingsYes.onRelease(new CallbackListener() {
public void controlEvent(CallbackEvent theEvent) {
@@ -1017,17 +1033,13 @@ class ConfigSelector {
clearAllSettingsYes.setDescription("Clicking 'Yes' will delete all user settings and stop the session if running.");
}
- public void toggleExpertMode(boolean b) {
+ public void toggleExpertModeFrontEnd(boolean b) {
if (b) {
expertMode.getCaptionLabel().setText("Turn Expert Mode Off");
expertMode.setColorBackground(BUTTON_EXPERTPURPLE);
- println("GUI Settings: Expert Mode On");
- settings.expertModeToggle = true;
} else {
expertMode.getCaptionLabel().setText("Turn Expert Mode On");
expertMode.setColorBackground(BUTTON_NOOBGREEN);
- println("GUI Settings: Expert Mode Off");
- settings.expertModeToggle = false;
}
}
}
@@ -1160,7 +1172,7 @@ class TutorialSelector {
gettingStarted = createButton(tutorial_cp5, name, text, _x, _y, _w, _h);
gettingStarted.onRelease(new CallbackListener() {
public void controlEvent(CallbackEvent theEvent) {
- openURLInBrowser("https://openbci.github.io/Documentation/docs/01GettingStarted/GettingStartedLanding");
+ openURLInBrowser("https://docs.openbci.com/GettingStarted/GettingStartedLanding/");
toggleVisibility(); //shut layoutSelector if something is selected
}
});
@@ -1171,7 +1183,7 @@ class TutorialSelector {
testingImpedance = createButton(tutorial_cp5, name, text, _x, _y, _w, _h);
testingImpedance.onRelease(new CallbackListener() {
public void controlEvent(CallbackEvent theEvent) {
- openURLInBrowser("https://openbci.github.io/Documentation/docs/06Software/01-OpenBCISoftware/GUIDocs#impedance-testing");
+ openURLInBrowser("https://docs.openbci.com/Software/OpenBCISoftware/GUIDocs/#impedance-testing");
toggleVisibility(); //shut layoutSelector if something is selected
}
});
@@ -1182,7 +1194,7 @@ class TutorialSelector {
troubleshootingGuide = createButton(tutorial_cp5, name, text, _x, _y, _w, _h);
troubleshootingGuide.onRelease(new CallbackListener() {
public void controlEvent(CallbackEvent theEvent) {
- openURLInBrowser("https://docs.openbci.com/docs/10Troubleshooting/GUI_Troubleshooting");
+ openURLInBrowser("https://docs.openbci.com/Troubleshooting/GUI_Troubleshooting/");
toggleVisibility(); //shut layoutSelector if something is selected
}
});
@@ -1193,7 +1205,7 @@ class TutorialSelector {
customWidgets = createButton(tutorial_cp5, name, text, _x, _y, _w, _h);
customWidgets.onRelease(new CallbackListener() {
public void controlEvent(CallbackEvent theEvent) {
- openURLInBrowser("https://openbci.github.io/Documentation/docs/06Software/01-OpenBCISoftware/GUIWidgets#custom-widget");
+ openURLInBrowser("https://docs.openbci.com/Software/OpenBCISoftware/GUIWidgets/#custom-widget");
toggleVisibility(); //shut layoutSelector if something is selected
}
});
diff --git a/OpenBCI_GUI/W_Networking.pde b/OpenBCI_GUI/W_Networking.pde
index fdc55a46e..ad046c017 100644
--- a/OpenBCI_GUI/W_Networking.pde
+++ b/OpenBCI_GUI/W_Networking.pde
@@ -113,7 +113,7 @@ class W_Networking extends Widget {
"obci_eeg1","EEG",
"obci_eeg2","EEG",
"obci_eeg3","EEG"};
- String networkingGuideURL = "https://openbci.github.io/Documentation/docs/06Software/01-OpenBCISoftware/GUIWidgets#networking";
+ String networkingGuideURL = "https://docs.openbci.com/Software/OpenBCISoftware/GUIWidgets/#networking";
String dataOutputsURL = "https://docs.google.com/document/d/e/2PACX-1vR_4DXPTh1nuiOwWKwIZN3NkGP3kRwpP4Hu6fQmy3jRAOaydOuEI1jket6V4V6PG4yIG15H1N7oFfdV/pub";
boolean configIsVisible = false;
boolean layoutIsVisible = false;
@@ -121,7 +121,7 @@ class W_Networking extends Widget {
private LinkedList dataAccumulationQueue;
// accessed by individual streams. yes, i hate it too
public float[][] dataBufferToSend;
- public boolean newDataToSend = false;
+ public boolean newTimeSeriesDataToSend = false;
HashMap cp5Map = new HashMap();
@@ -215,8 +215,6 @@ class W_Networking extends Widget {
if (stream3!=null) {
stream3.run();
}
- //Setting this var here fixes #592 to allow multiple LSL streams
- newDataToSend = false;
}
checkTopNovEvents();
@@ -287,7 +285,8 @@ class W_Networking extends Widget {
}
private void checkIfEnoughDataToSend() {
- if (dataAccumulationQueue.size() >= nPointsPerUpdate) {
+ newTimeSeriesDataToSend = dataAccumulationQueue.size() >= nPointsPerUpdate;
+ if (newTimeSeriesDataToSend) {
for (int iSample=0; iSample