1 /* 2 ** Copyright 2002-2011, Double Precision Inc. 3 ** 4 ** See COPYING for distribution information. 5 */ 6 7 #ifndef cursesfield_H 8 #define cursesfield_H 9 10 #include "mycurses.H" 11 #include "cursesflowedline.H" 12 #include <wchar.h> 13 #include <vector> 14 15 /////////////////////////////////////////////////////////////////////////// 16 // 17 // An editable field. 18 // 19 20 class CursesField : public Curses { 21 22 editablewidechar text; // Editable text. 23 24 void getbeforeafter(widecharbuf &, widecharbuf &); 25 26 void setselectpos(); 27 28 size_t width; // Field width 29 size_t maxlength; // Maximum text length 30 31 size_t shiftoffset; // First text char shown 32 size_t selectpos; // Start of selection position 33 34 char32_t passwordChar; // password overlay character 35 bool yesnoField; // True if yes/no field. 36 37 std::u32string optionField; // One character list of options 38 39 std::vector<std::pair<std::string, std::string> > optionHelp; // Option help keys 40 // This field is of primary use by cursesstatusbar 41 42 bool isUnderlined; 43 protected: 44 Curses::CursesAttr attribute; 45 public: 46 static std::u32string yesKeys, noKeys; 47 static char32_t yankKey, clrEolKey; 48 49 static std::list<CursesFlowedLine> cutBuffer; // for cut/paste. 50 51 CursesField(CursesContainer *parent, 52 size_t widthArg=20, 53 size_t maxlengthArg=255, 54 std::string initValue=""); 55 ~CursesField(); 56 setUnderlined(bool flag)57 void setUnderlined(bool flag) { isUnderlined=flag; } 58 void setRow(int row); 59 void setCol(int col); 60 void setText(std::string textArg); 61 void setAttribute(Curses::CursesAttr attr); 62 void setCursorPos(size_t o); 63 std::string getText() const; // Return entered text 64 65 int getWidth() const; // Our width is known 66 int getHeight() const; // We're one row high 67 68 void setWidth(int); 69 70 void setPasswordChar(char32_t ch='*') { passwordChar=ch; } setYesNo()71 void setYesNo() { yesnoField=true; } setOptionField(const std::u32string & vec)72 void setOptionField(const std::u32string &vec) 73 { 74 optionField=vec; 75 } 76 77 void setOptionHelp(const std::vector< std::pair<std::string, std::string> > &help); 78 getOptionHelp()79 const std::vector< std::pair<std::string, std::string> > &getOptionHelp() const 80 { 81 return optionHelp; 82 } 83 84 void draw(); 85 86 int getCursorPosition(int &row, int &col); 87 bool processKeyInFocus(const Key &key); 88 89 bool isFocusable(); // Yes we are 90 void focusGained(); // Select old text automatically at entry. 91 void focusLost(); // Unselect any selected text at exit. 92 93 void erase(); 94 private: 95 void left(); 96 void right(); 97 }; 98 99 ////////////////////////////////////////////////////////////////////////// 100 // 101 // Instead of subclassing a CursesField, provide a template to make it easier 102 // to have CursesField be a member of another object. Typical usage: 103 // 104 // class X { 105 // 106 // CursesFieldRedirect<X> field1; 107 // CursesFieldRedirect<X> field2; 108 // 109 // void field1Enter(); // ENTER key pressed in field1 110 // void field2Enter(); // ENTER key pressed in field2 111 // 112 // }; 113 // 114 // 115 // X::X() 116 // { 117 // 118 // field1=this; 119 // field2=this; 120 // 121 // field1= &X::field1Enter; 122 // field2= &X::field2Enter; 123 // } 124 // 125 126 template<class T> class CursesFieldRedirect : public CursesField { 127 128 public: 129 T *myClass; 130 void (T::*myMethod)(void); 131 132 CursesFieldRedirect(CursesContainer *parent, 133 size_t widthArg=20, 134 size_t maxlengthArg=255, 135 std::string initValue="") CursesField(parent,widthArg,maxlengthArg,initValue)136 : CursesField(parent, widthArg, maxlengthArg, initValue), 137 myClass(0), myMethod(0) 138 { 139 } 140 ~CursesFieldRedirect()141 ~CursesFieldRedirect() 142 { 143 } 144 145 void operator=(T *p) { myClass=p; } 146 void operator=( void (T::*p)(void) ) { myMethod=p; } 147 processKeyInFocus(const Key & key)148 bool processKeyInFocus(const Key &key) 149 { 150 if (key == Key::ENTER && myClass && myMethod) 151 { 152 (myClass->*myMethod)(); 153 return true; 154 } 155 156 return CursesField::processKeyInFocus(key); 157 } 158 }; 159 160 #endif 161