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