erebus

diff src/console.cc @ 41:2e817711d0f6

console: proper input line windowing and clipping
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 10 Jun 2014 12:28:56 +0300
parents 9d6368850fe1
children b9294cd6b9dc
line diff
     1.1 --- a/src/console.cc	Tue Jun 10 10:53:19 2014 +0300
     1.2 +++ b/src/console.cc	Tue Jun 10 12:28:56 2014 +0300
     1.3 @@ -8,6 +8,7 @@
     1.4  #include "console.h"
     1.5  
     1.6  Console::Console()
     1.7 +	: prompt("> ")
     1.8  {
     1.9  	visible = false;
    1.10  	nlines = 16;
    1.11 @@ -23,6 +24,28 @@
    1.12  	font_size = 0;
    1.13  
    1.14  	cursor = 0;
    1.15 +	input_win = 0;
    1.16 +}
    1.17 +
    1.18 +void Console::set_cursor(int x)
    1.19 +{
    1.20 +	if(x < 0 || x > (int)input.size()) {
    1.21 +		return;
    1.22 +	}
    1.23 +	cursor = x;
    1.24 +
    1.25 +	int max_chars = ncolumns - (int)prompt.size() - 1;
    1.26 +
    1.27 +	if(cursor < input_win) {
    1.28 +		input_win = cursor;
    1.29 +	} else if(cursor > input_win + max_chars) {
    1.30 +		input_win = std::max(cursor - max_chars, 0);
    1.31 +	}
    1.32 +}
    1.33 +
    1.34 +int Console::get_cursor() const
    1.35 +{
    1.36 +	return cursor;
    1.37  }
    1.38  
    1.39  void Console::set_font(dtx_font *font, int sz)
    1.40 @@ -107,20 +130,19 @@
    1.41  		switch(c) {
    1.42  		case '\n':
    1.43  		case '\r':
    1.44 -			if(!input.empty() && cmd_handler) {
    1.45 -				cmd_handler(input.c_str());
    1.46 -			}
    1.47 -
    1.48  			if(echo) {
    1.49  				puts(input.c_str());
    1.50  				putchar('\n');
    1.51  			}
    1.52 +			if(!input.empty() && cmd_handler) {
    1.53 +				cmd_handler(input.c_str());
    1.54 +			}
    1.55  
    1.56  			hist.push_back(std::move(input));	// move the input string into the history buffer
    1.57  			if((int)hist.size() > max_hist_lines) {
    1.58  				hist.pop_front();
    1.59  			}
    1.60 -			cursor = 0;
    1.61 +			set_cursor(0);
    1.62  			must_redraw = true;
    1.63  			break;
    1.64  
    1.65 @@ -132,11 +154,11 @@
    1.66  			if(!input.empty()) {
    1.67  				if(cursor == (int)input.size()) {
    1.68  					input.pop_back();
    1.69 -					--cursor;
    1.70 +					set_cursor(get_cursor() - 1);
    1.71  					must_redraw = true;
    1.72  				} else if(cursor > 0) {
    1.73  					input.erase(cursor - 1, 1);
    1.74 -					--cursor;
    1.75 +					set_cursor(get_cursor() - 1);
    1.76  					must_redraw = true;
    1.77  				}
    1.78  			}
    1.79 @@ -144,25 +166,25 @@
    1.80  
    1.81  		case KEY_LEFT:
    1.82  			if(cursor > 0) {
    1.83 -				--cursor;
    1.84 +				set_cursor(get_cursor() - 1);
    1.85  				must_redraw = true;
    1.86  			}
    1.87  			break;
    1.88  
    1.89  		case KEY_RIGHT:
    1.90  			if(cursor < (int)input.size()) {
    1.91 -				++cursor;
    1.92 +				set_cursor(get_cursor() + 1);
    1.93  				must_redraw = true;
    1.94  			}
    1.95  			break;
    1.96  
    1.97  		case KEY_HOME:
    1.98 -			cursor = 0;
    1.99 +			set_cursor(0);
   1.100  			must_redraw = true;
   1.101  			break;
   1.102  
   1.103  		case KEY_END:
   1.104 -			cursor = input.size();
   1.105 +			set_cursor(input.size());
   1.106  			must_redraw = true;
   1.107  			break;
   1.108  
   1.109 @@ -178,7 +200,7 @@
   1.110  				} else {
   1.111  					input.insert(cursor, 1, c);
   1.112  				}
   1.113 -				++cursor;
   1.114 +				set_cursor(get_cursor() + 1);
   1.115  				must_redraw = true;
   1.116  			}
   1.117  		}
   1.118 @@ -202,7 +224,7 @@
   1.119  	glMatrixMode(GL_MODELVIEW);
   1.120  	glPushMatrix();
   1.121  	glLoadIdentity();
   1.122 -	glTranslatef(0, vp[3] - vp[1], 0);
   1.123 +	glTranslatef(0, vp[3], 0);
   1.124  
   1.125  	std::string buflines;
   1.126  
   1.127 @@ -215,18 +237,22 @@
   1.128  		const std::string &line = *it++;
   1.129  		buflines += line + std::string("\n");
   1.130  
   1.131 -		max_width = std::max(max_width, dtx_string_width(line.c_str()));
   1.132 +		//max_width = std::max(max_width, dtx_string_width(line.c_str()));
   1.133  	}
   1.134  
   1.135  	// draw the output box
   1.136  	float line_height = dtx_line_height();
   1.137  	float outbox_height = nlines * line_height;
   1.138 +	float console_height = outbox_height + line_height * 1.5;
   1.139  
   1.140  	glPushAttrib(GL_ENABLE_BIT);
   1.141  	glEnable(GL_BLEND);
   1.142  	glDisable(GL_TEXTURE_2D);
   1.143  	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   1.144  
   1.145 +	glEnable(GL_SCISSOR_TEST);
   1.146 +	glScissor(0, vp[3] - console_height, max_width, console_height);
   1.147 +
   1.148  	glBegin(GL_QUADS);
   1.149  	glColor4f(0.1, 0.2, 0.5, 0.7);
   1.150  	glVertex2f(0, -outbox_height);
   1.151 @@ -235,8 +261,8 @@
   1.152  	glVertex2f(0, 0);
   1.153  
   1.154  	glColor4f(0.5, 0.2, 0.1, 0.7);
   1.155 -	glVertex2f(0, -(outbox_height + line_height * 1.5));
   1.156 -	glVertex2f(max_width, -(outbox_height + line_height * 1.5));
   1.157 +	glVertex2f(0, -console_height);
   1.158 +	glVertex2f(max_width, -console_height);
   1.159  	glVertex2f(max_width, -outbox_height);
   1.160  	glVertex2f(0, -outbox_height);
   1.161  	glEnd();
   1.162 @@ -251,11 +277,11 @@
   1.163  	// draw the input line
   1.164  	glTranslatef(0, -outbox_height - line_height, 0);
   1.165  
   1.166 -	std::string inpline = std::string("> ") + input;
   1.167 +	std::string inpline = prompt + input.substr(input_win);
   1.168  	dtx_string(inpline.c_str());
   1.169  	glDisable(GL_TEXTURE_2D);
   1.170  
   1.171 -	float cursor_x = dtx_char_pos(inpline.c_str(), cursor + 2);
   1.172 +	float cursor_x = dtx_char_pos(inpline.c_str(), cursor - input_win + prompt.size());
   1.173  	glBegin(GL_QUADS);
   1.174  	glColor4f(1, 1, 1, 0.7);
   1.175  	glVertex2f(cursor_x, 0);