Subversion Repositories DIN Is Noise

Rev

Rev 2302 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
964 jag 1
/*
2
* console.cc
2302 jag 3
* DIN Is Noise is copyright (c) 2006-2025 Jagannathan Sampath
1713 jag 4
* DIN Is Noise is released under GNU Public License 2.0
1479 jag 5
* For more information, please visit https://dinisnoise.org/
964 jag 6
*/
7
 
8
 
2303 jag 9
#include <algorithm>
10
#include <string>
11
using namespace std;
12
 
964 jag 13
#include "console.h"
14
#include "font.h"
15
#include "input.h"
16
#include "command.h"
17
#include "tcl_interp.h"
18
#include "tokenizer.h"
19
#include "globals.h"
20
#include "ui_list.h"
21
#include "log.h"
22
 
23
extern cmdlist cmdlst;
24
extern char BUFFER [];
25
extern int line_height;
26
 
27
void console::add_line (const mesg& ln) {
28
  lines.push_back (ln);
29
  ++nlines;
1565 jag 30
  if (nlines > maxlines) {
964 jag 31
    lines.pop_front ();
32
    --nlines;
33
  }
34
  last ();
35
}
36
 
37
void console::last () { // ensures last line is always displayed
38
  end ();
39
  if (rollup_ == 0) up (lines_per_screen - 1);
40
}
41
 
42
void console::end () {
43
  startl = std::max (0, nlines - 1);
44
  calc_startl_iterator ();
45
}
46
 
47
void console::up (int i) {
48
  startl = std::max (0, startl - i);
49
  calc_startl_iterator ();
50
}
51
 
52
void console::down (int i) {
53
  startl += i;
54
  if (startl >= nlines) startl = std::max (0, nlines - 1);
55
  calc_startl_iterator ();
56
}
57
 
58
void console::pgdn () {
59
  down (lines_per_screen);
60
}
61
 
62
void console::pgup () {
63
  up (lines_per_screen);
64
}
65
 
66
void console::home () {
67
  startl = 0;
68
  calc_startl_iterator ();
69
}
70
 
1710 jag 71
console::console () : b_roll (10, arrow_button::up) {
1576 jag 72
  maxlines = 512;
964 jag 73
  command_mode = 0;
74
  rollup_ = 0;
75
  curs_loc = 0;
76
  curs_locx = 0;
77
  hid = -1;
78
  clear ();
79
  b_roll.set_listener (this);
80
  history.reserve (1024);
81
}
82
 
83
console& console::operator<< (const color& c) {
84
  clr = c;
85
  return *this;
86
}
87
 
88
console& console::operator<< (const string& s) {
89
  cur_line.text += s;
90
  return *this;
91
}
92
 
93
console& console::operator<< (unsigned int i) {
94
  sprintf (BUFFER, "%x", i);
95
  *this << BUFFER;
96
  return *this;
97
}
98
 
99
console& console::operator<< (int i) {
100
  sprintf (BUFFER, "%d", i);
101
  *this << BUFFER;
102
  return *this;
103
}
104
 
105
console& console::operator<< (unsigned long  i) {
106
  sprintf (BUFFER, "%lu", i);
107
  *this << BUFFER;
108
  return *this;
109
}
110
 
111
console& console::operator<< (float f) {
1709 jag 112
  sprintf (BUFFER, precision, f);
964 jag 113
  *this << BUFFER;
114
  return *this;
115
}
116
 
117
console& console::operator<< (double d) {
1709 jag 118
  sprintf (BUFFER, precision, d);
964 jag 119
  *this << BUFFER;
120
  return *this;
121
}
122
 
123
console& console::operator<< (char c) {
124
  if (c == '\n') {
1710 jag 125
    //if (suppress == 0) {
1141 jag 126
      cur_line.clr = clr;
127
      add_line (cur_line);
1710 jag 128
    //}
1141 jag 129
    cur_line = mesg ();
964 jag 130
  } else cur_line.text += c;
131
  return *this;
132
}
133
 
134
void console::del () {
135
  int len = cmd_line.text.length ();
136
  if (curs_loc > 0 && curs_loc <= len) {
137
    cmd_line.text.erase (cmd_line.text.begin() + curs_loc - 1);
138
    curs_locx = (int) get_char_width (cmd_line.text.substr (0, --curs_loc));
139
  }
140
}
141
 
142
 
143
void console::draw () {
144
 
145
  // draw lines
146
  int cx = startx, cy = starty;
147
  int n = 0, i = startl;
148
  line_iterator it = it_startl;
149
  while ((n++ < lines_per_screen) && (i < nlines)) {
150
    const mesg& linei = *it++; i++;
151
    const color& clr = linei.clr;
152
    glColor3f (clr.r, clr.g, clr.b);
153
    draw_string (linei.text, cx, cy);
154
    cy -= line_height;
155
  }
156
 
157
  // draw command line
158
  glColor3f (cmd_line.clr.r, cmd_line.clr.g, cmd_line.clr.b);
159
  draw_string (cmd_line.text, cx, cy);
160
 
161
  // draw cursor
162
  if (command_mode) {
163
    glColor3f (1, 0, 0);
164
    int px = cx + curs_locx, py = cy - 2;
1922 jag 165
    glBegin (GL_LINES);
166
      glVertex2i (px, py);
167
      glVertex2i (px+char_width, py);
168
    glEnd ();
964 jag 169
  }
170
 
171
  // draw rollup arrow
172
  int py = b_roll.posy;
173
  if (py != cy) b_roll.set_pos (1, cy);
174
  b_roll.draw ();
175
 
176
}
177
 
