// from https://discourse.processing.org/t/closed-user-types-codes-special-strings-if-correct-something-happends
// A Console.
// The main program can send to console.
// Use commands like: Hello circle rect fill dump quit help show.
// Search for "Add your" here in the code to see where you can add more commands (3 major occurances with ****).
// The main class
Console console;
// help text in yellow box
final String helpText =
"My little Console \n\n"
+"Hit PgUp to toggle this help text.\n"
+"Type text.\n"
+"Hit enter to go to the next line.\n"
+"Cursor up to copy previous line.\n"
+"Use Backspace.\n"
+"Try to type Hello and dump\n"
+"Try circle 33 or circle x y r; circle help.\n"
+"Try rect 33 or rect x y r; rect help.\n"
+"Try fill/fill help and quit, show, clear.\n"
+"Esc is disabled; use Alt-F4 instead.";
// yellow box height
final int heightYellowBox = 234;
// show the yellow box yes/ no (PgUp)
boolean showYellowHelpBoxFlag = true;
// when we switch off the yellow box, this text is displayed
final String errMsgForShowYellowHelpBoxFlag = "Hit PgUp to toggle the yellow box help text.";
// help texts for cmds
final String strCircleHelp = "circle can be used as: circle, circle radius, circle x y, circle x y r or circle x y w h. Example: circle 111.";
final String strRectHelp = "rect can be used as: rect, rect radius, rect x y, rect x y r or rect x y w h. Example: rect 111.";
final String strFillHelp = "fill can be used as: fill (just gives blue), fill GRAY-value (0..255), fill Red Green Blue. Example: fill 111.";
final String strQuestionMarkHelp = "? can be used instead of help: ?fill or ?rect or ? circle";
final String strGeneralHelp1 = "Commands are help, quit, dump, show, fill, rect and circle.";
final String strGeneralHelp2 = "With some Commands, use ?rect etc. to get help for the command.";
final String strShowHelp = "The command 'show' dumps only the internal list with your draw commands.";
final String strClearHelp = "The command 'clear' clears the internal list with your draw commands.";
// list of commands
ArrayList<String> listCmds = new ArrayList();
// error
String errMsg="";
// help
String helpMsg="";
// --------------------------------------------
// Processing Core Functions
void setup() {
size(660, 660);
background(255);
console = new Console(9, height-130, width-18, 125);
// console = new Console(9, height-330, 160, 310);
console.send("Hello.");
}//setup()
void draw() {
background(255);
// show yellow box with help text
showHelpText();
// parse list of commands - draws rect and circles
parseList();
// show console
console.showTextArrayConsole();
// show error text in red
showErrorMessage();
// show help message
showHelpMessage();
}//draw()
// ------------------------------------------
// Inputs Keyboard
void keyPressed() {
// eval key
// println (keyCode);
if (keyCode==33) {
// PG Up
showYellowHelpBoxFlag = !showYellowHelpBoxFlag;
if (!showYellowHelpBoxFlag) {
errMsg=errMsgForShowYellowHelpBoxFlag;
}//if
else {
if (errMsg.equals(errMsgForShowYellowHelpBoxFlag))
errMsg="";
}//else
} //if
else
{
// eval key
sendKeyToConsole();
}//else
}//keyPressed()
// ------------------------------------------
// Main Tools ; Inputs
void sendKeyToConsole() {
// we send the key to the console.
// The return value is true for RETURN or false for any other key.
if (console.keyPressedConsole()) {
// return was pressed
// eval the last line
evalTheLastLine();
} else {
// Any other key than return was pressed
// Show help during typing
evalTheCurrentLine();
}//else
}//sendKeyToConsole()
void evalTheLastLine() {
// Evaluates the last line of the console (after ENTER has been pressed)
// reset
errMsg="";
// Delete the help msg (reset)
helpMsg="";
// *********************************************************************
// Add your commands here **********************************************
// *********************************************************************
// We check the last line.
// We use
// * console.lastLineIs("Hello") for entire line check and
// * console.lastLineStartsWith("circle ") for the beginning of a line (when parameters follow like in circle 120).
//
// The shorter a command is, the further back in the if..else if.. list it has to be ( console.lastLineStartsWith("circle help") BEFORE console.lastLineStartsWith("circle").
// Commands like circle that draw on the screen need to be added to the listCmds: listCmds.add(console.lastLine); because background is used in draw() and deletes the canvas.
// You want to add your commands here and to parseList().
//
if (console.lastLineIs("Hello")||console.lastLineIs("hello")) {
// Hello
console.send("Hello to you, too");
} else if (console.lastLineIs("show")) {
// show
showCmdList();
} else if (console.lastLineIs("clear")) {
// show
console.dump();
listCmds.clear();
console.send("I dumped and cleared the draw commands list.");
} else if (console.lastLineIs("dump")) {
console.send("I dump the console. (dump as file AND as println)");
console.dump();
} else if (console.lastLineIs("help circle")||
console.lastLineIs("circle help")||
console.lastLineIs("circle?")||
console.lastLineIs("?circle")||
console.lastLineIs("circle ?")||
console.lastLineIs("? circle")) {
// we show help for circle
console.send(strCircleHelp);
} else if (console.lastLineIs("help fill")||
console.lastLineIs("fill help")||
console.lastLineIs("fill?")||
console.lastLineIs("?fill")||
console.lastLineIs("fill ?")||
console.lastLineIs("? fill")) {
// we show help for fill
console.send(strFillHelp);
} else if (console.lastLineIs("help rect")||
console.lastLineIs("rect help")||
console.lastLineIs("rect?")||
console.lastLineIs("?rect")||
console.lastLineIs("rect ?")||
console.lastLineIs("? rect")) {
// we show help for rect
console.send(strRectHelp);
} else if (console.lastLineIs("help rect")||
console.lastLineIs("? help")||
console.lastLineIs("??")||
console.lastLineIs("?")||
console.lastLineIs("? ?")||
console.lastLineIs("? ?")) {
// we show help for ?
console.send(strQuestionMarkHelp);
}
//
else if (console.lastLineStartsWith("circle")) {
// we add this to a list of commands
listCmds.add(console.lastLine);
}//
else if (console.lastLineStartsWith("rect")) {
// we add this to a list of commands
listCmds.add(console.lastLine);
}//
else if (console.lastLineStartsWith("fill")) {
// we add this to a list of commands
listCmds.add(console.lastLine);
}//
else if (console.lastLineStartsWith("help")) {
//
// we show help (2 lines)
console.send(strGeneralHelp1);
console.send(strGeneralHelp2);
}//
else if (console.lastLineStartsWith("quit")) {
//
console.send("I dump the console. (dump as file AND as println)");
console.dump();
exit();
}//
else {
errMsg="Unknown command";
}
}//evalTheLastLine()
void evalTheCurrentLine() {
// eval the line that is typed at the moment (before hitting Enter).
// eval throughout (not only when Enter has been hit)
// *********************************************************************
// Add your help here **********************************************
// *********************************************************************
if (console.currentLine.equals("")) {
helpMsg = "";//reset
} else if (console.isStringAtTheBeginningOfTheCurrentLine("circle")) {
helpMsg = strCircleHelp;
} else if (console.isStringAtTheBeginningOfTheCurrentLine("fill")) {
helpMsg = strFillHelp;
} else if (console.isStringAtTheBeginningOfTheCurrentLine("rect")) {
helpMsg = strRectHelp;
} else if (console.isStringAtTheBeginningOfTheCurrentLine("show")) {
helpMsg = strShowHelp;
} else if (console.isStringAtTheBeginningOfTheCurrentLine("clear")) {
helpMsg = strClearHelp;
} else if (console.isStringAtTheBeginningOfTheCurrentLine("help")) {
// 2 lines
helpMsg = strGeneralHelp1
+"\n"
+strGeneralHelp2;
} else if ("?".indexOf(console.currentLine) == 0) {
helpMsg = strQuestionMarkHelp;
}
// ---
else {
helpMsg = ""; // reset
}//else
}//func
// --------------------------------------------------------------
// list of commands
void showCmdList() {
//
for (String lineOfTheForLoop : listCmds) {
println(lineOfTheForLoop);
}//for
String remark1="";
if (listCmds.size()==0)
remark1=" List is empty at the moment.";
console.send("List of Commands are dumped in the processing console."
+remark1);
}//func
void parseList() {
// parsing the cmd list
// *********************************************************************
// Add your PERSISTENT commands here ***********************************
// *********************************************************************
fill(255, 0, 0); // RED
for (String lineOfTheForLoop : listCmds) {
// 1. circle command
if (lineOfTheForLoop.indexOf("circle")==0) {
String line = lineOfTheForLoop.replace("circle", "");
line = line.trim();
// empty?
if (line.equals("")) {
// 0 params
ellipse(width/2, height/2, 33, 33); // default circle
}//if
else {
String[] params = split(line, " ");
// Different number of params:
if (params.length==3)
ellipse(float(params[0]), float(params[1]), float(params[2]), float(params[2]));
else if (params.length==2)
ellipse(float(params[0]), float(params[1]), 33, 33);
else if (params.length==1)
ellipse(width/2, height/2, float(params[0]), float(params[0]));
else if (params.length==4)
ellipse(float(params[0]), float(params[1]), float(params[2]), float(params[3]));
else {
errMsg = "Circle command says unknown number of parameters("
+params.length
+"): "
+ lineOfTheForLoop;
}//else
}//else
}//if
//
// 2. rect command
else if (lineOfTheForLoop.indexOf("rect")==0) {
String line = lineOfTheForLoop.replace("rect", "");
line = line.trim();
// empty?
if (line.equals("")) {
// 0 params
rect(width/2, height/2, 33, 33); // default rect
}//if
else {
String[] params = split(line, " ");
// Different number of params:
if (params.length==3)
rect(float(params[0]), float(params[1]), float(params[2]), float(params[2]));
else if (params.length==2)
rect(float(params[0]), float(params[1]), 33, 33);
else if (params.length==1)
rect(width/2, height/2, float(params[0]), float(params[0]));
else if (params.length==4)
rect(float(params[0]), float(params[1]), float(params[2]), float(params[3]));
else {
errMsg = "rect command says unknown number of parameters("
+params.length
+"): "
+ lineOfTheForLoop;
}//else
}//else
}//else if
//
// 3. fill command
else if (lineOfTheForLoop.indexOf("fill")==0) {
String line = lineOfTheForLoop.replace("fill", "");
line = line.trim();
// empty?
if (line.equals("")) {
// 0 params
fill(0, 0, 255); // default : blue
}//if
else {
String[] params = split(line, " ");
// Different number of params:
if (params.length==3)
fill(int(params[0]), int(params[1]), int(params[2])); // RGB
else if (params.length==1)
fill(float(params[0])); // GRAY
else {
errMsg = "fill command says unknown number of parameters("
+params.length
+"): "
+ lineOfTheForLoop;
}//else
}//else
}//else if
//
}//for
//
}//func
// ------------------------------------------
// Minor Tools: Text and messages
void showHelpText() {
// Yellow box and text
if (!showYellowHelpBoxFlag) {
return; // leave here
}
// Yellow box
fill(#F6FA1C); // Yellow
stroke(0); // Black
rect(width-225, 3,
210, heightYellowBox);
// Black text
fill(0); // Black
textSize(12);
text(helpText,
width-220, 20);
textSize(14);
}
void showErrorMessage() {
// show error msg
fill(255, 0, 0); // red
text(errMsg,
console.xBoxConsole+10, console.yBoxConsole-23);
}
void showHelpMessage() {
// show help msg in white
// when there is no help msg, we leave here
if (helpMsg.equals(""))
return; // leave here
// The box for the help text
float x = console.xBoxConsole+133;
float y = console.yBoxConsole-123;
float w = 224;
float h = 62;
// for longer text we can make the box higher
if (helpMsg.length()>110) {
h=82;
}
// draw 2 lines as a right angle
stroke(0);
// line left <-
line(x-1, y+h/2,
console.xBoxConsole+4, y+h/2);
// line down |
line(console.xBoxConsole+4, y+h/2,
console.xBoxConsole+4, console.yBoxConsole-4);
// draw box
noFill();
rect(x, y,
w, h);
// draw text
fill( 0); //black
text(helpMsg,
x+4, y+1,
w-2, h+10);
}
// =======================================================================================
class Console {
// Pos of box
float xBoxConsole, yBoxConsole;
// writing pos inside box
float xWriteConsole, yWriteConsole;
// w and h
float wConsole, hConsole;
// space between lines
int lineSpaceConsole=22;
//font
PFont fontEditor;
// Editor variables
String[] lines = new String[300];
int lineCounter1 = 0; // current line number
String lastLine=""; // after hitting Enter
String currentLine=""; // before hitting Enter
// cursor sign blinks
boolean cursorBlinkFlag;
int timerCursorBlink;
DateTimeTool dateTimeTool = new DateTimeTool();
// constr
Console( float x_, float y_,
float w_, float h_) {
xBoxConsole=x_;
yBoxConsole=y_;
xWriteConsole = xBoxConsole+3;
yWriteConsole = yBoxConsole+20;
wConsole=w_;
hConsole=h_;
fontEditor = createFont("ARIAL", 14);
textFont(fontEditor);
lines[lineCounter1]="";
}// constr
void showTextArrayConsole() {
// The text field
// box
fill(190); // gray
stroke(0); // Black
rect(xBoxConsole, yBoxConsole,
wConsole, hConsole);
// Text
fill(0); // black
// for loop
int start=lineCounter1- int((hConsole-25) / lineSpaceConsole);
if (start<0)
start=0;
int stop=lines.length;
int lineCounterForLoop=0;
for (int i=start; i<stop+1; i++) {
if ((lineCounterForLoop*lineSpaceConsole+yWriteConsole) > hConsole-10+yBoxConsole) {
break;
}
if (lines[i]!=null) {
text(lines[i],
xWriteConsole, lineCounterForLoop*lineSpaceConsole+yWriteConsole);
showBlinkingCursor(lines[i], i, lineCounterForLoop);
}//if
lineCounterForLoop++;
}//for
//
}//func
// ------------------------------------
boolean lastLineIs(String line_) {
// equality
return lastLine.equals(line_);
}// method
boolean lastLineStartsWith(String line_) {
// Is the param line_ present at start of last line? Rest of line is ignored
return lastLine.indexOf(line_) == 0;
}// method
boolean isStringAtTheBeginningOfTheCurrentLine(String line_) {
// This is checking if line_ (e.g. circle) is at the start of the line that is cuurently entered (console.currentLine)
if (line_==null)
return false;
int lenLine = line_.length();
lenLine = min(lenLine, currentLine.length());
String compare1 = currentLine.substring(0, lenLine);
return line_.indexOf(compare1) == 0;
}//func
// ------------------------------------
void send(String line_) {
lines[lineCounter1]=line_;
lineCounter1++; // pitfall ???
lines[lineCounter1]="";
}//method
boolean keyPressedConsole() {
// eval key
// The return value is true for return or false for any other key.
boolean result=false;
if (key==CODED) {
//CODED
result=keyPressedConsoleForCodedKeys();
} else {
//not CODED
result=keyPressedConsoleForNotCodedKeys();
}
//
currentLine = lines[lineCounter1];
return result;
//
} // keyPressedConsole()
// ----
boolean keyPressedConsoleForCodedKeys() {
// Coded
// CURSOR KEYS
if (keyCode==UP) {
// copy prev line
if (lineCounter1>0) {
lines[lineCounter1]=lines[lineCounter1-1];
}
} else if (keyCode==DOWN) {
// ignore
} else if (keyCode==LEFT) {
// ignore
} else if (keyCode==RIGHT) {
// ignore
}
// IGNORE
else if (keyCode==ALT) {
// ignore
} else if (keyCode==CONTROL) {
// ignore
} else if (keyCode==SHIFT) {
// ignore
}
// IGNORE
else {
// ignore
} //else
return false;
}//func
boolean keyPressedConsoleForNotCodedKeys() {
// not Coded
if ( keyCode == ENTER || keyCode == RETURN ) {
// new line
lastLine=lines[lineCounter1];
lineCounter1++; // pitfall ???
lines[lineCounter1]="";
currentLine=""; // (it's deleted below as well)
return true;
}//if
// Backspace and Escape keys
else if (keyCode==BACKSPACE) {
lines[lineCounter1] = shortenStringByOneSign(lines[lineCounter1]);
} else if (key==ESC) {
key=0; // kill ESC, stay in the program
}
// LETTERS - the usual input
else if (keyCode>0||key=='?') { // was: else if (keyCode>30||key=='?') {
// normal text input
lines[lineCounter1] += key;
} else {
// ignore
}//else
return false;
}//func
// ----
String shortenStringByOneSign( String strIn_) {
if (strIn_.length()>0)
return
strIn_.substring( 0, strIn_.length()-1 );
else
return strIn_;
}
void showBlinkingCursor(String oneLine, int i, int lineCounterForLoop) {
// manage and show the red Blinking Cursor |
// Is it the current/active line?
if (i==lineCounter1 && cursorBlinkFlag) {
// show text cursor
fill(255, 0, 0); // RED
text("|",
xWriteConsole + textWidth(oneLine), lineCounterForLoop*lineSpaceConsole+yWriteConsole);
// back to normal
fill(0);
}//if
// timer to toggle the flag cursorBlinkFlag
if (millis()-timerCursorBlink > 330) {
cursorBlinkFlag = !cursorBlinkFlag; // toggle
timerCursorBlink = millis();
}//if
}
void dump() {
// dump as file AND as println
String dateTimeStampShort=dateTimeTool.dateTimeStampShort();
// here he should import a new array without null....
saveStrings( "result"+dateTimeStampShort+".txt", lines);
int stop=lines.length;
for (int i=0; i<stop; i++) {
if (lines[i]!=null) {
println( lines[i] );
}
}
}//method
//
}//class
//
//------------------------------------------------------
class DateTimeTool {
String dateTimeStampShort() {
// short version
return getDate() + "_" + getTime();
}
String dateTimeStampLong() {
// long version
return getDateLong()
+ " at "
+ getTimeLong();
}
//-----
String getTime() {
return leadingZeros(hour())
+ leadingZeros(minute())
+ leadingZeros(second());
}
String getTimeLong() {
return leadingZeros(hour())
+":"+ leadingZeros(minute())
+":"+ leadingZeros(second());
}
String getDate() {
return leadingZeros(year())
+ leadingZeros(month())
+ leadingZeros(day());
}
String getDateLong() {
return leadingZeros(year())
+"/"+ leadingZeros(month())
+"/"+ leadingZeros(day());
}
//-----
String leadingZeros(int a) {
String Buffer;
Buffer=nf(a, 2);
return(Buffer);
}
//
}//class
//