-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstringlist.cpp
145 lines (121 loc) · 3.35 KB
/
stringlist.cpp
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
/**
* @file stringlist.cpp
* @brief Brief description of file.
*
*/
#include <algorithm>
#include <ncurses.h>
#include "stringlist.h"
#include "colours.h"
using namespace std;
static const int WIDTH=25; // not including LHS bar.
void StringList::display(){
// this overwrites the right hand part of the display.
int scrw,scrh;
getmaxyx(stdscr,scrh,scrw);
unsigned int x = scrw-WIDTH;
unsigned int h = scrh-2; // room for filter line and status bar
pagelen=h;
// First draw the column.
attrset(COLOR_PAIR(PAIR_GREEN));
for(unsigned int y=0;y<h+1;y++) // extend past "bottom row" to cover filter line
mvaddch(y,x-1,' ');
attrset(COLOR_PAIR(0));
if(cursor>0 && cursor>=listFiltered.size())
cursor=listFiltered.size()-1; // negative won't happen (tested above)
// integer divide/multiply to get page start
int startpos = cursor/h;
startpos *= h;
for(unsigned int y=0;y<h;y++){
unsigned int i = startpos+y;
move(y,x);
if(i < listFiltered.size()){
attrset(i==cursor ? COLOR_PAIR(PAIR_HILIGHT)|A_BOLD:
COLOR_PAIR(0));
addstr(listFiltered[i].substr(0,WIDTH-1).c_str());
}
clrtoeol();
}
attrset(COLOR_PAIR(0)|A_BOLD);
mvaddstr(h+1,0,prompt.c_str()); // overwrites status line
if(prefix.size())
mvaddstr(h,x,prefix.c_str());
attrset(COLOR_PAIR(0));
}
EditState StringList::handleKey(int k){
unsigned int len = listFiltered.size();
switch(k){
case KEY_UP:
if(cursor>0)cursor--;
break;
case KEY_DOWN:
if(cursor<len-1)cursor++;
break;
case 10:
state=Finished;
break;
case KEY_END:
case 5: // ctrl-e
cursor=len-1;
break;
case KEY_HOME:
case 1: // ctrl-a
cursor=0;
break;
case KEY_NPAGE:case 6: // ctrl-f
if(len){
cursor+=pagelen;
if(cursor>len-1)cursor=len-1;
}
break;
case KEY_PPAGE:case 2: // ctrl-b
if(cursor>pagelen)
cursor-=pagelen;
break;
case 7:
state=Aborted;
break;
case 11: // ctrl-k
prefix="";
recalcFilter();
break;
case KEY_DC:case KEY_BACKSPACE:case 8:
// shorten filter
if(prefix.size())
prefix.resize(prefix.size()-1);
recalcFilter();
break;
default:
if(k<128 && k>=32){
prefix+=k;
recalcFilter();
}
break;
}
return state;
}
void StringList::recalcFilter(){
// try to keep the current string
string cur;
if(listFiltered.size() && cursor<listFiltered.size())
cur = listFiltered[cursor];
else
cur = "";
// do the filtering
listFiltered.clear();
vector<string>::iterator it;
for(it = list.begin();it!=list.end();it++){
if((*it).compare(0,prefix.size(),prefix)==0)
listFiltered.push_back(*it);
}
// sort filtered list
sort(listFiltered.begin(),listFiltered.end());
// try to keep the current item
if(cur.size()){
for(unsigned int i=0;i<listFiltered.size();i++){
if(listFiltered[i].compare(0,prefix.size(),prefix))
cursor=i;
}
} else
cursor=0;
}