summaryrefslogtreecommitdiff
path: root/src/unite/internal/state.h
blob: e294372bc7026aebc7292e0ce9f227556a076bab (plain)
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#ifndef FQTERM_UNITE_STATE
#define FQTERM_UNITE_STATE

#include <QByteArray>
#include "session.h"

namespace FQTerm {
class FQTermUniteDecode;
typedef bool (FQTermUniteDecode:: *StateFunc)();

struct StateOption {
  int byte; // char value to look for; -1==end/default
  StateFunc action;
  StateOption *nextState;
};



class FQTermUniteDecode {
public:
  FQTermUniteDecode();
  virtual ~FQTermUniteDecode() {}
  //should return number of chars consumed
  virtual int processInput(const QByteArray& input);
protected:
  virtual bool keyReceived(int key) = 0;
  //tab = 7, backspace = 8, delete is *[3~, page up is 5~, page down is 6~, home is 1~, end is 4~, double esc is double esc, 
  //up is A, down is B, left is D, right is C.
  //F1 - F12 11~  12~  13~  14~  15~  17~  18~  19~  20~  21~  23~  24~  
  //static char* specialKeys[];
  enum SPECIALKEY{SPECIALKEYSTART = 0x10000, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
    UP, DOWN, LEFT, RIGHT, DOUBLEESC, INSERT, HOME, END, PGUP, PGDOWN, DELETE};

  // Virtual Keys: move cursor
  bool cursorLeft();
  bool cursorDown();
  bool cursorRight();
  bool cursorUp();

  // other escape sequence actions
  bool normalInput();

  //double esc pressed
  bool doubleEsc();

  // action parameters
  bool clearParam();
  bool paramDigit();
  //function key map
  bool functionKey();
private:
  // ********** decoder states ****************
  StateOption *current_state_;
  int param_; //valid when > 0.
  const char* data_;
  int inputLength_;
  int currentByte_;
  QByteArray leftToDecode_;
  struct EscStateMachine {
    static StateOption normal_state_[], esc_state_[], bracket_state_[];
  };
};

class FQTermUniteState : public QObject,
  public FQTermUniteDecode {
    Q_OBJECT;
public:
  FQTermUniteState(FQTermUniteSessionContext* context);
  virtual ~FQTermUniteState() {}
  virtual void initialize() = 0;


protected:
  //util functions
  //cursor manipulations
  void moveCursorRelative(int dx, int dy);
  void moveCursorAbsolute(int x, int y);
  void moveCursorHome();
  //To scroll up, dy < 0, scroll down, dy > 0. 
  void scrollWindow(int dy);
  void moveCursorNextLine();
  void saveCursor();
  void restoreCursor();

  //attr control
  enum CHARATTR{DEFAULTATTR = -1, CLEARATTR = 0, BOLD = 1, LOWINTENSITY = 2, UNDERLINE = 4, BLINK = 5, REVERSECOLOR = 7, INVISIBLE = 8};
  void setAttr(int attr);
  enum CHARCOLOR{BLACK = 0, RED = 1, GREEN = 2, YELLOW = 3, BLUE = 4, PURPLE = 5, INDIGO = 6, WHITE = 7};
  void setForegroundColor(int color, bool highlight = true);
  void setBackgroundColor(int color);

  //clear lines/screen
  enum CLEARLINE{CURSORRIGHT = 0, CURSORLEFT = 1, WHOLELINE = 2};
  void clearLine(int part);
  enum CLEARSCREEN{CURSORDOWN = 0, CURSORUP = 1, WHOLESCREEN = 2};
  void clearScreen(int part);

  //window setting
  void setWindowRange(int startLine, int endLine);

  QByteArray escape();
  QByteArray cursorStr();
  void write(const QByteArray& output);
  void quit() {context_->quit();}
  FQTermUniteState* setNextState(int state, bool init = true) {return context_->setCurrentState(state, init);}
  int row() {return context_->row();}
  int column() {return context_->column();}


  friend struct cursorGuard;
  struct cursorGuard {
    cursorGuard(FQTermUniteState& state) : state_(state) {state_.saveCursor();}
    ~cursorGuard() {state_.restoreCursor();}
  private:
    FQTermUniteState& state_;
  };
private:
  FQTermUniteSessionContext* context_;
  int lastState_;
};

class FQTermUniteMenu {
public:
  FQTermUniteMenu() {current_ = 0;}
  virtual ~FQTermUniteMenu() {}
protected:
  int addEntry(char key);
  int findEntry(char key);
  void clearEntry();
  int currentEntry();
  int setCurrentEntry(char key);
  int setCurrentIndex(int index);

  int nextEntry();
  int prevEntry();
  virtual void clearPointer(int index) = 0;
  virtual void drawPointer(int index) = 0;
  virtual void enterEntry() = 0;
private:
  std::vector<char> entries_;
  int current_;
};


class FQTermWelcomeState : public FQTermUniteState, public FQTermUniteMenu {
  Q_OBJECT;
public:
  FQTermWelcomeState(FQTermUniteSessionContext* context);
  virtual void initialize();
protected:
  virtual bool keyReceived(int key);
private:
  virtual void clearPointer(int index);
  virtual void drawPointer(int index);
  virtual void enterEntry();
};

class FQTermExitState : public FQTermUniteState, public FQTermUniteMenu {
  Q_OBJECT;
public:
  FQTermExitState(FQTermUniteSessionContext* context);
  virtual void initialize();
protected:
  virtual bool keyReceived(int key);
private:
  virtual void clearPointer(int index);
  virtual void drawPointer(int index);
  void enterEntry();
};

class SplittedArticleBuffer {
public:
  SplittedArticleBuffer(const QByteArray& utf8Content, int column, int row = 24);
  ~SplittedArticleBuffer() {}
  int count() {return lines_.size();}
  QByteArray& retriveLine(size_t index) {return lines_[index];}
private:
  static int findNextLine(const QString& str, int start, int column);
  std::vector<QByteArray> lines_;
};

//TODO: content should be shared.
//TODO: buffer should be opt-ed.
class FQTermReadingState : public FQTermUniteState {
  Q_OBJECT;
public:
  FQTermReadingState(FQTermUniteSessionContext* context);
  ~FQTermReadingState();
  virtual void initialize();
  void setFile(const QString& filename);
  void setReturnState(int state) {returnState_ = state;}
protected:
  virtual bool keyReceived(int key);
private:
  void drawLines(int count, int yPos);
  void drawFooter();
  void adjustLineByDiff(int delta);
  SplittedArticleBuffer* saBuffer_;
  QByteArray content_;
  int currentStartLine_;
  int returnState_;
};


class FQTermHelpState : public FQTermUniteState, public FQTermUniteMenu {
  Q_OBJECT;
public:
  FQTermHelpState(FQTermUniteSessionContext* context);
  virtual void initialize();
protected:
  virtual bool keyReceived(int key);
private:
  virtual void clearPointer(int index);
  virtual void drawPointer(int index);
  virtual void enterEntry();
};

} // namespace FQTerm
#endif