sources/interface.cpp

changeset 139
da7d5a8e608f
parent 138
c909c38ca886
child 140
e49aa4aa98c0
equal deleted inserted replaced
138:c909c38ca886 139:da7d5a8e608f
39 39
40 static const int PAGE_SIZE = 10; 40 static const int PAGE_SIZE = 10;
41 41
42 // ------------------------------------------------------------------------------------------------- 42 // -------------------------------------------------------------------------------------------------
43 // 43 //
44 chtype Interface::color_pair (Color fg, Color bg) 44 chtype Interface::getColorPair (Color fg, Color bg)
45 { 45 {
46 if (fg == DEFAULT && bg == DEFAULT) 46 if (fg == DEFAULT && bg == DEFAULT)
47 return 0; 47 return 0;
48 else 48 else
49 return COLOR_PAIR (1 + (int (fg) * NUM_COLORS) + int (bg)); 49 return COLOR_PAIR (1 + (int (fg) * NUM_COLORS) + int (bg));
50 } 50 }
51 51
52 // ------------------------------------------------------------------------------------------------- 52 // -------------------------------------------------------------------------------------------------
53 // 53 //
54 const String& Interface::current_input() 54 const String& Interface::getCurrentInput()
55 { 55 {
56 return m_inputHistory[m_inputCursor]; 56 return m_inputHistory[m_inputCursor];
57 } 57 }
58 58
59 // ------------------------------------------------------------------------------------------------- 59 // -------------------------------------------------------------------------------------------------
60 // 60 //
61 // Makes current_input() the lastmost input (so that we won't modify history) 61 // Makes current_input() the lastmost input (so that we won't modify history)
62 // 62 //
63 void Interface::detach_input() 63 void Interface::detachInput()
64 { 64 {
65 if (m_inputCursor > 0) 65 if (m_inputCursor > 0)
66 { 66 {
67 m_inputHistory[0] = current_input(); 67 m_inputHistory[0] = getCurrentInput();
68 m_inputCursor = 0; 68 m_inputCursor = 0;
69 } 69 }
70 } 70 }
71 71
72 // ------------------------------------------------------------------------------------------------- 72 // -------------------------------------------------------------------------------------------------
73 // A version of current_input() that allows changing the contents of it. 73 // A version of current_input() that allows changing the contents of it.
74 // 74 //
75 String& Interface::mutable_current_input() 75 String& Interface::getEditableInput()
76 { 76 {
77 detach_input(); 77 detachInput();
78 return m_inputHistory[m_inputCursor]; 78 return m_inputHistory[m_inputCursor];
79 } 79 }
80 80
81 // ------------------------------------------------------------------------------------------------- 81 // -------------------------------------------------------------------------------------------------
82 // 82 //
83 void Interface::move_input_cursor (int delta) 83 void Interface::moveInputCursor (int delta)
84 { 84 {
85 // No input history when inputting addresses or passwords 85 // No input history when inputting addresses or passwords
86 if (m_inputState != INPUTSTATE_NORMAL) 86 if (m_inputState != INPUTSTATE_NORMAL)
87 { 87 {
88 m_inputCursor = 0; 88 m_inputCursor = 0;
92 int oldcursor = m_inputCursor; 92 int oldcursor = m_inputCursor;
93 m_inputCursor = clamp (m_inputCursor + delta, 0, m_inputHistory.size() - 1); 93 m_inputCursor = clamp (m_inputCursor + delta, 0, m_inputHistory.size() - 1);
94 94
95 if (m_inputCursor != oldcursor) 95 if (m_inputCursor != oldcursor)
96 { 96 {
97 m_cursorPosition = current_input().length(); 97 m_cursorPosition = getCurrentInput().length();
98 m_needInputRender = true; 98 m_needInputRender = true;
99 } 99 }
100 } 100 }
101 101
102 // ------------------------------------------------------------------------------------------------- 102 // -------------------------------------------------------------------------------------------------
103 // 103 //
104 String Interface::prompt_string() 104 String Interface::getPromptString()
105 { 105 {
106 String prompt; 106 String prompt;
107 107
108 switch (m_inputState) 108 switch (m_inputState)
109 { 109 {
116 return prompt; 116 return prompt;
117 } 117 }
118 118
119 // ------------------------------------------------------------------------------------------------- 119 // -------------------------------------------------------------------------------------------------
120 // 120 //
121 void Interface::set_input_state (InputState newstate) 121 void Interface::setInputState (InputState newstate)
122 { 122 {
123 // Clear the input row (unless going to or from confirm state) 123 // Clear the input row (unless going to or from confirm state)
124 if (newstate != INPUTSTATE_CONFIRM_DISCONNECTION 124 if (newstate != INPUTSTATE_CONFIRM_DISCONNECTION
125 and m_inputState != INPUTSTATE_CONFIRM_DISCONNECTION) 125 and m_inputState != INPUTSTATE_CONFIRM_DISCONNECTION)
126 { 126 {
127 m_inputCursor = 0; 127 m_inputCursor = 0;
128 mutable_current_input().clear(); 128 getEditableInput().clear();
129 } 129 }
130 130
131 switch (newstate) 131 switch (newstate)
132 { 132 {
133 case INPUTSTATE_ADDRESS: 133 case INPUTSTATE_ADDRESS:
134 if (m_remoteAddress.host != 0) 134 if (m_remoteAddress.host != 0)
135 mutable_current_input() = m_remoteAddress.to_string (IPAddress::WITH_PORT); 135 getEditableInput() = m_remoteAddress.to_string (IPAddress::WITH_PORT);
136 break; 136 break;
137 137
138 default: 138 default:
139 break; 139 break;
140 } 140 }
167 m_inputHistory.clear(); 167 m_inputHistory.clear();
168 m_inputHistory << ""; 168 m_inputHistory << "";
169 m_outputLines.clear(); 169 m_outputLines.clear();
170 m_outputLines << ColoredLine(); 170 m_outputLines << ColoredLine();
171 m_session.set_interface (this); 171 m_session.set_interface (this);
172 reset_title(); 172 resetTitle();
173 173
174 if (::has_colors()) 174 if (::has_colors())
175 { 175 {
176 ::start_color(); 176 ::start_color();
177 bool hasDefaultColors = (::use_default_colors() == OK); 177 bool hasDefaultColors = (::use_default_colors() == OK);
199 m_needRefresh = false; 199 m_needRefresh = false;
200 } 200 }
201 201
202 // ------------------------------------------------------------------------------------------------- 202 // -------------------------------------------------------------------------------------------------
203 // 203 //
204 void Interface::render_titlebar() 204 void Interface::renderTitlebar()
205 { 205 {
206 if (m_title.length() <= COLS) 206 if (m_title.length() <= COLS)
207 { 207 {
208 chtype pair = color_pair (WHITE, BLUE); 208 chtype pair = getColorPair (WHITE, BLUE);
209 int startx = (COLS - m_title.length()) / 2; 209 int startx = (COLS - m_title.length()) / 2;
210 int endx = startx + m_title.length(); 210 int endx = startx + m_title.length();
211 attron (pair); 211 attron (pair);
212 mvprintw (0, startx, "%s", m_title.chars()); 212 mvprintw (0, startx, "%s", m_title.chars());
213 mvhline (0, 0, ' ', startx); 213 mvhline (0, 0, ' ', startx);
221 // ------------------------------------------------------------------------------------------------- 221 // -------------------------------------------------------------------------------------------------
222 // 222 //
223 void Interface::setTitle (const String& title) 223 void Interface::setTitle (const String& title)
224 { 224 {
225 m_title = title; 225 m_title = title;
226 render_titlebar(); 226 renderTitlebar();
227 } 227 }
228 228
229 // ------------------------------------------------------------------------------------------------- 229 // -------------------------------------------------------------------------------------------------
230 // 230 //
231 void Interface::safe_disconnect (std::function<void(bool)> afterwards) 231 void Interface::safeDisconnect (std::function<void(bool)> afterwards)
232 { 232 {
233 if (m_session.is_active()) 233 if (m_session.is_active())
234 { 234 {
235 m_disconnectCallback = afterwards; 235 m_disconnectCallback = afterwards;
236 set_input_state (INPUTSTATE_CONFIRM_DISCONNECTION); 236 setInputState (INPUTSTATE_CONFIRM_DISCONNECTION);
237 } 237 }
238 else 238 else
239 afterwards(false); 239 afterwards(false);
240 } 240 }
241 241
242 // ------------------------------------------------------------------------------------------------- 242 // -------------------------------------------------------------------------------------------------
243 // 243 //
244 int Interface::nicklist_width() 244 int Interface::nicklistWidth()
245 { 245 {
246 // Allocate at least 12 characters, at most 24 characters, for the nicklist. If we cannot 246 // Allocate at least 12 characters, at most 24 characters, for the nicklist. If we cannot
247 // afford that (o_O) then we probably shouldn't draw the nicklist at all I think. 247 // afford that (o_O) then we probably shouldn't draw the nicklist at all I think.
248 int nicklistWidth = COLS / 4; 248 int nicklistWidth = COLS / 4;
249 249
255 255
256 // ------------------------------------------------------------------------------------------------- 256 // -------------------------------------------------------------------------------------------------
257 // Renders the given colored line onto the screen. Will wrap if allowWrap is true. Returns the 257 // Renders the given colored line onto the screen. Will wrap if allowWrap is true. Returns the
258 // 'y' value for the next line. 258 // 'y' value for the next line.
259 // 259 //
260 int Interface::render_colorline (int y, int x0, int width, const ColoredLine& line, bool allowWrap) 260 int Interface::renderColorline (int y, int x0, int width, const ColoredLine& line, bool allowWrap)
261 { 261 {
262 int x = x0; 262 int x = x0;
263 263
264 for (int byte : line.data()) 264 for (int byte : line.data())
265 { 265 {
278 ++x; 278 ++x;
279 } 279 }
280 else if (byte >= RLINE_ON_COLOR and byte < (RLINE_ON_COLOR + 16)) 280 else if (byte >= RLINE_ON_COLOR and byte < (RLINE_ON_COLOR + 16))
281 { 281 {
282 auto attrfunction = (byte < RLINE_OFF_COLOR ? &attron : &attroff); 282 auto attrfunction = (byte < RLINE_OFF_COLOR ? &attron : &attroff);
283 (*attrfunction) (color_pair (Color ((byte - RLINE_ON_COLOR) & 7), DEFAULT)); 283 (*attrfunction) (getColorPair (Color ((byte - RLINE_ON_COLOR) & 7), DEFAULT));
284 } 284 }
285 else switch (byte) 285 else switch (byte)
286 { 286 {
287 case RLINE_ON_BOLD: 287 case RLINE_ON_BOLD:
288 attron (A_BOLD); 288 attron (A_BOLD);
297 return y + 1; 297 return y + 1;
298 } 298 }
299 299
300 // ------------------------------------------------------------------------------------------------- 300 // -------------------------------------------------------------------------------------------------
301 // 301 //
302 void Interface::render_output() 302 void Interface::renderOutput()
303 { 303 {
304 if (m_outputLines.size() == 1) 304 if (m_outputLines.size() == 1)
305 return; 305 return;
306 306
307 m_outputScroll = clamp (m_outputScroll, 0, m_outputLines.size() - 1); 307 m_outputScroll = clamp (m_outputScroll, 0, m_outputLines.size() - 1);
308 308
309 int height = LINES - 3; 309 int height = LINES - 3;
310 int width = COLS - nicklist_width(); 310 int width = COLS - nicklistWidth();
311 int printOffset = 0; 311 int printOffset = 0;
312 int end = m_outputLines.size() - 1 - m_outputScroll; 312 int end = m_outputLines.size() - 1 - m_outputScroll;
313 int start = end; 313 int start = end;
314 int usedHeight = 0; 314 int usedHeight = 0;
315 int y = 1; 315 int y = 1;
365 365
366 // Print the lines 366 // Print the lines
367 y += printOffset; 367 y += printOffset;
368 368
369 for (int i : range(start, end)) 369 for (int i : range(start, end))
370 y = render_colorline (y, 0, width, m_outputLines[i], true); 370 y = renderColorline (y, 0, width, m_outputLines[i], true);
371 371
372 m_needOutputRender = false; 372 m_needOutputRender = false;
373 m_needRefresh = true; 373 m_needRefresh = true;
374 } 374 }
375 375
376 // ------------------------------------------------------------------------------------------------- 376 // -------------------------------------------------------------------------------------------------
377 // 377 //
378 void Interface::render_nicklist() 378 void Interface::renderNicklist()
379 { 379 {
380 int width = nicklist_width(); 380 int width = nicklistWidth();
381 int height = LINES- 3; 381 int height = LINES- 3;
382 int y = 1; 382 int y = 1;
383 int x = COLS - width; 383 int x = COLS - width;
384 384
385 if (width > 0) 385 if (width > 0)
388 for (int i : range(height)) 388 for (int i : range(height))
389 { 389 {
390 mvhline (y, x, ' ', width); 390 mvhline (y, x, ' ', width);
391 391
392 if (i < m_playerNames.size()) 392 if (i < m_playerNames.size())
393 render_colorline (y, x, width, m_playerNames[i], false); 393 renderColorline (y, x, width, m_playerNames[i], false);
394 394
395 y++; 395 y++;
396 } 396 }
397 397
398 m_needNicklistRender = false; 398 m_needNicklistRender = false;
399 m_needRefresh = true; 399 m_needRefresh = true;
400 } 400 }
401 401
402 // ------------------------------------------------------------------------------------------------- 402 // -------------------------------------------------------------------------------------------------
403 // 403 //
404 void Interface::render_input() 404 void Interface::renderInput()
405 { 405 {
406 chtype promptColor = color_pair (WHITE, BLUE); 406 chtype promptColor = getColorPair (WHITE, BLUE);
407 407
408 // If we're asking the user if they want to disconnect, we don't render any input strings, 408 // If we're asking the user if they want to disconnect, we don't render any input strings,
409 // just the confirmation message. 409 // just the confirmation message.
410 if (m_inputState == INPUTSTATE_CONFIRM_DISCONNECTION) 410 if (m_inputState == INPUTSTATE_CONFIRM_DISCONNECTION)
411 { 411 {
415 attroff (promptColor); 415 attroff (promptColor);
416 m_needRefresh = true; 416 m_needRefresh = true;
417 return; 417 return;
418 } 418 }
419 419
420 String prompt = prompt_string(); 420 String prompt = getPromptString();
421 int displayLength = COLS - prompt.length() - 2; 421 int displayLength = COLS - prompt.length() - 2;
422 String displayString = current_input(); 422 String displayString = getCurrentInput();
423 int y = LINES - 2; 423 int y = LINES - 2;
424 424
425 // If we're inputting a password, replace it with asterisks 425 // If we're inputting a password, replace it with asterisks
426 if (m_inputState == INPUTSTATE_PASSWORD) 426 if (m_inputState == INPUTSTATE_PASSWORD)
427 { 427 {
460 m_needInputRender = false; 460 m_needInputRender = false;
461 } 461 }
462 462
463 // ------------------------------------------------------------------------------------------------- 463 // -------------------------------------------------------------------------------------------------
464 // 464 //
465 void Interface::render_statusbar() 465 void Interface::renderStatusBar()
466 { 466 {
467 chtype color = color_pair (WHITE, BLUE); 467 chtype color = getColorPair (WHITE, BLUE);
468 int y = LINES - 1; 468 int y = LINES - 1;
469 attron (color); 469 attron (color);
470 mvhline (y, 0, ' ', COLS); 470 mvhline (y, 0, ' ', COLS);
471 mvprintw (y, 0, "%s", m_statusBarText.chars()); 471 mvprintw (y, 0, "%s", m_statusBarText.chars());
472 attroff (color); 472 attroff (color);
529 // ------------------------------------------------------------------------------------------------- 529 // -------------------------------------------------------------------------------------------------
530 // 530 //
531 void Interface::renderFull() 531 void Interface::renderFull()
532 { 532 {
533 updateStatusBar(); 533 updateStatusBar();
534 render_titlebar(); 534 renderTitlebar();
535 render_output(); 535 renderOutput();
536 render_statusbar(); 536 renderStatusBar();
537 render_input(); 537 renderInput();
538 render_nicklist(); 538 renderNicklist();
539 } 539 }
540 540
541 // ------------------------------------------------------------------------------------------------- 541 // -------------------------------------------------------------------------------------------------
542 // 542 //
543 void Interface::position_cursor() 543 void Interface::positionCursor()
544 { 544 {
545 // This is only relevant if the input string is being drawn 545 // This is only relevant if the input string is being drawn
546 if (m_inputState == INPUTSTATE_CONFIRM_DISCONNECTION) 546 if (m_inputState == INPUTSTATE_CONFIRM_DISCONNECTION)
547 return; 547 return;
548 548
549 int y = LINES - 2; 549 int y = LINES - 2;
550 550
551 if (m_cursorCharacter.ch != '\0') 551 if (m_cursorCharacter.ch != '\0')
552 mvprintw (y, m_cursorCharacter.x, "%c", m_cursorCharacter.ch); 552 mvprintw (y, m_cursorCharacter.x, "%c", m_cursorCharacter.ch);
553 else 553 else
554 mvprintw (y, prompt_string().length(), " "); 554 mvprintw (y, getPromptString().length(), " ");
555 } 555 }
556 556
557 // ------------------------------------------------------------------------------------------------- 557 // -------------------------------------------------------------------------------------------------
558 // 558 //
559 int Interface::find_previous_word() 559 int Interface::findPreviousWord()
560 { 560 {
561 const String& input = current_input(); 561 const String& input = getCurrentInput();
562 int pos = m_cursorPosition; 562 int pos = m_cursorPosition;
563 563
564 // Move past whitespace 564 // Move past whitespace
565 while (pos > 0 and isspace (input[pos - 1])) 565 while (pos > 0 and isspace (input[pos - 1]))
566 pos--; 566 pos--;
572 return pos; 572 return pos;
573 } 573 }
574 574
575 // ------------------------------------------------------------------------------------------------- 575 // -------------------------------------------------------------------------------------------------
576 // 576 //
577 int Interface::find_next_word() 577 int Interface::findNextWord()
578 { 578 {
579 const String& input = current_input(); 579 const String& input = getCurrentInput();
580 int pos = m_cursorPosition; 580 int pos = m_cursorPosition;
581 581
582 // Move past current whitespace 582 // Move past current whitespace
583 while (pos < input.length() and isspace (input[pos])) 583 while (pos < input.length() and isspace (input[pos]))
584 pos++; 584 pos++;
598 return; 598 return;
599 599
600 if (m_cursorPosition > a and m_cursorPosition <= b) 600 if (m_cursorPosition > a and m_cursorPosition <= b)
601 m_cursorPosition = a; 601 m_cursorPosition = a;
602 602
603 String& input = mutable_current_input(); 603 String& input = getEditableInput();
604 m_pasteBuffer = input.mid (a, b); 604 m_pasteBuffer = input.mid (a, b);
605 input.remove (a, b - a); 605 input.remove (a, b - a);
606 m_needInputRender = true; 606 m_needInputRender = true;
607 } 607 }
608 608
628 { 628 {
629 m_session.disconnect(); 629 m_session.disconnect();
630 m_disconnectCallback(true); 630 m_disconnectCallback(true);
631 } 631 }
632 else if (ch == 'n' or ch == 'N') 632 else if (ch == 'n' or ch == 'N')
633 set_input_state (INPUTSTATE_NORMAL); 633 setInputState (INPUTSTATE_NORMAL);
634 634
635 return; 635 return;
636 } 636 }
637 637
638 if (ch >= 0x20 and ch <= 0x7E) 638 if (ch >= 0x20 and ch <= 0x7E)
639 { 639 {
640 mutable_current_input().insert (m_cursorPosition++, char (ch)); 640 getEditableInput().insert (m_cursorPosition++, char (ch));
641 m_needInputRender = true; 641 m_needInputRender = true;
642 } 642 }
643 else switch (ch) 643 else switch (ch)
644 { 644 {
645 case 'Q' - 'A' + 1: // ^Q 645 case 'Q' - 'A' + 1: // ^Q
647 { 647 {
648 case INPUTSTATE_CONFIRM_DISCONNECTION: 648 case INPUTSTATE_CONFIRM_DISCONNECTION:
649 break; 649 break;
650 650
651 case INPUTSTATE_NORMAL: 651 case INPUTSTATE_NORMAL:
652 safe_disconnect ([&](bool hadsession) 652 safeDisconnect ([&](bool hadsession)
653 { 653 {
654 if (hadsession) 654 if (hadsession)
655 { 655 {
656 set_input_state (INPUTSTATE_NORMAL); 656 setInputState (INPUTSTATE_NORMAL);
657 } 657 }
658 else 658 else
659 { 659 {
660 endwin(); 660 endwin();
661 throw Exitception(); 661 throw Exitception();
662 } 662 }
663 }); 663 });
664 break; 664 break;
665 665
666 case INPUTSTATE_PASSWORD: 666 case INPUTSTATE_PASSWORD:
667 set_input_state (INPUTSTATE_ADDRESS); 667 setInputState (INPUTSTATE_ADDRESS);
668 break; 668 break;
669 669
670 case INPUTSTATE_ADDRESS: 670 case INPUTSTATE_ADDRESS:
671 set_input_state (INPUTSTATE_NORMAL); 671 setInputState (INPUTSTATE_NORMAL);
672 } 672 }
673 break; 673 break;
674 674
675 case KEY_LEFT: 675 case KEY_LEFT:
676 case 'B' - 'A' + 1: // readline ^B 676 case 'B' - 'A' + 1: // readline ^B
681 } 681 }
682 break; 682 break;
683 683
684 case KEY_RIGHT: 684 case KEY_RIGHT:
685 case 'F' - 'A' + 1: // readline ^F 685 case 'F' - 'A' + 1: // readline ^F
686 if (m_cursorPosition < current_input().length()) 686 if (m_cursorPosition < getCurrentInput().length())
687 { 687 {
688 m_cursorPosition++; 688 m_cursorPosition++;
689 m_needInputRender = true; 689 m_needInputRender = true;
690 } 690 }
691 break; 691 break;
692 692
693 case KEY_DOWN: 693 case KEY_DOWN:
694 case KEY_UP: 694 case KEY_UP:
695 move_input_cursor (ch == KEY_DOWN ? -1 : 1); 695 moveInputCursor (ch == KEY_DOWN ? -1 : 1);
696 break; 696 break;
697 697
698 case KEY_HOME: 698 case KEY_HOME:
699 case 'A' - 'A' + 1: // readline ^A 699 case 'A' - 'A' + 1: // readline ^A
700 if (m_cursorPosition != 0) 700 if (m_cursorPosition != 0)
704 } 704 }
705 break; 705 break;
706 706
707 case KEY_END: 707 case KEY_END:
708 case 'E' - 'A' + 1: // readline ^E 708 case 'E' - 'A' + 1: // readline ^E
709 if (m_cursorPosition != current_input().length()) 709 if (m_cursorPosition != getCurrentInput().length())
710 { 710 {
711 m_cursorPosition = current_input().length(); 711 m_cursorPosition = getCurrentInput().length();
712 m_needInputRender = true; 712 m_needInputRender = true;
713 } 713 }
714 break; 714 break;
715 715
716 case KEY_BACKSPACE: 716 case KEY_BACKSPACE:
717 case '\b': 717 case '\b':
718 if (m_cursorPosition > 0) 718 if (m_cursorPosition > 0)
719 { 719 {
720 mutable_current_input().remove_at (--m_cursorPosition); 720 getEditableInput().remove_at (--m_cursorPosition);
721 m_needInputRender = true; 721 m_needInputRender = true;
722 } 722 }
723 break; 723 break;
724 724
725 case KEY_DC: 725 case KEY_DC:
726 case 'D' - 'A' + 1: // readline ^D 726 case 'D' - 'A' + 1: // readline ^D
727 if (m_cursorPosition < current_input().length()) 727 if (m_cursorPosition < getCurrentInput().length())
728 { 728 {
729 mutable_current_input().remove_at (m_cursorPosition); 729 getEditableInput().remove_at (m_cursorPosition);
730 m_needInputRender = true; 730 m_needInputRender = true;
731 } 731 }
732 break; 732 break;
733 733
734 case KEY_PPAGE: 734 case KEY_PPAGE:
748 m_cursorPosition = 0; 748 m_cursorPosition = 0;
749 } 749 }
750 break; 750 break;
751 751
752 case 'K' - 'A' + 1: // readline ^K - delete from cursor to end 752 case 'K' - 'A' + 1: // readline ^K - delete from cursor to end
753 yank (m_cursorPosition, mutable_current_input().length()); 753 yank (m_cursorPosition, getEditableInput().length());
754 break; 754 break;
755 755
756 case 'W' - 'A' + 1: // readline ^W - delete from previous word bounary to current 756 case 'W' - 'A' + 1: // readline ^W - delete from previous word bounary to current
757 yank (find_previous_word(), m_cursorPosition); 757 yank (findPreviousWord(), m_cursorPosition);
758 break; 758 break;
759 759
760 case 'Y' - 'A' + 1: // readline ^Y - paste previously deleted text 760 case 'Y' - 'A' + 1: // readline ^Y - paste previously deleted text
761 if (not m_pasteBuffer.is_empty()) 761 if (not m_pasteBuffer.is_empty())
762 { 762 {
763 mutable_current_input().insert (m_cursorPosition, m_pasteBuffer); 763 getEditableInput().insert (m_cursorPosition, m_pasteBuffer);
764 m_cursorPosition += m_pasteBuffer.length(); 764 m_cursorPosition += m_pasteBuffer.length();
765 m_needInputRender = true; 765 m_needInputRender = true;
766 } 766 }
767 break; 767 break;
768 768
769 case '\t': 769 case '\t':
770 { 770 {
771 int space = current_input().find (" "); 771 int space = getCurrentInput().find (" ");
772 772
773 if (m_inputState == INPUTSTATE_NORMAL 773 if (m_inputState == INPUTSTATE_NORMAL
774 and m_cursorPosition > 0 774 and m_cursorPosition > 0
775 and (space == -1 or space >= m_cursorPosition)) 775 and (space == -1 or space >= m_cursorPosition))
776 { 776 {
777 String start = current_input().mid (0, m_cursorPosition); 777 String start = getCurrentInput().mid (0, m_cursorPosition);
778 m_session.request_tab_complete (start); 778 m_session.request_tab_complete (start);
779 } 779 }
780 } 780 }
781 break; 781 break;
782 782
789 break; // handled above 789 break; // handled above
790 790
791 case INPUTSTATE_ADDRESS: 791 case INPUTSTATE_ADDRESS:
792 try 792 try
793 { 793 {
794 m_remoteAddress = IPAddress::from_string (current_input()); 794 m_remoteAddress = IPAddress::from_string (getCurrentInput());
795 } 795 }
796 catch (std::exception& e) 796 catch (std::exception& e)
797 { 797 {
798 print ("%s\n", e.what()); 798 print ("%s\n", e.what());
799 return; 799 return;
800 } 800 }
801 801
802 if (m_remoteAddress.port == 0) 802 if (m_remoteAddress.port == 0)
803 m_remoteAddress.port = 10666; 803 m_remoteAddress.port = 10666;
804 804
805 set_input_state (INPUTSTATE_PASSWORD); 805 setInputState (INPUTSTATE_PASSWORD);
806 break; 806 break;
807 807
808 case INPUTSTATE_PASSWORD: 808 case INPUTSTATE_PASSWORD:
809 if (m_inputState == INPUTSTATE_PASSWORD and not current_input().is_empty()) 809 if (m_inputState == INPUTSTATE_PASSWORD and not getCurrentInput().is_empty())
810 { 810 {
811 m_session.disconnect(); 811 m_session.disconnect();
812 m_session.set_password (current_input()); 812 m_session.set_password (getCurrentInput());
813 m_session.connect (m_remoteAddress); 813 m_session.connect (m_remoteAddress);
814 set_input_state (INPUTSTATE_NORMAL); 814 setInputState (INPUTSTATE_NORMAL);
815 } 815 }
816 break; 816 break;
817 817
818 case INPUTSTATE_NORMAL: 818 case INPUTSTATE_NORMAL:
819 if (current_input()[0] == '/') 819 if (getCurrentInput()[0] == '/')
820 { 820 {
821 handleCommand(current_input()); 821 handleCommand(getCurrentInput());
822 flush_input(); 822 flushInput();
823 } 823 }
824 else if (m_session.send_command (current_input())) 824 else if (m_session.send_command (getCurrentInput()))
825 { 825 {
826 flush_input(); 826 flushInput();
827 } 827 }
828 break; 828 break;
829 } 829 }
830 break; 830 break;
831 831
832 case 'N' - 'A' + 1: // ^N 832 case 'N' - 'A' + 1: // ^N
833 if (m_inputState == INPUTSTATE_NORMAL) 833 if (m_inputState == INPUTSTATE_NORMAL)
834 safe_disconnect ([&](bool){set_input_state (INPUTSTATE_ADDRESS);}); 834 safeDisconnect ([&](bool){setInputState (INPUTSTATE_ADDRESS);});
835 break; 835 break;
836 836
837 case '\x1b': // Escape 837 case '\x1b': // Escape
838 // We may have an alt key coming 838 // We may have an alt key coming
839 ch = ::getch(); 839 ch = ::getch();
843 switch (ch) 843 switch (ch)
844 { 844 {
845 case 'b': 845 case 'b':
846 case 'B': 846 case 'B':
847 // readline alt-b - move one word to the left 847 // readline alt-b - move one word to the left
848 m_cursorPosition = find_previous_word(); 848 m_cursorPosition = findPreviousWord();
849 m_needInputRender = true; 849 m_needInputRender = true;
850 break; 850 break;
851 851
852 case 'f': 852 case 'f':
853 case 'F': 853 case 'F':
854 // readline alt-f - move one word to the right 854 // readline alt-f - move one word to the right
855 m_cursorPosition = find_next_word(); 855 m_cursorPosition = findNextWord();
856 m_needInputRender = true; 856 m_needInputRender = true;
857 break; 857 break;
858 858
859 case 'd': 859 case 'd':
860 case 'D': 860 case 'D':
861 // readline alt-d - delete from here till next word boundary 861 // readline alt-d - delete from here till next word boundary
862 yank (m_cursorPosition, find_next_word()); 862 yank (m_cursorPosition, findNextWord());
863 break; 863 break;
864 864
865 case KEY_BACKSPACE: // alt+backspace, remove previous word 865 case KEY_BACKSPACE: // alt+backspace, remove previous word
866 case '\b': 866 case '\b':
867 yank (find_previous_word(), m_cursorPosition); 867 yank (findPreviousWord(), m_cursorPosition);
868 break; 868 break;
869 } 869 }
870 } 870 }
871 else 871 else
872 { 872 {
873 // No alt-key, handle pure escape 873 // No alt-key, handle pure escape
874 if (m_inputState == INPUTSTATE_PASSWORD) 874 if (m_inputState == INPUTSTATE_PASSWORD)
875 set_input_state (INPUTSTATE_ADDRESS); 875 setInputState (INPUTSTATE_ADDRESS);
876 else if (m_inputState == INPUTSTATE_ADDRESS) 876 else if (m_inputState == INPUTSTATE_ADDRESS)
877 set_input_state (INPUTSTATE_NORMAL); 877 setInputState (INPUTSTATE_NORMAL);
878 } 878 }
879 break; 879 break;
880 } 880 }
881 881
882 render(); 882 render();
884 884
885 // ------------------------------------------------------------------------------------------------- 885 // -------------------------------------------------------------------------------------------------
886 // 886 //
887 void Interface::render() 887 void Interface::render()
888 { 888 {
889 if (m_needStatusBarRender) render_statusbar(); 889 if (m_needStatusBarRender) renderStatusBar();
890 if (m_needInputRender) render_input(); 890 if (m_needInputRender) renderInput();
891 if (m_needOutputRender) render_output(); 891 if (m_needOutputRender) renderOutput();
892 if (m_needNicklistRender) render_nicklist(); 892 if (m_needNicklistRender) renderNicklist();
893 893
894 if (m_needRefresh) 894 if (m_needRefresh)
895 { 895 {
896 position_cursor(); 896 positionCursor();
897 refresh(); 897 refresh();
898 m_needRefresh = false; 898 m_needRefresh = false;
899 } 899 }
900 } 900 }
901 901
903 // 903 //
904 void Interface::vprint (const char* fmtstr, va_list args) 904 void Interface::vprint (const char* fmtstr, va_list args)
905 { 905 {
906 String message; 906 String message;
907 message.vsprintf (fmtstr, args); 907 message.vsprintf (fmtstr, args);
908 print_to_console (message); 908 printToConsole (message);
909 } 909 }
910 910
911 // ------------------------------------------------------------------------------------------------- 911 // -------------------------------------------------------------------------------------------------
912 // 912 //
913 void __cdecl Interface::printText (const char* fmtstr, ...) 913 void __cdecl Interface::printText (const char* fmtstr, ...)
922 // 922 //
923 void __cdecl Interface::print (const char* fmtstr, ...) 923 void __cdecl Interface::print (const char* fmtstr, ...)
924 { 924 {
925 va_list args; 925 va_list args;
926 va_start (args, fmtstr); 926 va_start (args, fmtstr);
927 print_to_console (TEXTCOLOR_BrightBlue); 927 printToConsole (TEXTCOLOR_BrightBlue);
928 vprint (fmtstr, args); 928 vprint (fmtstr, args);
929 va_end (args); 929 va_end (args);
930 } 930 }
931 931
932 // ------------------------------------------------------------------------------------------------- 932 // -------------------------------------------------------------------------------------------------
933 // 933 //
934 void __cdecl Interface::printWarning (const char* fmtstr, ...) 934 void __cdecl Interface::printWarning (const char* fmtstr, ...)
935 { 935 {
936 va_list args; 936 va_list args;
937 va_start (args, fmtstr); 937 va_start (args, fmtstr);
938 print_to_console (TEXTCOLOR_BrightYellow "-!- "); 938 printToConsole (TEXTCOLOR_BrightYellow "-!- ");
939 vprint (fmtstr, args); 939 vprint (fmtstr, args);
940 va_end (args); 940 va_end (args);
941 } 941 }
942 942
943 // ------------------------------------------------------------------------------------------------- 943 // -------------------------------------------------------------------------------------------------
944 // 944 //
945 void __cdecl Interface::printError (const char* fmtstr, ...) 945 void __cdecl Interface::printError (const char* fmtstr, ...)
946 { 946 {
947 va_list args; 947 va_list args;
948 va_start (args, fmtstr); 948 va_start (args, fmtstr);
949 print_to_console (TEXTCOLOR_BrightRed "!!! "); 949 printToConsole (TEXTCOLOR_BrightRed "!!! ");
950 vprint (fmtstr, args); 950 vprint (fmtstr, args);
951 va_end (args); 951 va_end (args);
952 } 952 }
953 953
954 // ------------------------------------------------------------------------------------------------- 954 // -------------------------------------------------------------------------------------------------
955 // 955 //
956 void Interface::print_to_console (String message) 956 void Interface::printToConsole (String message)
957 { 957 {
958 // Zandronum sometimes sends color codes as "\\c" and sometimes as "\x1C". 958 // Zandronum sometimes sends color codes as "\\c" and sometimes as "\x1C".
959 // Let's correct that on our end and hope this won't cause conflicts. 959 // Let's correct that on our end and hope this won't cause conflicts.
960 message.replace ("\\c", "\x1C"); 960 message.replace ("\\c", "\x1C");
961 961
1030 1030
1031 // ------------------------------------------------------------------------------------------------- 1031 // -------------------------------------------------------------------------------------------------
1032 // 1032 //
1033 void Interface::tabComplete (const String& part, String complete) 1033 void Interface::tabComplete (const String& part, String complete)
1034 { 1034 {
1035 String& input = mutable_current_input(); 1035 String& input = getEditableInput();
1036 1036
1037 if (input.starts_with (part)) 1037 if (input.starts_with (part))
1038 { 1038 {
1039 if (input[part.length()] != ' ') 1039 if (input[part.length()] != ' ')
1040 complete += ' '; 1040 complete += ' ';
1101 // ------------------------------------------------------------------------------------------------- 1101 // -------------------------------------------------------------------------------------------------
1102 // 1102 //
1103 void Interface::disconnected() 1103 void Interface::disconnected()
1104 { 1104 {
1105 print("Disconnected from %s\n", m_session.address().to_string(IPAddress::WITH_PORT).chars()); 1105 print("Disconnected from %s\n", m_session.address().to_string(IPAddress::WITH_PORT).chars());
1106 reset_title(); 1106 resetTitle();
1107 renderFull(); 1107 renderFull();
1108 } 1108 }
1109 1109
1110 // ------------------------------------------------------------------------------------------------- 1110 // -------------------------------------------------------------------------------------------------
1111 // 1111 //
1112 void Interface::reset_title() 1112 void Interface::resetTitle()
1113 { 1113 {
1114 m_title.sprintf ("%s %s (%s)", application_name(), full_version_string(), changeset_date_string()); 1114 m_title.sprintf ("%s %s (%s)", application_name(), full_version_string(), changeset_date_string());
1115 } 1115 }
1116 1116
1117 // ------------------------------------------------------------------------------------------------- 1117 // -------------------------------------------------------------------------------------------------
1118 // 1118 //
1119 void Interface::flush_input() 1119 void Interface::flushInput()
1120 { 1120 {
1121 m_inputHistory.insert (0, ""); 1121 m_inputHistory.insert (0, "");
1122 m_inputCursor = 0; 1122 m_inputCursor = 0;
1123 m_needInputRender = true; 1123 m_needInputRender = true;
1124 } 1124 }

mercurial