PlasCom2  1.0
XPACC Multi-physics simluation application
Menu.H
Go to the documentation of this file.
1 #ifndef __MENU_H__
7 #define __MENU_H__
8 
9 #include "Configuration.H"
10 #include <iomanip>
11 
12 namespace ix {
13 
14  namespace util {
15 
16  typedef std::string::size_type strsize;
17 
18  template<typename ConfigType = util::ConfigurationObject,typename ParamType = util::ConfigParameters>
19  class MenuObject
20  {
21  public:
24  std::string LastSection() const { return(_last_section); };
25  std::string hRule()
26  {
27  std::ostringstream Ostr;
28  strsize menuspace = _menu_width - _external_border.size()*2 - 2;
29  int hsize = _horizontal_rule.size();
30  if(hsize == 0) hsize=1;
31  Ostr << _external_border;
32  for(unsigned int npchar = 0;npchar < (menuspace+2);npchar+=hsize)
33  Ostr << std::setw(hsize) << _horizontal_rule;
34  Ostr << _external_border;
35  return(Ostr.str());
36  };
37  std::string centerString(const std::string &message)
38  {
39  std::ostringstream Ostr;
40  strsize border_size = _external_border.size() + 1;
41  strsize menuspace = _menu_width-(border_size*2);
42  int nspaces = (menuspace-message.size())/2;
43  int spaces = 0;
44  Ostr << _external_border << " ";
45  while(spaces++ < nspaces)
46  Ostr << " ";
47  Ostr << message;
48  // spaces = 0;
49  // while(spaces++ < nspaces)
50  // Ostr << " ";
51  int space_left = _menu_width - (Ostr.str().size() + 2);
52  while(space_left--)
53  Ostr << " ";
54  Ostr << " " << _external_border;
55  return(Ostr.str());
56  };
57  virtual std::string menuString(ConfigType &config,const std::string &section)
58  {
59  _last_section.assign(section);
60  std::ostringstream Ostr;
61 
62  // Calculate some sizes for output formatting
63  strsize border_size = _external_border.size() + 1;
64  strsize vrule_size = _vertical_rule.size() + 2;
65  strsize menuspace = _menu_width-(border_size*2);
66  ParamType &params = config.Section(section);
67  int npp = params.size();
68  int ncol = 1;
69  while((_column_length*ncol) < npp)
70  ncol++;
71  int lines_per_col = (npp + ncol)/ncol;
72  std::vector<int> npercol(ncol,0);
73  std::vector<int>::iterator npci = npercol.begin();
74  while(npci != npercol.end()){
75  *npci = (npp < lines_per_col ? npp : lines_per_col);
76  npp -= *npci++;
77  }
78  int rule_size = vrule_size * (ncol - 1);
79  int button_size = 4; // "xx) "
80  int field_separator_size = _field_separator.size(); // " = "
81  int column_size = (menuspace - rule_size)/ncol;
82  int field_space = column_size - button_size - field_separator_size;
83  unsigned int field_size = field_space/2;
84  int total_size = rule_size + (ncol * (button_size+(2*field_size)+field_separator_size));
85  int xtraspace = (menuspace-total_size);
86  int fieldspace = xtraspace/(ncol*2);
87 
88  // If there is space left over, flow it into the field size and
89  // track the overflow. This is needed to make sure all the
90  // borders line up when printing the menu.
91  if(fieldspace > 0){
92  field_size += fieldspace;
93  xtraspace -= (fieldspace*ncol*2);
94  }
95 
96  // Print the header and the section name to the buffer
97  // followed by a horizontal rule.
98  Ostr << _header << std::endl
99  << centerString(section) << std::endl << hRule() << std::endl
100  << _external_border << " ";
101  // Print the menu lines
102  int line_count = 1;
103  for(line_count = 1; line_count <= npercol[0];line_count++){
104  int extraspace = xtraspace;
105  for(int cc = 0;cc < ncol;cc++){
106  unsigned int param_index = line_count-1;
107  for(int ccount = 0;ccount < cc;ccount++)
108  param_index += npercol[ccount];
109  std::string key;
110  std::string value;
111  if(param_index < params.size()){
112  key = params[param_index].Key();
113  value = params[param_index].Value();
114  if(key.size() > field_size){
115  key = std::string("*") + key.substr(key.size() - field_size + 1);
116  }
117  if(value.size() > field_size){
118  value = std::string("*")+ value.substr(value.size() - field_size + 1);
119  }
120  }
121  if(param_index < params.size())
122  Ostr << std::setw(2) << std::setiosflags(std::ios::left) << param_index+1 << std::setw(2) << ") ";
123  else
124  Ostr << std::setw(4) << "";
125  Ostr << std::setw(field_size) << std::setiosflags(std::ios::left)
126  << (param_index < params.size() ? key : "")
127  << std::setw(3) << (param_index < params.size() ? " = " : "")
128  << std::setw(field_size)
129  << (param_index < params.size() ? value : "") << ((extraspace--) > 0 ? " " : "")
130  << ((cc == (ncol-1)) ? "" : (std::string(std::string(" ") + _vertical_rule + std::string(" "))));
131  }
132  while(extraspace-- > 0)
133  Ostr << " ";
134  Ostr << " " << _external_border << std::endl;
135  if(line_count < npercol[0])
136  Ostr << _external_border << " ";
137  }
138  // Print a horizontal rule between the menu lines and the navigation section
139  Ostr << hRule();
140  return(Ostr.str());
141  };
142 
143  std::string navigationString(ConfigType &config,const std::string &section){
144  std::ostringstream Ostr;
145  int section_index = config.SectionIndex(section);
146  ParamType &params = config.Section(section);
147  strsize border_size = _external_border.size() + 1;
148  strsize vrule_size = _vertical_rule.size() + 2;
149  strsize menuspace = _menu_width-(border_size*2);
150  int npp = params.size();
151  int ncol = 1;
152  while((_column_length*ncol) < npp)
153  ncol++;
154  int lines_per_col = (npp + ncol)/ncol;
155  std::vector<int> npercol(ncol,0);
156  std::vector<int>::iterator npci = npercol.begin();
157  while(npci != npercol.end()){
158  *npci = (npp < lines_per_col ? npp : lines_per_col);
159  npp -= *npci++;
160  }
161  int rule_size = vrule_size * (ncol - 1);
162  int button_size = 4; // default: "xx) "
163  int field_separator_size = _field_separator.size(); // default: " = "
164  int column_size = (menuspace - rule_size)/ncol;
165  int field_space = column_size - button_size - field_separator_size;
166  unsigned int field_size = field_space/2;
167  int total_size = rule_size + (ncol * (button_size+(2*field_size)+field_separator_size));
168  int xtraspace = (menuspace-total_size);
169  int menuitem = params.size()+1;
170  int navsize = button_size + field_size + 1;
171  int nnavperline = menuspace/navsize;
172  xtraspace = menuspace - navsize*nnavperline + 1;
173 
174  std::string topName(config.Name());
175  if(topName.size() > menuspace){
176  topName = std::string("*") + topName.substr(topName.size() - menuspace + 1);
177  }
178 
179  Ostr << centerString("Navigation") << std::endl << hRule() << std::endl;
180  std::ostringstream OnavStr;
181  OnavStr << _external_border << " "
182  << 0 << ")" << std::setiosflags(std::ios::left)
183  << std::setw(topName.size()) << topName;
184  std::string navSectionString(config.NavigationSections()[section_index]);
185  std::istringstream Istr(navSectionString);
186  std::string navString;
187  bool first_on_line = false;
188  xtraspace = _menu_width - (OnavStr.str().size() + _external_border.size()+1);
189  while(Istr >> navString){
190  // Trim the string if it is larger than the max size
191  if(navString.size() > menuspace){
192  navString = std::string("*") + navString.substr(navString.size() - menuspace +1);
193  }
194  if((int)(button_size + navString.size()+3) > xtraspace){
195  while(xtraspace--)
196  OnavStr << " ";
197  OnavStr << " " << _external_border << std::endl;
198  Ostr << OnavStr.str();
199  OnavStr.str("");
200  OnavStr << _external_border << " ";
201  first_on_line = true;
202  }
203  OnavStr << (first_on_line ? "" : " | ") << menuitem++ << ")" << std::setw(std::ios::left)
204  << std::setw(navString.size()) << navString;
205  xtraspace = _menu_width - (OnavStr.str().size()+_external_border.size()+1);
206  }
207  if(xtraspace > 0){
208  xtraspace = _menu_width - (OnavStr.str().size()+_external_border.size()+1);
209  while(xtraspace--)
210  OnavStr << " ";
211  OnavStr << " " << _external_border;
212  }
213  Ostr << OnavStr.str() << std::endl << hRule();
214  return(Ostr.str());
215  };
216  void SetExternalBorder(const std::string &eb){
217  _external_border.assign(eb);
218  };
219  std::string Border() const {
220  return(_external_border);
221  };
222  void SetHeader(const std::string &hdr){
223  _header.assign(hdr);
224  };
225  std::string Header() const {
226  return(_header);
227  };
228  void SetHRule(const std::string &hrule){
229  _horizontal_rule.assign(hrule);
230  };
231  void SetVRule(const std::string &vrule){
232  _vertical_rule.assign(vrule);
233  };
234  void SetFieldSeparator(const std::string &sep){
235  _field_separator.assign(sep);
236  };
237  void SetMenuWidth(unsigned int wid){
238  _menu_width = wid;
239  };
240  void SetColumnLength(unsigned int colen){
241  _column_length = colen;
242  };
243  private:
244  std::string _header;
245  std::string _external_border;
246  std::string _vertical_rule;
247  std::string _horizontal_rule;
248  std::string _field_separator;
249  strsize _menu_width;
251  std::string _last_section;
252  std::string _next_section;
253  std::string _up_section;
254  };
255  };
256 };
257 #endif
258 
259 
260 
void SetHeader(const std::string &hdr)
Definition: Menu.H:222
std::string centerString(const std::string &message)
Definition: Menu.H:37
std::string _external_border
Definition: Menu.H:245
std::string::size_type strsize
Definition: Menu.H:16
void SetExternalBorder(const std::string &eb)
Definition: Menu.H:216
std::string LastSection() const
Definition: Menu.H:24
void SetColumnLength(unsigned int colen)
Definition: Menu.H:240
void SetVRule(const std::string &vrule)
Definition: Menu.H:231
Defines MPI-specific parallel global and program classes.
std::string _next_section
Definition: Menu.H:252
std::string _vertical_rule
Definition: Menu.H:246
void SetMenuWidth(unsigned int wid)
Definition: Menu.H:237
std::string _header
Definition: Menu.H:242
std::string _last_section
Definition: Menu.H:251
void SetFieldSeparator(const std::string &sep)
Definition: Menu.H:234
virtual std::string menuString(ConfigType &config, const std::string &section)
Definition: Menu.H:57
void SetHRule(const std::string &hrule)
Definition: Menu.H:228
std::string hRule()
Definition: Menu.H:25
std::string _field_separator
Definition: Menu.H:248
std::string Border() const
Definition: Menu.H:219
Configuration object interface (for config files, etc).
std::string _horizontal_rule
Definition: Menu.H:247
std::string _up_section
Definition: Menu.H:253
std::string Header() const
Definition: Menu.H:225
Simple key-value pair.
std::string navigationString(ConfigType &config, const std::string &section)
Definition: Menu.H:143
strsize _menu_width
Definition: Menu.H:249