1 /*
2 ** Copyright 2002-2011, Double Precision Inc.
3 **
4 ** See COPYING for distribution information.
5 */
6 
7 #include "curses_config.h"
8 #include "cursesdialog.H"
9 #include "curseslabel.H"
10 #include "cursesfield.H"
11 
12 using namespace std;
13 
CursesDialog(CursesContainer * parent)14 CursesDialog::CursesDialog(CursesContainer *parent)
15 	: CursesContainer(parent), max_label_width(0), max_field_width(0),
16 	  draw_flag(0)
17 {
18 }
19 
~CursesDialog()20 CursesDialog::~CursesDialog()
21 {
22 }
23 
24 // Automatically size to the largest prompt/input field combo
25 
getWidth()26 int CursesDialog::getWidth() const
27 {
28 	return max_label_width + max_field_width;
29 }
30 
31 // Automatically size to the lowest input field
32 
getHeight()33 int CursesDialog::getHeight() const
34 {
35 	int h=0;
36 
37 	vector< pair<CursesLabel *, Curses *> >::const_iterator
38 		b=prompts.begin(), e=prompts.end();
39 
40 	while (b != e)
41 	{
42 		if (b->first && b->first->getRow() >= h)
43 			h=b->first->getRow()+1;
44 
45 		if (b->second && b->second->getRow() >= h)
46 			h=b->second->getRow()+1;
47 		b++;
48 
49 	}
50 
51 	return h;
52 }
53 
draw()54 void CursesDialog::draw()
55 {
56 	draw_flag=1;
57 	CursesContainer::draw();
58 }
59 
addPrompt(CursesLabel * label,Curses * field)60 void CursesDialog::addPrompt(CursesLabel *label, Curses *field)
61 {
62 	size_t maxrow=0;
63 
64 	vector< pair<CursesLabel *, Curses *> >::iterator
65 		b=prompts.begin(), e=prompts.end();
66 
67 	while (b != e)
68 	{
69 		if ( b->first != NULL && (size_t)b->first->getRow() >= maxrow)
70 			maxrow=b->first->getRow()+1;
71 
72 		if ( b->second != NULL && (size_t)b->second->getRow() >=maxrow)
73 			maxrow=b->second->getRow()+1;
74 
75 		b++;
76 	}
77 
78 	addPrompt(label, field, maxrow);
79 }
80 
81 
addPrompt(CursesLabel * label,Curses * field,size_t atRow)82 void CursesDialog::addPrompt(CursesLabel *label, Curses *field, size_t atRow)
83 {
84 	vector< pair<CursesLabel *, Curses *> >::iterator
85 		b=prompts.begin(), e=prompts.end();
86 
87 	// If the new field should precede the existing fields, push them down
88 	// by one row.
89 
90 	while (b != e)
91 	{
92 		if ( b->first != NULL && (size_t)b->first->getRow() >= atRow)
93 			b->first->setRow(b->first->getRow()+1);
94 
95 		if ( b->second != NULL && (size_t)b->second->getRow() >= atRow)
96 			b->second->setRow(b->second->getRow()+1);
97 		b++;
98 	}
99 
100 	if (label != NULL)
101 	{
102 		label->setAlignment(Curses::RIGHT);
103 		label->setRow(atRow);
104 		addChild(label);
105 	}
106 
107 	if (field != NULL)
108 	{
109 		field->setRow(atRow);
110 		addChild(field);
111 	}
112 
113 	prompts.push_back(make_pair(label, field));
114 
115 	int w;
116 
117 	if (label != NULL)
118 	{
119 		w=label->getWidth();
120 
121 		if (w > max_label_width)
122 			max_label_width=w;
123 	}
124 
125 	if (field != NULL)
126 	{
127 		w=field->getWidth();
128 
129 		if (w > max_field_width)
130 			max_field_width=w;
131 	}
132 
133 	b=prompts.begin();
134 	e=prompts.end();
135 
136 	while (b != e)
137 	{
138 		if (b->first != NULL)
139 			b->first->setCol(max_label_width);
140 		if (b->second != NULL)
141 			b->second->setCol(max_label_width);
142 		b++;
143 	}
144 }
145 
delPrompt(CursesLabel * label)146 void CursesDialog::delPrompt(CursesLabel *label)
147 {
148 	vector< pair<CursesLabel *, Curses *> >::iterator
149 		b=prompts.begin(), e=prompts.end();
150 
151 	while (b != e)
152 	{
153 		if (b->first == label)
154 		{
155 			delPrompt(b, b->first->getRow());
156 			return;
157 		}
158 		b++;
159 	}
160 }
161 
delPrompt(Curses * field)162 void CursesDialog::delPrompt(Curses *field)
163 {
164 	vector< pair<CursesLabel *, Curses *> >::iterator
165 		b=prompts.begin(), e=prompts.end();
166 
167 	while (b != e)
168 	{
169 		if (b->second == field)
170 		{
171 			delPrompt(b, b->second->getRow());
172 			return;
173 		}
174 		b++;
175 	}
176 }
177 
delPrompt(vector<pair<CursesLabel *,Curses * >>::iterator p,int row)178 void CursesDialog::delPrompt(vector< pair<CursesLabel *, Curses *> >::iterator
179 			     p, int row)
180 {
181 	prompts.erase(p);
182 
183 	vector< pair<CursesLabel *, Curses *> >::iterator
184 		b=prompts.begin(), e=prompts.end();
185 
186 	while (b != e)
187 	{
188 		if (b->first && b->first->getRow() > row)
189 			b->first->setRow(b->first->getRow()-1);
190 
191 		if (b->second && b->second->getRow() > row)
192 			b->second->setRow(b->second->getRow()-1);
193 		b++;
194 	}
195 }
196 
writeText(const char * text,int row,int col,const CursesAttr & attr)197 bool CursesDialog::writeText(const char *text, int row, int col,
198 			       const CursesAttr &attr) const
199 {
200 	if (draw_flag)
201 		return CursesContainer::writeText(text, row, col, attr);
202 	return false;
203 }
204 
writeText(const std::u32string & text,int row,int col,const Curses::CursesAttr & attr)205 bool CursesDialog::writeText(const std::u32string &text,
206 			     int row, int col,
207 			     const Curses::CursesAttr &attr) const
208 {
209 	if (draw_flag)
210 		CursesContainer::writeText(text, row, col, attr);
211 	return false;
212 }
213 
214 
deleteChild(Curses * child)215 void CursesDialog::deleteChild(Curses *child)
216 {
217 	vector< pair<CursesLabel *, Curses *> >::iterator
218 		b=prompts.begin(), e=prompts.end();
219 
220 	while (b != e)
221 	{
222 		if ( b->first != NULL &&
223 		     ((Curses *)b->first) == child)
224 			b->first=NULL;
225 
226 		if ( b->second != NULL &&
227 		     ((Curses *)b->second) == child)
228 			b->second=NULL;
229 		b++;
230 	}
231 
232 	CursesContainer::deleteChild(child);
233 }
234