/* Terminality - a portable terminal handling library * Copyright (C) 1998-2002, Emil Mikulic. * This is LGPL - look at COPYING.LIB */ /* Project: Terminality/GUI * File: textbox.cpp * Author: Emil Mikulic, Michal Safranek * Description: Implements the textbox class */ #include const char textbox_rcsid[] = "$Id: textbox.cpp,v 1.17 2002/07/26 01:39:40 darkmoon Exp $"; /* Textbox elements */ void textbox::element(const textbox_element el) { if (has_color()) { /* Pretty colors */ switch (el) { case TB_begin: if (focus) setcolor(SELECTED_FRAME,SELECTED_FRAME_BG); else setcolor(FRAME,FRAME_BG); if (scroll) printw("%c", BEG_MORE_CHR); else printw("%c", BEG_CHR); break; case TB_middle: if (focus) setcolor(SELECTED_SPACE,SELECTED_SPACE_BG); else setcolor(SPACE,SPACE_BG); printw("%c", MID_CHR); break; case TB_char: if (focus) setcolor(SELECTED_TEXT,SELECTED_TEXT_BG); else setcolor(TEXT,TEXT_BG); break; case TB_end: if (focus) setcolor(SELECTED_FRAME,SELECTED_FRAME_BG); else setcolor(FRAME,FRAME_BG); if (scroll + width < count) printw("%c", END_MORE_CHR); else printw("%c", END_CHR); break; } } else { /* Plain */ switch (el) { case TB_begin: if (focus) highvideo(); else normvideo(); if (scroll) printw("%c", BEG_MORE_CHR); else printw("%c", BEG_CHR); break; case TB_middle: lowvideo(); printw("%c", MID_CHR); break; case TB_char: if (focus) normvideo(); else lowvideo(); break; case TB_end: if (focus) highvideo(); else normvideo(); if (scroll + width < count) printw("%c", END_MORE_CHR); else printw("%c", END_CHR); break; } } } #define TB_SETUP() FRAME = COLOR_TEXTBOX_FRAME; \ SPACE = COLOR_TEXTBOX_SPACE; SELECTED_SPACE = COLOR_TEXTBOX_SSPACE; \ TEXT_BG = COLOR_TEXTBOX_TEXTBG; SPACE_BG = COLOR_TEXTBOX_SPACEBG; \ FRAME_BG = COLOR_TEXTBOX_FRAMEBG; TEXT = COLOR_TEXTBOX_TEXT; \ SELECTED_TEXT_BG = COLOR_TEXTBOX_STEXTBG; \ BEG_CHR = '['; END_CHR = ']'; \ SELECTED_SPACE_BG = COLOR_TEXTBOX_SSPACEBG; MID_CHR = '.'; \ SELECTED_FRAME_BG = COLOR_TEXTBOX_SFRAMEBG; BEG_MORE_CHR = '{'; \ SELECTED_TEXT = COLOR_TEXTBOX_STEXT; END_MORE_CHR = '}'; \ SELECTED_FRAME = COLOR_TEXTBOX_SFRAME; // Construct textbox at holding characters textbox::textbox(const int xx, const int yy, const int w) { // Encapsulate data x = xx; y = yy; maxlength = width = w; // Allocate buffer buf = (char*)xmalloc(width+1); memset(buf, 0, maxlength+1); buf[0] = 0; scroll = pos = count = 0; focus = false; charmap = NULL; type_id = Textbox; visible = true; fixed_colors = false; TB_SETUP(); } // Construct textbox at using for a buffer textbox::textbox(const int xx, const int yy, const char *s) { // Encapsulate data x = xx; y = yy; // Get width maxlength = width = strlen(s); // Allocate buffer buf = (char*)xmalloc(width+1); memset(buf, 0, maxlength+1); // Copy buffer strcpy(buf, s); count = width; scroll = pos = 0; focus = false; charmap = NULL; type_id = Textbox; visible = true; fixed_colors = false; TB_SETUP(); } // Construct textbox at using for a buffer textbox::textbox(const int xx, const int yy, const char *s, const int w) { // Encapsulate data x = xx; y = yy; // Get width maxlength = width = w; // Allocate buffer buf = (char*)xmalloc(width+1); memset(buf, 0, maxlength+1); // Copy buffer strcpy(buf, s); count = strlen(s); scroll = pos = 0; focus = false; charmap = NULL; type_id = Textbox; visible = true; fixed_colors = false; TB_SETUP(); } // Construct textbox at holding characters, maxlength textbox::textbox(const int xx, const int yy, const int w, const int m) { // Encapsulate data x = xx; y = yy; width = w; maxlength = m; // Allocate buffer buf = (char*)xmalloc(maxlength+1); memset(buf, 0, maxlength+1); buf[0] = 0; scroll = pos = count = 0; focus = false; charmap = NULL; visible = true; fixed_colors = false; type_id = Textbox; TB_SETUP(); } // Construct textbox at using for a buffer, maxlength textbox::textbox(const int xx, const int yy, const char *s, const int w, const int m) { // Encapsulate data x = xx; y = yy; // Get width width = w; maxlength = m; // Allocate buffer buf = (char*)xmalloc(maxlength+1); memset(buf, 0, maxlength+1); // Copy buffer strcpy(buf, s); count = strlen(s); scroll = pos = 0; focus = false; charmap = NULL; type_id = Textbox; visible = true; fixed_colors = false; TB_SETUP(); } // Destroy textbox textbox::~textbox() { // Deallocate buffer! xfree(buf); } // Draw textbox in its current state void textbox::draw(void) { char *temp; if (!visible) return; // Draw empty box gotoxy(x,y); element(TB_begin); for (int i=0; i 0) { killch(scroll+pos); pos--; count--; draw(); if(onchange) onchange(Textbox, this); } else { if (scroll > 0) { killch(scroll); /* Jump forward */ if (width > 1 && count > 1) { if (scroll > width) { pos += width - 1; scroll -= width; } else { pos += scroll-1; scroll = 0; } } else { scroll--; } count--; draw(); if(onchange) onchange(Textbox, this); } else { beep(); } } break; case KEY_DEL: /* Delete - delete letter in front (if we can) */ if (pos+scroll < count) { killch(pos+scroll+1); count--; draw(); if(onchange) onchange(Textbox, this); } else { beep(); } break; case KEY_INS: /* Change edit-mode */ if (overwrite) { overwrite = false; set_cursor(line); } else { overwrite = true; set_cursor(rect); } break; case KEY_LEFT: if (pos > 0) { pos--; draw(); } else { if (scroll > 0) scroll--; draw(); } break; case KEY_RIGHT: if (pos+scroll < count) { pos++; if (pos > width) { pos--; scroll++; } draw(); } break; case KEY_HOME: pos = 0; scroll = 0; draw(); break; case KEY_END: if (count > width) { pos = width; scroll = count - pos; } else { pos = count; scroll = 0; } draw(); break; default: /* Is it acceptable? */ if (32 > c || c > 255) { beep(); break; } if (charmap) { if (!strrchr(charmap, c)) { beep(); break; } } /* Overwrite-mode */ if (overwrite) { /* If we're out too far then beep */ if (pos+scroll == maxlength) { beep(); break; } if (pos+scroll == count) { count++; } /* Insert-mode */ } else { /* If we're out too far then beep */ if (count == maxlength) { beep(); break; } if (pos+scroll < count) { for (tmp=count; tmp>pos+scroll-1; tmp--) buf[tmp] = buf[tmp-1]; } count++; } buf[pos + scroll] = c; pos++; if (pos > width) { pos--; scroll++; } draw(); if(onchange) onchange(Textbox, this); break; } } while (result == 101); visible = old_vis; buf[count] = 0; set_cursor(cs); focus = false; return result; } // Blocking get (cannot be aborted) char *textbox::get(void) { while (1) { switch (getnb()) { case 27: return NULL; case 0: return buf; } } } // Sets tb's content int textbox::set_buf(char *buffer) { int i; memset(buf, 0, maxlength + 1); for (i = 0; i < maxlength && (unsigned) i < strlen(buffer); i++) { buf[i] = buffer[i]; } buf[++i] = 0; count = i-1; pos = scroll = 0; if(onchange) onchange(Textbox, this); return 1; } // Change scheme void textbox::change_scheme(void) { if (fixed_colors) return; SELECTED_FRAME = COLOR_TEXTBOX_SFRAME; FRAME = COLOR_TEXTBOX_FRAME; SPACE = COLOR_TEXTBOX_SPACE; SELECTED_SPACE = COLOR_TEXTBOX_SSPACE; TEXT_BG = COLOR_TEXTBOX_TEXTBG; SPACE_BG = COLOR_TEXTBOX_SPACEBG; FRAME_BG = COLOR_TEXTBOX_FRAMEBG; TEXT = COLOR_TEXTBOX_TEXT; SELECTED_SPACE_BG = COLOR_TEXTBOX_SSPACEBG; SELECTED_FRAME_BG = COLOR_TEXTBOX_SFRAMEBG; SELECTED_TEXT_BG = COLOR_TEXTBOX_STEXTBG; SELECTED_TEXT = COLOR_TEXTBOX_STEXT; }