Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

TextEntry.C

00001 /* $Id: TextEntry.C,v 1.1 2001/01/01 00:25:56 rpav Exp $
00002  *
00003  * SFW - Studio FrameWork
00004  * Copyright (C) 2000  Ryan Pavlik
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  * 
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00019  *
00020  */
00021 
00022 /*
00023  * TextEntry.C
00024  *
00025  * TextEntry implementation
00026  *
00027  */ 
00028 
00029 #include <SFW/SFW.H>
00030 #include <SFW/Curses/TextEntry.H>
00031 
00032 TYPE_INIT(SFW::Curses::TextEntry);
00033 TYPE_INIT(SFW::Curses::TextEntry::Method);
00034 
00035 using namespace SFW;
00036 using namespace SFW::Curses;
00037 
00038 TextEntry::TextEntry(Window *_w, string _prompt,
00039                      int _r, int _c, int _width,
00040                      string _text)
00041     : binding(this) {
00042 
00043     w      = _w;
00044     prompt = _prompt;
00045     r      = _r;
00046     c      = _c;
00047 
00048     width      = _width;
00049     entryWidth = _width - prompt.size();
00050 
00051     maxLength = 0;
00052     text      = _text;
00053     cx        = 0;
00054     toffs     = 0;
00055 
00056     histpos   = history.end();
00057 
00058     /* Add the bindings */
00059     binding.bind(Key::Enter, new Method(&TextEntry::finish_edit));
00060     binding.bind(10,         new Method(&TextEntry::finish_edit));
00061     binding.bind(13,         new Method(&TextEntry::finish_edit));
00062 
00063     binding.bind(7,          new Method(&TextEntry::abort_edit));
00064 
00065     binding.bind(Key::Left,  new Method(&TextEntry::cursor_left));
00066     binding.bind(Key::Right, new Method(&TextEntry::cursor_right));
00067     binding.bind(Key::Home,  new Method(&TextEntry::cursor_bol));
00068     binding.bind(1,          new Method(&TextEntry::cursor_bol));
00069     binding.bind(Key::End,   new Method(&TextEntry::cursor_eol));
00070     binding.bind(5,          new Method(&TextEntry::cursor_eol));
00071 
00072     binding.bind(Key::DC,        new Method(&TextEntry::delete_after));
00073     binding.bind(4,              new Method(&TextEntry::delete_after));
00074     binding.bind(Key::Backspace, new Method(&TextEntry::delete_before));
00075     binding.bind(11,             new Method(&TextEntry::delete_to_eol));
00076     binding.bind(21,             new Method(&TextEntry::delete_to_bol));
00077 
00078     binding.bind(Key::Up,        new Method(&TextEntry::prev_in_history));
00079     binding.bind(Key::Down,      new Method(&TextEntry::next_in_history));
00080 
00081     Method *m = new Method(&TextEntry::insert_self);
00082 
00083     for(int i = 32; i < 127; i++)
00084         binding.bind(i, m);
00085 }
00086 
00087 TextEntry::~TextEntry() {
00088     /* Clean up the history */
00089     for(List::iterator i = history.begin(); i != history.end(); i++)
00090         GC.done(*i);
00091 }
00092 
00093 void TextEntry::draw(bool noRefresh) {
00094     string slice = text.substr(toffs, entryWidth);
00095     
00096     w->addstr(r, c, prompt);
00097     w->addstr(slice);
00098 
00099     w->attrset(Attr::Reverse);
00100     w->addstr(string(entryWidth - slice.size(), ' '));
00101     w->attrset(Attr::Normal);
00102 
00103     w->moveto(r, c + prompt.size() + cx);
00104 
00105     if(!noRefresh)
00106         w->refresh();
00107 }
00108 
00109 void TextEntry::activate() {
00110     finished = false;
00111     aborted  = false;
00112 
00113     Screen::setCursor(true);
00114     
00115     while(!finished) {
00116         draw();
00117         binding.listen();
00118     }
00119 
00120     Screen::setCursor(false);
00121 }
00122 
00123 string TextEntry::getText() {
00124     return text;
00125 }
00126 
00127 void TextEntry::setText(const string &_text) {
00128     text = _text;
00129 
00130     if(cx + toffs > text.size())
00131         cursor_eol(NULL);
00132 }
00133 
00134 bool TextEntry::wasAborted() {
00135     return aborted;
00136 }
00137 
00138 void TextEntry::canAbort(bool _b) {
00139     abortable = _b;
00140 }
00141 
00142 bool TextEntry::canAbort() {
00143     return abortable;
00144 }
00145 
00146 void TextEntry::reset() {
00147     text  = "";
00148     toffs = 0;
00149     cx    = 0;
00150 }
00151 
00152 Object* TextEntry::finish_edit(Object *o) {
00153     var *v = new var(text); GC.use(v);
00154     history.push_back(v);
00155     histpos = history.end();
00156     
00157     finished = true;
00158     
00159     return NULL;
00160 }
00161 
00162 Object* TextEntry::abort_edit(Object *o) {
00163     if(abortable) {
00164         finished = true;
00165         aborted  = true;
00166     }
00167     
00168     return NULL;
00169 }
00170 
00171 Object* TextEntry::insert_self(Object *o) {
00172     var *ch = (var*)o;
00173     
00174     if(text.size()  < maxLength ||
00175        maxLength   == 0) {
00176         text.insert(cx + toffs, string(1, (char)*ch));
00177 
00178         cx++;
00179     }
00180 
00181     if(cx >= entryWidth) {
00182         cx = entryWidth - 1;
00183 
00184         if(text.size() - toffs >= entryWidth)
00185             toffs++;
00186     }
00187                     
00188     return NULL;
00189 }
00190 
00191 Object* TextEntry::cursor_left(Object *o) {
00192     if(cx > 0)
00193         cx--;
00194     else if(toffs > 0)
00195         toffs--;
00196     
00197     return NULL;
00198 }
00199 
00200 Object* TextEntry::cursor_right(Object *o) {
00201     if(cx         < entryWidth - 1 &&
00202        cx + toffs < text.size())
00203         cx++;
00204     else if(toffs + cx < text.size())
00205         toffs++;
00206     
00207     return NULL;
00208 }
00209 
00210 Object* TextEntry::cursor_bol(Object *o) {
00211     cx    = 0;
00212     toffs = 0;
00213     
00214     return NULL;
00215 }
00216 
00217 Object* TextEntry::cursor_eol(Object *o) {
00218     toffs = text.size() - entryWidth + 1;
00219 
00220     if(toffs < 0)
00221         toffs = 0;
00222 
00223     cx = text.size() - toffs;
00224 
00225     return NULL;
00226 }
00227 
00228 Object* TextEntry::delete_after(Object *o) {
00229     text.erase(cx + toffs, 1);
00230     return NULL;
00231 }
00232 
00233 Object* TextEntry::delete_before(Object *o) {
00234     if(toffs + cx)
00235         text.erase(cx + toffs - 1, 1);
00236 
00237     if(cx > 1 && toffs)
00238         cx--;
00239     else if(cx == 1 && toffs)
00240         toffs--;
00241     else if(cx > 0)
00242         cx--;
00243     
00244     return NULL;
00245 }
00246 
00247 Object* TextEntry::delete_to_bol(Object *o) {
00248     text.erase(0, toffs + cx);
00249     cx    = 0;
00250     toffs = 0;
00251     
00252     return NULL;
00253 }
00254 
00255 Object* TextEntry::delete_to_eol(Object *o) {
00256     text.erase(cx);
00257     return NULL;
00258 }
00259 
00260 Object* TextEntry::prev_in_history(Object *o) {
00261     if(histpos != history.begin()) {
00262         histpos--;
00263         text = (string)*(var*)*histpos;
00264         cursor_eol(NULL);
00265     }
00266     
00267     return NULL;
00268 }
00269 
00270 Object* TextEntry::next_in_history(Object *o) {
00271     if(histpos != history.end()) {
00272         histpos++;
00273         text = (string)*(var*)*histpos;
00274         cursor_eol(NULL);
00275     }
00276 
00277     return NULL;
00278 }

Generated at Tue Jan 2 15:38:34 2001 for SFW by doxygen1.2.4 written by Dimitri van Heesch, © 1997-2000