178
void console::clear () {
179
  lines.clear ();
180
  clear_cmd_line ();
181
  nlines = 0;
182
  startl = 0;
183
  calc_startl_iterator ();
184
  rollup (1);
185
}
186
 
187
void console::set_window (const box<int>& w) {
188
  win = w;
189
  calc_visual_params ();
190
}
191
 
2300 jag 192
void console::calc_visual_params () {
193
  char_width = fnt.charwidth.max;
194
  lines_per_screen = (win.top - win.bottom) / line_height - GUTTER;
2301 jag 195
  startx = win.left + 20;
2300 jag 196
  starty = win.top - line_height;
197
  rollup (rollup());
198
}
964 jag 199
 
2300 jag 200
extern char get_typed_char ();
201
 
964 jag 202
int console::handle_input () {
203
 
204
  b_roll.handle_input ();
205
 
206
  int ret = 0;
207
  static float sc0 = 0.5, sc1 = 1./64;
208
  static float pg0 = 0.5, pg1 = 1./32;
209
 
1517 jag 210
  if (keypressed (SDLK_TAB) && !ALT) {
964 jag 211
    toggle_command_mode ();
212
    return 1;
2300 jag 213
  }
214
 
215
  else
216
 
217
  if (command_mode) {
218
 
964 jag 219
    if (keypressed (SDLK_ESCAPE)) {
220
      toggle_command_mode ();
221
      return 1;
222
    }
223
 
224
    ret = 1;
225
    char c = get_typed_char ();
226
    if (c != 0) {
227
      cmd_line.text.insert (cmd_line.text.begin() + curs_loc++, c);
228
      curs_locx = get_char_width (cmd_line.text.substr (0, curs_loc));
229
    }
230
 
231
    if (keypressedd (SDLK_BACKSPACE)) del (); else
232
 
233
    if (keypressed (SDLK_RETURN)) {
234
 
235
      add_line (cmd_line);
236
 
237
      history.push_back (cmd_line.text);
238
      hid = history.size () - 1;
239
 
240
      operator() (cmd_line.text);
241
      clear_cmd_line ();
242
 
243
    } else if (keypressedd (SDLK_LEFT)) {
244
 
245
      if (--curs_loc < 1)
246
        curs_loc = curs_locx = 0;
247
      else
248
        curs_locx = (int) get_char_width (cmd_line.text.substr (0, curs_loc));
249
 
250
 
251
    } else if (keypressedd (SDLK_RIGHT)) {
252
 
253
      int len = cmd_line.text.length ();
254
      if (++curs_loc > len) curs_loc = len;
255
      curs_locx = (int) get_char_width (cmd_line.text.substr (0, curs_loc));
256
 
257
 
258
    } else if (hid > -1) {
259
 
260
      if (keypressedd (SDLK_UP)) {
261
        set_cmd_line (history[hid--]);
262
        if (hid < 0) hid = history.size () - 1;
263
      } else if (keypressedd (SDLK_DOWN)) {
264
        set_cmd_line (history[hid++]);
265
        if (hid >= (int) history.size()) hid = 0;
266
      }
267
 
268
    }
269
 
270
    return 1;
271
 
272
  } else
2007 jag 273
 
964 jag 274
  if (keypressed (SDLK_HOME)) home (); else
275
  if (keypressed (SDLK_END)) end(); else
276
  if (keypressedd (SDLK_PAGEUP, pg0, pg1)) pgup(); else
277
  if (keypressedd (SDLK_PAGEDOWN, pg0, pg1)) pgdn(); else
2007 jag 278
  if (keypressed (SDLK_BACKSPACE)) clear(); else
964 jag 279
  if (keypressedd (SDLK_UP, sc0, sc1)) up(1); else
280
  if (keypressedd (SDLK_DOWN, sc0, sc1)) down(1);
281
 
282
  return ret;
283
 
284
}
285
 
286
void console::rollup (int r) {
287
  rollup_ = r;
288
  if (rollup_ == 1)
1015 jag 289
    b_roll.set_dir (arrow_button::down);
964 jag 290
  else
1015 jag 291
    b_roll.set_dir (arrow_button::up);
964 jag 292
  last ();
293
}
294
 
295
console& console::operator() (const string& cmd) {
296
  into_lines (interpreter(cmd).result, *this);
297
  return *this;
298
}
299
 
300
void console::set_cmd_line (const string& s, const color& c) {
301
  cmd_line.text = s;
302
  cmd_line.clr = c;
303
  curs_loc = cmd_line.text.length ();
304
  curs_locx = get_char_width (cmd_line.text);
305
}
306
 
307
void console::clear_cmd_line () {
308
  cmd_line = mesg ();
309
  curs_loc = curs_locx = 0;
310
}
311
 
312
void console::toggle_command_mode () {
313
  command_mode = !command_mode;
314
  if (command_mode) {
315
    widget::focus = this;
316
  } else widget::focus = 0;
317
  last ();
318
}
319
 
320
void console::clicked (button& b) {
321
  rollup (!rollup());
322
  if (command_mode) widget::focus = this;
323
}
324
 
325
console::~console() {
326
  dlog << "--- destroyed console ---" << endl;
327
}
2300 jag 328
 
329
void console::calc_startl_iterator () {
330
  it_startl = lines.begin ();
331
  for (int i = 0; i < startl; ++i, ++it_startl);
332
}