diff --git a/ProcessingGrapher/FileGraph.pde b/ProcessingGrapher/FileGraph.pde index 1e92dc2..e5df276 100644 --- a/ProcessingGrapher/FileGraph.pde +++ b/ProcessingGrapher/FileGraph.pde @@ -121,6 +121,16 @@ class FileGraph implements TabAPI { } + /** + * Set current side menu level + * + * @param newLevel The new menu level + */ + void setMenuLevel(int newLevel) { + menuLevel = newLevel; + } + + /** * Redraw all tab content */ @@ -583,11 +593,19 @@ class FileGraph implements TabAPI { drawButton("Confirm", c_sidebar_button, iL, sT + (uH * 6.5) + iW, iW, iH, tH); drawButton("Cancel", c_sidebar_button, iL, sT + (uH * 7.5) + iW, iW, iH, tH); } + } + + /** + * Draw the btoom information bar + */ + void drawInfoBar() { + int sW = width - cR; textAlign(LEFT, TOP); textFont(base_font); fill(c_status_bar); - text("Input: " + constrainString(currentfile, width - sW - round(30 * uimult) - textWidth("Input: ")), round(5 * uimult), height - round(bottombarHeight * uimult) + round(2*uimult)); + text("Input: " + constrainString(currentfile, width - sW - round(175 * uimult) - textWidth("Input: ")), + round(5 * uimult), height - round(bottombarHeight * uimult) + round(2*uimult)); } diff --git a/ProcessingGrapher/Graph.pde b/ProcessingGrapher/Graph.pde index f24ad90..5af2ab1 100644 --- a/ProcessingGrapher/Graph.pde +++ b/ProcessingGrapher/Graph.pde @@ -680,7 +680,6 @@ class Graph { // Ensure that the element actually exists in data arrays while(lastY.length < type + 1) lastY = append(lastY, Float.MIN_VALUE); while(lastX.length < type + 1) lastX = append(lastX, -xStep); - plotData(dataY, lastX[type] + xStep, type); } @@ -693,7 +692,7 @@ class Graph { */ void plotData(float dataY, float dataX, int type) { int colorIndex = type - (c_colorlist.length * floor(type / c_colorlist.length)); - plotData(dataY, dataX, type, c_colorlist[colorIndex]); + plotData(dataX, dataY, type, c_colorlist[colorIndex]); } /** @} */ diff --git a/ProcessingGrapher/LiveGraph.pde b/ProcessingGrapher/LiveGraph.pde index 2b696a5..8540944 100644 --- a/ProcessingGrapher/LiveGraph.pde +++ b/ProcessingGrapher/LiveGraph.pde @@ -151,6 +151,16 @@ class LiveGraph implements TabAPI { } + /** + * Set current side menu level + * + * @param newLevel The new menu level + */ + void setMenuLevel(int newLevel) { + // Do nothing + } + + /** * Redraw all tab content */ @@ -645,6 +655,7 @@ class LiveGraph implements TabAPI { } // --- Data Recording --- + lock.lock(); TableRow newRow = dataTable.addRow(); //float[] newData = new float[dataArray.length]; @@ -660,6 +671,7 @@ class LiveGraph implements TabAPI { println(" - When parsing live graph data"); } } + lock.unlock(); //graphA.bufferNewData(newData); @@ -679,13 +691,15 @@ class LiveGraph implements TabAPI { int dotPos = outputfile.lastIndexOf("."); String nextoutputfile = outputfile.substring(0, dotPos); nextoutputfile = nextoutputfile + "-" + (fileCounter + 1) + ".csv"; - if (!dataTable.openCSVoutput(nextoutputfile)) { - emergencyOutputSave(true); - } // Ensure table is empty - dataTable = new CustomTable(); + dataTable.clearRows(); drawFrom = 0; + + if (!dataTable.openCSVoutput(nextoutputfile)) { + //emergencyOutputSave(true); + println("Failed to start recording to a new output file"); + } } } else if (!isPaused && !lock.isLocked()) { // Remove rows from table which don't need to be shown on the graphs anymore @@ -843,11 +857,19 @@ class LiveGraph implements TabAPI { if (itemCount == 0) drawText("Empty", c_idletab_text, iL + iW / 2, sT + (uH * (tHnow - itemCount - 0.75)), iW / 2, iH * 3 / 4); } + } + + /** + * Draw the btoom information bar + */ + void drawInfoBar() { + int sW = width - cR; textAlign(LEFT, TOP); textFont(base_font); fill(c_status_bar); - text("Output: " + constrainString(outputfile, width - sW - round(30 * uimult) - textWidth("Output: ")), round(5 * uimult), height - round(bottombarHeight * uimult) + round(2*uimult)); + text("Output: " + constrainString(outputfile, width - sW - round(175 * uimult) - textWidth("Output: ")), + round(5 * uimult), height - round(bottombarHeight * uimult) + round(2*uimult)); } diff --git a/ProcessingGrapher/ProcessingGrapher.pde b/ProcessingGrapher/ProcessingGrapher.pde index 4fddca9..fce677c 100644 --- a/ProcessingGrapher/ProcessingGrapher.pde +++ b/ProcessingGrapher/ProcessingGrapher.pde @@ -7,12 +7,12 @@ * @website https://wired.chillibasket.com/processing-grapher/ * * @copyright GNU General Public License v3 - * @date 2nd September 2022 - * @version 1.5.0 + * @date 5 February 2024 + * @version 1.6.0 * * * * * * * * * * * * * * * * * * * * * * */ /* - * Copyright (C) 2022 - Simon Bluett + * Copyright (C) 2019-2024 - Simon Bluett * * This file is part of ProcessingGrapher * @@ -31,7 +31,7 @@ * along with this program. If not, see . */ -final String versionNumber = "1.5.0"; +final String versionNumber = "1.6.0"; // Swing for input popups import static javax.swing.JOptionPane.*; @@ -523,6 +523,7 @@ void drawProgram() { if (redrawUI){ drawTabs(currentTab); drawSidebar(); + drawInfoBar(); redrawUI = false; } @@ -666,6 +667,100 @@ void drawSidebar () { } +/** + * Draw the Bottom Bar + * + * This function draws the right-side menu area + * for the current tab and the bottom status bar + */ +void drawInfoBar () { + + // Setup drawing parameters + rectMode(CORNER); + noStroke(); + textAlign(CENTER, CENTER); + + // Calculate sizing of info bar + final int sW = round(sidebarWidth * uimult); + final int bW = round(70 * uimult); + final int pW = round(70 * uimult); + final int cW = round(bottombarHeight * uimult); + final int bH = round(bottombarHeight * uimult); + + final int cL = width - sW - pW - cW - bW - round(4*uimult); + final int cR = width - sW - pW - bW - round(4*uimult); + final int pL = width - sW - pW - bW - round(2*uimult); + final int pR = width - sW - bW - round(2*uimult); + final int bL = width - sW - bW - round(0*uimult); + final int bR = width - sW - round(0*uimult); + + // Bottom info area + fill(c_tabbar); + rect(0, height - bH, width - sW + 1, bH); + + // Connected/Disconnected + if (serialConnected) { + fill(c_status_bar); + rect(cL, height - bH, cW, bH); + fill(c_idletab); + circle(cL + (cW / 2) + round(1*uimult), height - (bH / 2) - round(1*uimult), round(6*uimult)); + circle(cL + (cW / 2) - round(1*uimult), height - (bH / 2) + round(1*uimult), round(6*uimult)); + stroke(c_idletab); + strokeWeight(1 * uimult); + line(cL + round(5*uimult), height - round(5*uimult), cR - round(5*uimult), height - bH + round(5*uimult)); + stroke(c_status_bar); + strokeWeight(1 * uimult); + line(cL + round(1*uimult), height - bH + round(1*uimult), cR - round(1*uimult), height - round(1*uimult)); + noStroke(); + } else { + fill(c_idletab); + rect(cL, height - bH, cW, bH); + fill(c_status_bar); + circle(cL + (cW / 2) + round(2*uimult), height - (bH / 2) - round(2*uimult), round(6*uimult)); + circle(cL + (cW / 2) - round(2*uimult), height - (bH / 2) + round(2*uimult), round(6*uimult)); + stroke(c_status_bar); + strokeWeight(1 * uimult); + line(cL + round(5*uimult), height - round(5*uimult), cR - round(5*uimult), height - bH + round(5*uimult)); + stroke(c_idletab); + strokeWeight(5 * uimult); + line(cL + round(2*uimult), height - bH + round(2*uimult), cR - round(2*uimult), height - round(2*uimult)); + stroke(c_status_bar); + strokeWeight(1 * uimult); + line(cL + round(7*uimult), height - bH + round(7*uimult), cR - round(7*uimult), height - round(7*uimult)); + noStroke(); + } + + // Serial port + String[] ports = Serial.list(); + fill(c_idletab); + rect(pL, height - bH, pW, bH); + textAlign(CENTER, TOP); + textFont(base_font); + fill(c_status_bar); + String portString = ports[portNumber]; + if (currentPort != "") portString = currentPort; + portString = constrainString(portString, pW * 3 / 4); + text(portString, pL + (pW / 2), height - bH + round(2*uimult)); + + // Baud rates + fill(c_idletab); + rect(bL, height - bH, bW, bH); + textAlign(CENTER, TOP); + textFont(base_font); + fill(c_status_bar); + text(str(baudRate), bL + (bW / 2), height - bH + round(2*uimult)); + + // Bar outline + fill(c_tabbar_h); + rect(0, height - bH, width - sW + round(1*uimult), round(1 * uimult)); + + if (tabObjects.size() > currentTab) { + TabAPI curTab = tabObjects.get(currentTab); + curTab.drawInfoBar(); + } else currentTab = 0; +} + + /** * Draw the loading screen which is shown during start-up */ @@ -1169,6 +1264,42 @@ void mousePressed(){ } } + // If mouse is over the info bar + else if ((mouseY > height - (bottombarHeight * uimult)) && (mouseX < width - (sidebarWidth * uimult))) { + // Calculate sizing of info bar + final int sW = round(sidebarWidth * uimult); + final int bW = round(70 * uimult); + final int pW = round(70 * uimult); + final int cW = round(bottombarHeight * uimult); + + final int cL = width - sW - pW - cW - bW - round(4*uimult); + final int cR = width - sW - pW - bW - round(4*uimult); + final int pL = width - sW - pW - bW - round(2*uimult); + final int pR = width - sW - bW - round(2*uimult); + final int bL = width - sW - bW - round(0*uimult); + final int bR = width - sW - round(0*uimult); + + // Connect/disconnect button + if ((mouseX >= cL) && (mouseX <= cR)) { + setupSerial(); + redrawUI = true; + redrawContent = true; + // Port selection button + } else if ((mouseX >= pL) && (mouseX <= pR)) { + currentTab = 0; + tabObjects.get(currentTab).setMenuLevel(1); + redrawContent = true; + redrawUI = true; + // Baud rate selection button + } else if ((mouseX >= bL) && (mouseX <= bR)) { + currentTab = 0; + tabObjects.get(currentTab).setMenuLevel(2); + redrawContent = true; + redrawUI = true; + } + + } + // If mouse is hovering over the side bar else if ((mouseX > width - (sidebarWidth * uimult)) && (mouseX < width)) { thread("menuClickEvent"); @@ -1759,6 +1890,9 @@ void checkSerialPortList() { setupSerial(); alertMessage("Error\nThe serial port has been disconnected"); } + //else if (serialConnected) { + // serialSend("1,2,3,4,5"); + //} if (different) { redrawUI = true; @@ -2373,7 +2507,8 @@ interface TabAPI { void drawContent(); void drawNewData(); void drawSidebar(); - + void drawInfoBar(); + // Mouse clicks void menuClick (int xcoord, int ycoord); void contentClick (int xcoord, int ycoord); @@ -2382,7 +2517,7 @@ interface TabAPI { // Keyboard input void keyboardInput(char keyChar, int keyCodeInt, boolean codedKey); - + // Change content area size void changeSize(int newL, int newR, int newT, int newB); @@ -2394,7 +2529,10 @@ interface TabAPI { void connectionEvent(boolean status); void parsePortData(String inputData, boolean graphable); + // Set menu settings + void setMenuLevel(int newLevel); + // Exit function boolean checkSafeExit(); void performExit(); -} \ No newline at end of file +} diff --git a/ProcessingGrapher/SerialMonitor.pde b/ProcessingGrapher/SerialMonitor.pde index bb46669..711dcaa 100644 --- a/ProcessingGrapher/SerialMonitor.pde +++ b/ProcessingGrapher/SerialMonitor.pde @@ -173,6 +173,16 @@ class SerialMonitor implements TabAPI { } + /** + * Set current side menu level + * + * @param newLevel The new menu level + */ + void setMenuLevel(int newLevel) { + menuLevel = newLevel; + } + + /** * Redraw all tab content */ @@ -770,12 +780,19 @@ class SerialMonitor implements TabAPI { drawButton("Confirm", c_sidebar_button, iL, sT + (uH * 6.5) + iW, iW, iH, tH); drawButton("Cancel", c_sidebar_button, iL, sT + (uH * 7.5) + iW, iW, iH, tH); } + } + - // Draw bottom info bar + /** + * Draw the btoom information bar + */ + void drawInfoBar() { + int sW = width - cR; textAlign(LEFT, TOP); textFont(base_font); fill(c_status_bar); - text("Output: " + constrainString(outputfile, width - sW - round(30 * uimult) - textWidth("Output: ")), round(5 * uimult), height - round(bottombarHeight * uimult) + round(2*uimult)); + text("Output: " + constrainString(outputfile, width - sW - round(175 * uimult) - textWidth("Output: ")), + round(5 * uimult), height - round(bottombarHeight * uimult) + round(2*uimult)); } diff --git a/ProcessingGrapher/Settings.pde b/ProcessingGrapher/Settings.pde index a2d18e3..1cc21e6 100644 --- a/ProcessingGrapher/Settings.pde +++ b/ProcessingGrapher/Settings.pde @@ -101,6 +101,16 @@ class Settings implements TabAPI { } + /** + * Set current side menu level + * + * @param newLevel The new menu level + */ + void setMenuLevel(int newLevel) { + menuLevel = newLevel; + } + + /** * Redraw all tab content */ @@ -449,6 +459,14 @@ class Settings implements TabAPI { } + /** + * Draw the btoom information bar + */ + void drawInfoBar() { + // Empty + } + + /** * Check whether settings are different than the default * diff --git a/ProcessingGrapher/data/user-preferences.xml b/ProcessingGrapher/data/user-preferences.xml index 6e251c0..ff43411 100644 --- a/ProcessingGrapher/data/user-preferences.xml +++ b/ProcessingGrapher/data/user-preferences.xml @@ -4,5 +4,5 @@ - +