Combines locate fix, show/hide cursor + Justin Jordans additions

Fork of Terminal by Justin Jordan

Committer:
j3
Date:
Sat Mar 25 19:10:15 2017 +0000
Revision:
8:9ab22fc6e88b
Parent:
7:aa29b7e10cd8
Child:
9:45fba42a98aa
Updated get user input fxs to support systems that use CR+LF, CR, or just LF.;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
simon 1:96ae39e58792 1 /* mbed Terminal Library, for ANSI/VT200 Terminals and ecape codes
simon 2:85184c13476c 2 * Copyright (c) 2007-2010, sford, http://mbed.org
simon 1:96ae39e58792 3 *
simon 1:96ae39e58792 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
simon 1:96ae39e58792 5 * of this software and associated documentation files (the "Software"), to deal
simon 1:96ae39e58792 6 * in the Software without restriction, including without limitation the rights
simon 1:96ae39e58792 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
simon 1:96ae39e58792 8 * copies of the Software, and to permit persons to whom the Software is
simon 1:96ae39e58792 9 * furnished to do so, subject to the following conditions:
simon 1:96ae39e58792 10 *
simon 1:96ae39e58792 11 * The above copyright notice and this permission notice shall be included in
simon 1:96ae39e58792 12 * all copies or substantial portions of the Software.
simon 1:96ae39e58792 13 *
simon 1:96ae39e58792 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
simon 1:96ae39e58792 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
simon 1:96ae39e58792 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
simon 1:96ae39e58792 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
simon 1:96ae39e58792 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
simon 1:96ae39e58792 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
simon 1:96ae39e58792 20 * THE SOFTWARE.
simon 0:2bf27af3c759 21 */
simon 0:2bf27af3c759 22
simon 0:2bf27af3c759 23 #include "Terminal.h"
simon 0:2bf27af3c759 24
j3 3:7c269f52ad77 25 Terminal::Terminal(PinName tx, PinName rx) : Serial(tx, rx){}
simon 0:2bf27af3c759 26
simon 0:2bf27af3c759 27 void Terminal::cls() {
simon 0:2bf27af3c759 28 this->printf("\033[2J");
simon 0:2bf27af3c759 29 }
simon 0:2bf27af3c759 30
j3 4:4510b10fb5d9 31 void Terminal::home(){
j3 4:4510b10fb5d9 32 this->printf("\033[H");
j3 4:4510b10fb5d9 33 }
j3 4:4510b10fb5d9 34
simon 0:2bf27af3c759 35 void Terminal::locate(int column, int row) {
simon 0:2bf27af3c759 36 // Cursor Home <ESC>[{ROW};{COLUMN}H
simon 0:2bf27af3c759 37 this->printf("\033[%d;%dH%c", row + 1, column + 1);
simon 0:2bf27af3c759 38 }
simon 0:2bf27af3c759 39
simon 0:2bf27af3c759 40 static int rgb888tobgr111(int colour) {
simon 0:2bf27af3c759 41 int r = (colour >> 23) & 1;
simon 0:2bf27af3c759 42 int g = (colour >> 15) & 1;
simon 0:2bf27af3c759 43 int b = (colour >> 7) & 1;
simon 0:2bf27af3c759 44 return (b << 2) | (g << 1) | (r << 0);
simon 0:2bf27af3c759 45 }
simon 0:2bf27af3c759 46
simon 0:2bf27af3c759 47 void Terminal::foreground(int colour) {
simon 0:2bf27af3c759 48 // Set Attribute Mode <ESC>[{n}m
simon 0:2bf27af3c759 49 // Foreground Colours : 30 + bgr
simon 0:2bf27af3c759 50 int c = 30 + rgb888tobgr111(colour);
simon 0:2bf27af3c759 51 this->printf("\033[%dm", c);
simon 0:2bf27af3c759 52 }
simon 0:2bf27af3c759 53
simon 0:2bf27af3c759 54 void Terminal::background(int colour) {
simon 0:2bf27af3c759 55 // Set Attribute Mode <ESC>[{n}m
simon 0:2bf27af3c759 56 // Background Colours : 40 + bgr
simon 0:2bf27af3c759 57 int c = 40 + rgb888tobgr111(colour);
simon 0:2bf27af3c759 58 this->printf("\033[%dm", c);
simon 0:2bf27af3c759 59 }
j3 3:7c269f52ad77 60
j3 3:7c269f52ad77 61 int32_t Terminal::get_int32(const char *msg, const int32_t min_val, const int32_t max_val)
j3 3:7c269f52ad77 62 {
j3 3:7c269f52ad77 63 int32_t user_input;
j3 8:9ab22fc6e88b 64 //mbed uses C++ 2003 so no benifit in using C++ string for this fx
j3 3:7c269f52ad77 65 char str[12];
j3 8:9ab22fc6e88b 66 uint8_t idx = 0;
j3 8:9ab22fc6e88b 67
j3 8:9ab22fc6e88b 68 do
j3 8:9ab22fc6e88b 69 {
j3 8:9ab22fc6e88b 70 //print prompt
j3 8:9ab22fc6e88b 71 this->printf(msg);
j3 8:9ab22fc6e88b 72
j3 8:9ab22fc6e88b 73 //get user input
j3 8:9ab22fc6e88b 74 idx = 0;
j3 8:9ab22fc6e88b 75 do
j3 8:9ab22fc6e88b 76 {
j3 8:9ab22fc6e88b 77 //wait for first char
j3 8:9ab22fc6e88b 78 do
j3 8:9ab22fc6e88b 79 {
j3 8:9ab22fc6e88b 80 if(this->readable())
j3 8:9ab22fc6e88b 81 {
j3 8:9ab22fc6e88b 82 str[idx++] = this->getc();
j3 8:9ab22fc6e88b 83 }
j3 8:9ab22fc6e88b 84 }
j3 8:9ab22fc6e88b 85 while(idx == 0);
j3 8:9ab22fc6e88b 86 }
j3 8:9ab22fc6e88b 87 while((str[idx - 1] != 0x0A) && (str[idx - 1] != 0x0D) && (idx < 12));
j3 8:9ab22fc6e88b 88
j3 8:9ab22fc6e88b 89 //wait for possible additional char on windows machines
j3 8:9ab22fc6e88b 90 //at even the slowest of baudrates, hopefully.
j3 8:9ab22fc6e88b 91 //need a better way...
j3 8:9ab22fc6e88b 92 wait_ms(50);
j3 8:9ab22fc6e88b 93
j3 8:9ab22fc6e88b 94 //gobble up trailing LF if there
j3 8:9ab22fc6e88b 95 while(this->readable())
j3 8:9ab22fc6e88b 96 {
j3 8:9ab22fc6e88b 97 this->getc();
j3 8:9ab22fc6e88b 98 }
j3 8:9ab22fc6e88b 99
j3 8:9ab22fc6e88b 100 //replace CR or LF with \0
j3 8:9ab22fc6e88b 101 str[idx - 1] = '\0';
j3 8:9ab22fc6e88b 102 //convert str into int
j3 8:9ab22fc6e88b 103 user_input = atoi(str);
j3 8:9ab22fc6e88b 104
j3 8:9ab22fc6e88b 105 if((user_input < min_val) || (user_input > max_val))
j3 8:9ab22fc6e88b 106 {
j3 8:9ab22fc6e88b 107 this->printf("\r\nYou entered = %d\r\n", user_input);
j3 8:9ab22fc6e88b 108 this->printf("\r\nOut of range\r\n");
j3 8:9ab22fc6e88b 109 }
j3 8:9ab22fc6e88b 110 }
j3 8:9ab22fc6e88b 111 while((user_input < min_val) || (user_input > max_val));
j3 8:9ab22fc6e88b 112
j3 8:9ab22fc6e88b 113 return(user_input);
j3 8:9ab22fc6e88b 114 }
j3 8:9ab22fc6e88b 115
j3 8:9ab22fc6e88b 116 char Terminal::get_char(const char *msg, const char min_val, const char max_val)
j3 8:9ab22fc6e88b 117 {
j3 8:9ab22fc6e88b 118 //mbed uses C++ 2003 so no benifit in using C++ string for this fx
j3 8:9ab22fc6e88b 119 char c[3];
j3 8:9ab22fc6e88b 120 uint8_t idx = 0;
j3 3:7c269f52ad77 121
j3 3:7c269f52ad77 122 do
j3 3:7c269f52ad77 123 {
j3 3:7c269f52ad77 124 this->printf(msg);
j3 3:7c269f52ad77 125
j3 3:7c269f52ad77 126 //get user input
j3 3:7c269f52ad77 127 idx = 0;
j3 3:7c269f52ad77 128 do
j3 3:7c269f52ad77 129 {
j3 8:9ab22fc6e88b 130 //wait for first char
j3 8:9ab22fc6e88b 131 do
j3 3:7c269f52ad77 132 {
j3 8:9ab22fc6e88b 133 if(this->readable())
j3 8:9ab22fc6e88b 134 {
j3 8:9ab22fc6e88b 135 c[idx++] = this->getc();
j3 8:9ab22fc6e88b 136 }
j3 3:7c269f52ad77 137 }
j3 8:9ab22fc6e88b 138 while(idx == 0);
j3 3:7c269f52ad77 139 }
j3 8:9ab22fc6e88b 140 while((c[idx-1] != 0x0A) && (c[idx-1] != 0x0D) && (idx < 3));
j3 3:7c269f52ad77 141
j3 8:9ab22fc6e88b 142 //wait for possible additional char on windows machines
j3 8:9ab22fc6e88b 143 //at even the slowest of baudrates, hopefully.
j3 8:9ab22fc6e88b 144 //need a better way...
j3 8:9ab22fc6e88b 145 wait_ms(50);
j3 8:9ab22fc6e88b 146
j3 8:9ab22fc6e88b 147 //gobble up trailing LF if there
j3 8:9ab22fc6e88b 148 while(this->readable())
j3 3:7c269f52ad77 149 {
j3 8:9ab22fc6e88b 150 this->getc();
j3 3:7c269f52ad77 151 }
j3 3:7c269f52ad77 152
j3 8:9ab22fc6e88b 153 //replace CR or LF with \0
j3 8:9ab22fc6e88b 154 c[idx - 1] = '\0';
j3 3:7c269f52ad77 155
j3 3:7c269f52ad77 156
j3 3:7c269f52ad77 157 if((c[0] < min_val) || (c[0] > max_val))
j3 3:7c269f52ad77 158 {
j3 3:7c269f52ad77 159 this->printf("\nYou entered = %c\n", c[0]);
j3 3:7c269f52ad77 160 this->printf("\nOut of range\n");
j3 3:7c269f52ad77 161 }
j3 3:7c269f52ad77 162 }
j3 3:7c269f52ad77 163 while((c[0] < min_val) || (c[0] > max_val));
j3 3:7c269f52ad77 164
j3 3:7c269f52ad77 165 return c[0];
j3 3:7c269f52ad77 166 }
j3 6:419eea2fe960 167
j3 6:419eea2fe960 168
j3 6:419eea2fe960 169 float Terminal::get_float(const char *msg, const float min_val, const float max_val)
j3 6:419eea2fe960 170 {
j3 6:419eea2fe960 171 float user_input;
j3 8:9ab22fc6e88b 172 //mbed uses C++ 2003 so no benifit in using C++ string for this fx
j3 8:9ab22fc6e88b 173 char str[12];
j3 8:9ab22fc6e88b 174 uint8_t idx = 0;
j3 6:419eea2fe960 175
j3 6:419eea2fe960 176 do
j3 6:419eea2fe960 177 {
j3 6:419eea2fe960 178 printf(msg);
j3 6:419eea2fe960 179
j3 6:419eea2fe960 180 //get user input
j3 6:419eea2fe960 181 idx = 0;
j3 6:419eea2fe960 182 do
j3 6:419eea2fe960 183 {
j3 8:9ab22fc6e88b 184 //wait for first char
j3 8:9ab22fc6e88b 185 do
j3 6:419eea2fe960 186 {
j3 8:9ab22fc6e88b 187 if(this->readable())
j3 8:9ab22fc6e88b 188 {
j3 8:9ab22fc6e88b 189 str[idx++] = this->getc();
j3 8:9ab22fc6e88b 190 }
j3 6:419eea2fe960 191 }
j3 8:9ab22fc6e88b 192 while(idx == 0);
j3 6:419eea2fe960 193 }
j3 8:9ab22fc6e88b 194 while((str[idx-1] != 0x0A) && (str[idx-1] != 0x0D) && (idx < 32));
j3 6:419eea2fe960 195
j3 8:9ab22fc6e88b 196 //wait for possible additional char on windows machines
j3 8:9ab22fc6e88b 197 //at even the slowest of baudrates.
j3 8:9ab22fc6e88b 198 //Need a better way...
j3 8:9ab22fc6e88b 199 wait_ms(50);
j3 8:9ab22fc6e88b 200
j3 8:9ab22fc6e88b 201 //gobble up trailing LF if there
j3 8:9ab22fc6e88b 202 while(this->readable())
j3 6:419eea2fe960 203 {
j3 8:9ab22fc6e88b 204 this->getc();
j3 6:419eea2fe960 205 }
j3 6:419eea2fe960 206
j3 8:9ab22fc6e88b 207 //replace CR or LF with \0
j3 8:9ab22fc6e88b 208 str[idx - 1] = '\0';
j3 8:9ab22fc6e88b 209 //convert to float
j3 6:419eea2fe960 210 user_input = atof(str);
j3 6:419eea2fe960 211
j3 6:419eea2fe960 212 if((user_input <= min_val) || (user_input >= max_val))
j3 6:419eea2fe960 213 {
j3 6:419eea2fe960 214 printf("\nYou entered = %f\n", user_input);
j3 6:419eea2fe960 215 printf("\nOut of range\n");
j3 6:419eea2fe960 216 }
j3 6:419eea2fe960 217 }
j3 6:419eea2fe960 218 while((user_input <= min_val) || (user_input >= max_val));
j3 6:419eea2fe960 219
j3 6:419eea2fe960 220 return(user_input);
j3 6:419eea2fe960 221 }