All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
nodemap_edit.cc
Go to the documentation of this file.
1 /*
2  * This file is part of the rc_genicam_api package.
3  *
4  * Copyright (c) 2023 Roboception GmbH
5  * All rights reserved
6  *
7  * Author: Heiko Hirschmueller
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * 3. Neither the name of the copyright holder nor the names of its contributors
20  * may be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 #include "nodemap_edit.h"
37 
38 #ifdef INCLUDE_CURSES
39 
40 #include "nodemap_out.h"
41 
42 #include <ncurses.h>
43 #include <sstream>
44 #include <vector>
45 #include <iomanip>
46 
47 namespace rcg
48 {
49 
50 namespace
51 {
52 
53 void mvaddstr_eol(int row, int col, const char *str, bool reverse=false)
54 {
55  int cols=getmaxx(stdscr);
56 
57  if (col < cols)
58  {
59  int n=strlen(str);
60 
61  if (col+n > cols)
62  {
63  n=cols-col;
64  }
65 
66  if (reverse) attron(WA_REVERSE);
67  mvaddnstr(row, col, str, n);
68  if (reverse) attroff(WA_REVERSE);
69  }
70 }
71 
72 class NodeParam
73 {
74  private:
75 
76  int level;
77  int value_column;
78  GenApi::INode *node;
79 
80  public:
81 
82  NodeParam(int _level, GenApi::INode *_node)
83  {
84  level=_level;
85  node=_node;
86  }
87 
88  int getMinValueColum();
89  void setValueColumn(int column);
90  int getValueColumn();
91 
92  std::string getValue(bool add_unit_range);
93  std::string getAllowedCharacters();
94 
95  void printName(int row);
96  void printValue(int row, bool reverse);
97  void printTooltip(int row, bool reverse);
98 
99  int getOptions(std::vector<std::string> &option);
100 
101  bool isWritable();
102  std::string setValue(const std::string &value);
103 
104  bool isExecutable();
105  std::string execute();
106 };
107 
108 int NodeParam::getMinValueColum()
109 {
110  return 2*level+static_cast<int>(node->GetName().size())+1;
111 }
112 
113 void NodeParam::setValueColumn(int column)
114 {
115  value_column=column;
116 }
117 
118 int NodeParam::getValueColumn()
119 {
120  return value_column;
121 }
122 
123 std::string NodeParam::getValue(bool add_unit_range)
124 {
125  std::ostringstream out;
126 
127  switch (node->GetPrincipalInterfaceType())
128  {
130  {
131  GenApi::IBoolean *p=dynamic_cast<GenApi::IBoolean *>(node);
132 
133  if (GenApi::IsReadable(p))
134  {
135  if (p->GetValue())
136  {
137  out << "True";
138  }
139  else
140  {
141  out << "False";
142  }
143  }
144  }
145  break;
146 
148  {
149  GenApi::IInteger *p=dynamic_cast<GenApi::IInteger *>(node);
150 
151  if (GenApi::IsReadable(p))
152  {
153  out << formatValue(p, p->GetValue());
154 
155  if (add_unit_range)
156  {
157  out << " " << p->GetUnit();
158 
159  if (GenApi::IsWritable(node))
160  {
161  out << " [" << formatValue(p, p->GetMin()) << ", " << formatValue(p, p->GetMax()) <<
162  "]";
163  }
164  }
165  }
166  }
167  break;
168 
170  {
171  GenApi::IRegister *p=dynamic_cast<GenApi::IRegister *>(node);
172 
173  if (GenApi::IsReadable(p))
174  {
175  int len=static_cast<int>(p->GetLength());
176 
177  len=std::min(len, (getmaxx(stdscr)-value_column)/2-1);
178  len=std::min(len, 128);
179 
180  uint8_t buffer[128];
181  p->Get(buffer, len);
182 
183  out << std::hex;
184  for (int i=0; i<len && i<len; i++)
185  {
186  out << std::setfill('0') << std::setw(2) << static_cast<int>(buffer[i]);
187  }
188  }
189  }
190  break;
191 
192  case GenApi::intfIFloat:
193  {
194  GenApi::IFloat *p=dynamic_cast<GenApi::IFloat *>(node);
195 
196  if (GenApi::IsReadable(p))
197  {
198  out << p->GetValue();
199 
200  if (add_unit_range)
201  {
202  out << " " << p->GetUnit();
203 
204  if (GenApi::IsWritable(node))
205  {
206  out << " [" << p->GetMin() << ", " << p->GetMax() << "]";
207  }
208  }
209  }
210  }
211  break;
212 
213  case GenApi::intfIString:
214  {
215  GenApi::IString *p=dynamic_cast<GenApi::IString *>(node);
216 
217  if (GenApi::IsReadable(p))
218  {
219  out << p->GetValue();
220  }
221  }
222  break;
223 
225  {
226  GenApi::IEnumeration *p=dynamic_cast<GenApi::IEnumeration *>(node);
227 
228  if (p)
229  {
230  if (GenApi::IsReadable(p->GetAccessMode()) && p->GetCurrentEntry() != 0)
231  {
232  out << p->GetCurrentEntry()->GetSymbolic();
233  }
234  }
235  }
236  break;
237 
239  out << "(execute)" << std::endl;
240  break;
241 
242  default:
243  break;
244  }
245 
246  return out.str();
247 }
248 
249 std::string NodeParam::getAllowedCharacters()
250 {
251  std::string ret;
252 
253  switch (node->GetPrincipalInterfaceType())
254  {
256  ret.push_back('0');
257  ret.push_back('1');
258  break;
259 
260  case GenApi::intfIFloat:
261  ret.push_back('.');
262  ret.push_back('e');
263  // and same as integer
264 
266  {
267  ret.push_back('-');
268  ret.push_back('0');
269  ret.push_back('1');
270  ret.push_back('2');
271  ret.push_back('3');
272  ret.push_back('4');
273  ret.push_back('5');
274  ret.push_back('6');
275  ret.push_back('7');
276  ret.push_back('8');
277  ret.push_back('9');
278 
279  GenApi::IInteger *p=dynamic_cast<GenApi::IInteger *>(node);
280  if (p)
281  {
282  switch (p->GetRepresentation())
283  {
284  case GenApi::IPV4Address:
285  ret.push_back('.');
286  break;
287 
288  case GenApi::MACAddress:
289  ret.push_back(':');
290  // and same as hex number
291 
292  case GenApi::HexNumber:
293  ret.push_back('a');
294  ret.push_back('b');
295  ret.push_back('c');
296  ret.push_back('d');
297  ret.push_back('e');
298  ret.push_back('f');
299  break;
300 
301  default:
302  break;
303  }
304  }
305  }
306  break;
307 
309  ret.push_back('0');
310  ret.push_back('1');
311  ret.push_back('2');
312  ret.push_back('3');
313  ret.push_back('4');
314  ret.push_back('5');
315  ret.push_back('6');
316  ret.push_back('7');
317  ret.push_back('8');
318  ret.push_back('9');
319  ret.push_back('a');
320  ret.push_back('b');
321  ret.push_back('c');
322  ret.push_back('d');
323  ret.push_back('e');
324  ret.push_back('f');
325  break;
326 
327  case GenApi::intfIString:
329  // empty set means all printable characters
330  break;
331 
332  default:
333  break;
334  }
335 
336  return ret;
337 }
338 
339 void NodeParam::printName(int row)
340 {
341  mvaddstr_eol(row, 2*level, node->GetName().c_str());
342 }
343 
344 void NodeParam::printValue(int row, bool reverse)
345 {
346  std::string value=getValue(true);
347 
348  if (value.size() > 0)
349  {
350  mvaddstr_eol(row, value_column, value.c_str(), reverse);
351  }
352 }
353 
354 void NodeParam::printTooltip(int row, bool reverse)
355 {
356  mvaddstr_eol(row, 0, node->GetToolTip().c_str(), reverse);
357 }
358 
359 int NodeParam::getOptions(std::vector<std::string> &option)
360 {
361  int ret=0;
362 
363  switch (node->GetPrincipalInterfaceType())
364  {
366  {
367  GenApi::IBoolean *p=dynamic_cast<GenApi::IBoolean *>(node);
368 
369  if (GenApi::IsReadable(p))
370  {
371  option.push_back(std::string("False"));
372  option.push_back(std::string("True"));
373 
374  if (p->GetValue())
375  {
376  ret=1;
377  }
378  }
379  }
380  break;
381 
383  {
384  GenApi::IEnumeration *p=dynamic_cast<GenApi::IEnumeration *>(node);
385 
386  if (p && GenApi::IsReadable(p))
387  {
388  std::string value;
389  if (p->GetCurrentEntry() != 0)
390  {
391  value=p->GetCurrentEntry()->GetSymbolic().c_str();
392  }
393 
395  p->GetSymbolics(list);
396 
397  for (size_t i=0; i<list.size(); i++)
398  {
399  std::string opt=list[i].c_str();
400  option.push_back(opt);
401 
402  if (opt == value)
403  {
404  ret=i;
405  }
406  }
407  }
408  }
409  break;
410 
411  default:
412  break;
413  }
414 
415  return ret;
416 }
417 
418 bool NodeParam::isWritable()
419 {
420  return GenApi::IsWritable(node);
421 }
422 
423 std::string NodeParam::setValue(const std::string &value)
424 {
425  std::string ret;
426 
427  try
428  {
429  if (GenApi::IsWritable(node))
430  {
431  switch (node->GetPrincipalInterfaceType())
432  {
434  {
435  GenApi::IBoolean *p=dynamic_cast<GenApi::IBoolean *>(node);
436 
437  std::string v=std::string(value);
438  if (v == "true" || v == "True" || v == "TRUE")
439  {
440  p->SetValue(1);
441  }
442  else if (v == "false" || v == "False" || v == "FALSE")
443  {
444  p->SetValue(0);
445  }
446  else
447  {
448  p->SetValue(static_cast<bool>(std::stoi(v)));
449  }
450  }
451  break;
452 
454  {
455  GenApi::IInteger *p=dynamic_cast<GenApi::IInteger *>(node);
456 
457  switch (p->GetRepresentation())
458  {
459  case GenApi::HexNumber:
460  p->SetValue(std::stoll(std::string(value), 0, 16));
461  break;
462 
463  case GenApi::IPV4Address:
464  {
465  int64_t ip=0;
466 
467  std::stringstream in(value);
468  std::string elem;
469 
470  for (int i=0; i<4; i++)
471  {
472  getline(in, elem, '.');
473  ip=(ip<<8)|(stoi(elem)&0xff);
474  }
475 
476  p->SetValue(ip);
477  }
478  break;
479 
480  case GenApi::MACAddress:
481  {
482  int64_t mac=0;
483 
484  std::stringstream in(value);
485  std::string elem;
486 
487  for (int i=0; i<4; i++)
488  {
489  getline(in, elem, ':');
490  mac=(mac<<8)|(stoi(elem, 0, 16)&0xff);
491  }
492 
493  p->SetValue(mac);
494  }
495  break;
496 
497  default:
498  p->SetValue(std::stoll(std::string(value)));
499  break;
500  }
501  }
502  break;
503 
505  {
506  GenApi::IRegister *p=dynamic_cast<GenApi::IRegister *>(node);
507 
508  std::vector<uint8_t> buffer;
509  for (size_t i=0; i<value.size()-1; i+=2)
510  {
511  buffer.push_back(stoi(value.substr(i, 2), 0, 16));
512  }
513 
514  p->Set(buffer.data(), buffer.size());
515  }
516  break;
517 
518  case GenApi::intfIFloat:
519  {
520  GenApi::IFloat *p=dynamic_cast<GenApi::IFloat *>(node);
521  p->SetValue(std::stof(std::string(value)));
522  }
523  break;
524 
526  {
527  GenApi::IEnumeration *p=dynamic_cast<GenApi::IEnumeration *>(node);
528  GenApi::IEnumEntry *entry=0;
529 
530  try
531  {
532  entry=p->GetEntryByName(value.c_str());
533  }
535  { }
536 
537  if (entry != 0)
538  {
539  p->SetIntValue(entry->GetValue());
540  }
541  }
542  break;
543 
544  case GenApi::intfIString:
545  {
546  GenApi::IString *p=dynamic_cast<GenApi::IString *>(node);
547  p->SetValue(value.c_str());
548  }
549  break;
550 
551  default:
552  break;
553  }
554  }
555  else
556  {
557  ret="Internal error: Node is not writable";
558  }
559  }
560  catch (const GENICAM_NAMESPACE::GenericException &ex)
561  {
562  ret=std::string("Error: ")+ex.what();
563  }
564  catch (...)
565  {
566  ret="Error: Unknown exception";
567  }
568 
569  return ret;
570 }
571 
572 bool NodeParam::isExecutable()
573 {
574  return (node->GetPrincipalInterfaceType() == GenApi::intfICommand);
575 }
576 
577 std::string NodeParam::execute()
578 {
579  std::string ret;
580 
581  try
582  {
583  if (GenApi::IsWritable(node))
584  {
585  GenApi::ICommand *val=dynamic_cast<GenApi::ICommand *>(node);
586 
587  if (val != 0)
588  {
589  val->Execute();
590  }
591  else
592  {
593  ret="Internal error: Feature not a command";
594  }
595  }
596  else
597  {
598  ret="Internal error: Node is not writable";
599  }
600  }
601  catch (const GENICAM_NAMESPACE::GenericException &ex)
602  {
603  ret=std::string("Error: ")+ex.what();
604  }
605  catch (...)
606  {
607  ret="Error: Unknown exception";
608  }
609 
610  return ret;
611 }
612 
613 /*
614  Adding the given node and all child nodes recursively to the given list.
615 */
616 
617 void addNodeToList(std::vector<NodeParam> &list, GenApi::INode *node, int level)
618 {
619  if (node->GetAccessMode() != GenApi::NI)
620  {
621  list.push_back(NodeParam(level, node));
622 
623  if (node->GetPrincipalInterfaceType() == GenApi::intfICategory)
624  {
625  GenApi::ICategory *root=dynamic_cast<GenApi::ICategory *>(node);
626 
627  if (root != 0)
628  {
629  GenApi::FeatureList_t feature;
630  root->GetFeatures(feature);
631 
632  level++;
633  for (size_t i=0; i<feature.size(); i++)
634  {
635  addNodeToList(list, feature[i]->GetNode(), level);
636  }
637  }
638  }
639  }
640 }
641 
642 /*
643  Redraw one line.
644 */
645 
646 void redraw_line(int row, NodeParam &node_param, bool focus, bool clear_line=false)
647 {
648  if (clear_line)
649  {
650  move(row, 0);
651  clrtoeol();
652  }
653 
654  attr_t attrs=0;
655  if (node_param.isWritable()) attrs|=A_BOLD;
656  if (focus) attrs|=WA_REVERSE;
657 
658  attron(attrs);
659  node_param.printName(row);
660  attroff(attrs);
661 
662  node_param.printValue(row, false);
663 }
664 
665 /*
666  Clear and redraw everything, starting with the given top row, which may be
667  changed such that the focus row is always visible.
668 */
669 
670 void redraw(std::vector<NodeParam> &list, int &top_row, int focus_row, const char *message=0)
671 {
672  int rows=getmaxy(stdscr);
673 
674  erase();
675 
676  if (rows > 1)
677  {
678  rows--; // last row is used for showing tool tips and errors
679 
680  // focus row must always be visible
681 
682  if (focus_row < top_row) top_row=focus_row;
683  if (focus_row > top_row+rows-1) top_row=focus_row-rows+1;
684 
685  // print all visible rows
686 
687  for (int i=0; i<rows; i++)
688  {
689  if (top_row+i < static_cast<int>(list.size()))
690  {
691  redraw_line(i, list[top_row+i], focus_row == top_row+i);
692  }
693  }
694 
695  if (message && *message != '\0')
696  {
697  mvaddstr_eol(rows, 0, message, true);
698  }
699  else
700  {
701  list[focus_row].printTooltip(rows, true);
702  }
703  }
704 }
705 
706 /*
707  Editing loop for executing a command node.
708 */
709 
710 std::string editNodeExecute(std::vector<NodeParam> &list, int &top_row, int focus_row)
711 {
712  std::string ret;
713 
714  bool edit=true;
715  while (edit)
716  {
717  redraw_line(focus_row-top_row, list[focus_row], false, false);
718 
719  list[focus_row].printValue(focus_row-top_row, true);
720 
721  int c=getch();
722 
723  switch (c)
724  {
725  case KEY_RESIZE:
726  redraw(list, top_row, focus_row);
727  break;
728 
729  case KEY_ENTER:
730  case '\n':
731  case '\r':
732  ret=list[focus_row].execute();
733  if (ret.size() == 0)
734  {
735  ret="Command executed!";
736  }
737  edit=false;
738  break;
739 
740  case 27:
741  case 'q':
742  case KEY_LEFT:
743  edit=false;
744  break;
745 
746  default:
747  break;
748  }
749  }
750 
751  return ret;
752 }
753 
754 /*
755  Editing loop for cycling through options.
756 */
757 
758 std::string editNodeOption(std::vector<NodeParam> &list, int &top_row, int focus_row,
759  const std::vector<std::string> &option, int current)
760 {
761  std::string ret;
762 
763  redraw_line(focus_row-top_row, list[focus_row], false, false);
764 
765  bool edit=true;
766  while (edit)
767  {
768  move(focus_row-top_row, list[focus_row].getValueColumn());
769  clrtoeol();
770 
771  mvaddstr_eol(focus_row-top_row, list[focus_row].getValueColumn(), option[current].c_str(), true);
772 
773  int c=getch();
774 
775  switch (c)
776  {
777  case KEY_RESIZE:
778  redraw(list, top_row, focus_row);
779  redraw_line(focus_row-top_row, list[focus_row], false, false);
780  break;
781 
782  case KEY_UP:
783  if (current > 0)
784  {
785  current--;
786  }
787  break;
788 
789  case KEY_DOWN:
790  if (current+1 < static_cast<int>(option.size()))
791  {
792  current++;
793  }
794  break;
795 
796  case KEY_ENTER:
797  case '\n':
798  case '\r':
799  ret=list[focus_row].setValue(option[current]);
800  edit=false;
801  break;
802 
803  case 27:
804  case 'q':
805  case KEY_LEFT:
806  edit=false;
807  break;
808 
809  default:
810  break;
811  }
812  }
813 
814  return ret;
815 }
816 
817 /*
818  Editing loop for entering a value as string.
819 */
820 
821 std::string editNodeString(std::vector<NodeParam> &list, int &top_row, int focus_row)
822 {
823  std::string allowed=list[focus_row].getAllowedCharacters();
824  std::string value=list[focus_row].getValue(false);
825  std::string message="Current value: "+list[focus_row].getValue(true);
826  std::string ret;
827 
828  // area for editing
829 
830  int row=focus_row-top_row;
831  int cpos=static_cast<int>(value.size());
832  int col0=list[focus_row].getValueColumn();
833  int cn=getmaxx(stdscr)-col0;
834 
835  // unfocus
836 
837  redraw_line(row, list[focus_row], false, false);
838 
839  // show current value instead of tooltip
840 
841  move(getmaxy(stdscr)-1, 0);
842  clrtoeol();
843 
844  mvaddstr_eol(getmaxy(stdscr)-1, 0, message.c_str(), true);
845 
846  // editing loop
847 
848  curs_set(1);
849 
850  bool edit=true;
851  while (edit)
852  {
853  // redraw current value
854 
855  move(row, col0);
856  clrtoeol();
857 
858  mvaddstr_eol(row, col0, value.c_str(), true);
859  move(row, col0+cpos);
860 
861  // wait for next character
862 
863  int c=getch();
864 
865  switch (c)
866  {
867  case KEY_RESIZE:
868  redraw(list, top_row, focus_row, message.c_str());
869  redraw_line(row, list[focus_row], false, false);
870  break;
871 
872  case KEY_LEFT:
873  if (cpos > 0)
874  {
875  cpos--;
876  }
877  break;
878 
879  case KEY_RIGHT:
880  if (cpos < static_cast<int>(value.size()) && cpos+1 < cn)
881  {
882  cpos++;
883  }
884  break;
885 
886  case KEY_BACKSPACE:
887  if (cpos > 0)
888  {
889  cpos--;
890  value.erase(cpos, 1);
891  }
892  break;
893 
894  case KEY_DC:
895  if (cpos < static_cast<int>(value.size()))
896  {
897  value.erase(cpos, 1);
898  }
899  break;
900 
901  case KEY_ENTER:
902  case '\n':
903  case '\r':
904  ret=list[focus_row].setValue(value);
905  edit=false;
906  break;
907 
908  case 27:
909  edit=false;
910  break;
911 
912  default:
913  // allowed to increase value by one character?
914 
915  if (static_cast<int>(value.size()) < cn)
916  {
917  // is it a printable character?
918 
919  char cc=static_cast<char>(c);
920  if (c < 256 && std::isprint(cc))
921  {
922  if (allowed.size() == 0 || allowed.find(cc) != std::string::npos)
923  {
924  value.insert(cpos, &cc, 1);
925  cpos++;
926  }
927  else if (cc == 'q')
928  {
929  edit=false;
930  }
931  }
932  }
933  break;
934  }
935  }
936 
937  curs_set(0);
938 
939  return ret;
940 }
941 
942 }
943 
944 bool editNodemap(const std::shared_ptr<GenApi::CNodeMapRef> &nodemap, const char root[])
945 {
946  // get list of all nodes
947 
948  std::vector<NodeParam> list;
949 
950  {
951  GenApi::INode *node=nodemap->_GetNode(root);
952 
953  if (node)
954  {
955  addNodeToList(list, node, 0);
956  }
957  else
958  {
959  return false;
960  }
961 
962  if (list.size() > 0 && std::string(root) == "Root")
963  {
964  list.erase(list.begin());
965  }
966  }
967 
968  // determine column at which to print values
969 
970  {
971  int value_column=0;
972 
973  for (size_t i=0; i<list.size(); i++)
974  {
975  value_column=std::max(value_column, list[i].getMinValueColum());
976  }
977 
978  for (size_t i=0; i<list.size(); i++)
979  {
980  list[i].setValueColumn(value_column);
981  }
982  }
983 
984  // initializing curses
985 
986  int top_row=0;
987  int focus_row=0;
988 
989  initscr();
990 
991  try
992  {
993  curs_set(0);
994  keypad(stdscr, TRUE);
995  cbreak();
996  noecho();
997  nonl();
998 
999  redraw(list, top_row, focus_row);
1000 
1001  // enter navigation and editing loop
1002 
1003  bool run=true;
1004  while (run)
1005  {
1006  move(0, 0);
1007  int c=getch();
1008 
1009  switch (c)
1010  {
1011  case KEY_RESIZE:
1012  redraw(list, top_row, focus_row);
1013  break;
1014 
1015  case KEY_PPAGE:
1016  if (focus_row > 0)
1017  {
1018  int rows=getmaxy(stdscr);
1019 
1020  if (rows > 1)
1021  {
1022  rows--;
1023  top_row=std::max(0, top_row-rows);
1024  focus_row=std::max(0, focus_row-rows);
1025  }
1026 
1027  redraw(list, top_row, focus_row);
1028  }
1029  break;
1030 
1031  case KEY_NPAGE:
1032  if (focus_row+1 < static_cast<int>(list.size()))
1033  {
1034  int rows=getmaxy(stdscr);
1035 
1036  if (rows > 1)
1037  {
1038  rows--;
1039  top_row=std::min(top_row+rows, std::max(0, static_cast<int>(list.size())-rows));
1040  focus_row=std::min(focus_row+rows, static_cast<int>(list.size())-1);
1041  }
1042 
1043  redraw(list, top_row, focus_row);
1044  }
1045  break;
1046 
1047  case KEY_UP:
1048  if (focus_row > 0)
1049  {
1050  focus_row--;
1051  redraw(list, top_row, focus_row);
1052  }
1053  break;
1054 
1055  case KEY_DOWN:
1056  if (focus_row+1 < static_cast<int>(list.size()))
1057  {
1058  focus_row++;
1059  redraw(list, top_row, focus_row);
1060  }
1061  break;
1062 
1063  case KEY_RIGHT:
1064  case KEY_ENTER:
1065  case '\n':
1066  case '\r':
1067  if (list[focus_row].isWritable())
1068  {
1069  // edit value
1070 
1071  std::string message;
1072 
1073  if (list[focus_row].isExecutable())
1074  {
1075  message=editNodeExecute(list, top_row, focus_row);
1076  }
1077  else
1078  {
1079  std::vector<std::string> option;
1080  int current=list[focus_row].getOptions(option);
1081 
1082  if (option.size() > 0)
1083  {
1084  message=editNodeOption(list, top_row, focus_row, option, current);
1085  }
1086  else
1087  {
1088  message=editNodeString(list, top_row, focus_row);
1089  }
1090  }
1091 
1092  // redraw and show message
1093 
1094  redraw(list, top_row, focus_row, message.c_str());
1095  }
1096  break;
1097 
1098  case 27:
1099  case 'q':
1100  run=false;
1101  break;
1102 
1103  default:
1104  break;
1105  }
1106  }
1107 
1108  endwin();
1109  }
1110  catch (...)
1111  {
1112  endwin();
1113  throw;
1114  }
1115 
1116  return true;
1117 }
1118 
1119 }
1120 
1121 #else
1122 
1123 namespace rcg
1124 {
1125 
1126 bool editNodemap(const std::shared_ptr<GenApi::CNodeMapRef> &nodemap, const char root[])
1127 {
1128  std::cerr << "Editing of nodemap is not implemented! Recompile with ncurses." << std::endl;
1129  return false;
1130 }
1131 
1132 }
1133 
1134 #endif
GENAPI_NAMESPACE::IInteger
GENICAM_INTERFACE IInteger
Interface for integer properties.
Definition: IFloat.h:114
GENAPI_NAMESPACE::intfIString
@ intfIString
IString interface.
Definition: Types.h:196
GENAPI_NAMESPACE::intfIBoolean
@ intfIBoolean
IBoolean interface.
Definition: Types.h:193
GENAPI_NAMESPACE::intfIRegister
@ intfIRegister
IRegister interface.
Definition: Types.h:197
GENAPI_NAMESPACE::intfIInteger
@ intfIInteger
IInteger interface.
Definition: Types.h:192
GENAPI_NAMESPACE::IsWritable
bool IsWritable(EAccessMode AccessMode)
Tests if writable.
Definition: INode.h:196
GENAPI_NAMESPACE::IBoolean
GENICAM_INTERFACE GENAPI_DECL_ABSTRACT IBoolean
Interface for Boolean properties.
Definition: IBoolean.h:61
nodemap_edit.h
rcg
Definition: buffer.cc:47
GENAPI_NAMESPACE::HexNumber
@ HexNumber
Hex number in an edit control.
Definition: Types.h:94
GENAPI_NAMESPACE::NI
@ NI
Not implemented.
Definition: Types.h:56
GENAPI_NAMESPACE::IPV4Address
@ IPV4Address
IP-Address.
Definition: Types.h:95
GENAPI_NAMESPACE::IRegister
GENICAM_INTERFACE GENAPI_DECL_ABSTRACT IRegister
Interface for registers.
Definition: IRegister.h:61
GENAPI_NAMESPACE::intfIFloat
@ intfIFloat
IFloat interface.
Definition: Types.h:195
GENAPI_NAMESPACE::ICommand
GENICAM_INTERFACE GENAPI_DECL_ABSTRACT ICommand
Interface for command like properties.
Definition: ICommand.h:59
GENAPI_NAMESPACE::intfIEnumeration
@ intfIEnumeration
IEnumeration interface.
Definition: Types.h:199
GENICAM_NAMESPACE::getline
std::istream & getline(std::istream &is, GENICAM_NAMESPACE::gcstring &str)
STL getline.
Definition: GCString.h:194
GENICAM_NAMESPACE::GenericException::what
virtual const char * what() const
Get error description (overwrite from std:exception)
GENAPI_NAMESPACE::GetNode
virtual INode * GetNode(const GENICAM_NAMESPACE::gcstring &Name) const =0
Retrieves the node from the central map by Name.
GENAPI_NAMESPACE::IEnumeration
GENICAM_INTERFACE GENAPI_DECL_ABSTRACT IEnumeration
Interface for enumeration properties.
Definition: IEnumeration.h:60
GENAPI_NAMESPACE::IsReadable
bool IsReadable(EAccessMode AccessMode)
Tests if readable.
Definition: INode.h:178
GENAPI_NAMESPACE::IFloat
GENICAM_INTERFACE GENAPI_DECL_ABSTRACT IFloat
Interface for float properties.
Definition: IFloat.h:60
GENAPI_NAMESPACE::INode
GENICAM_INTERFACE INode
Interface common to all nodes.
Definition: ICategory.h:51
GENICAM_NAMESPACE::GenericException
GenICam's exception class.
Definition: GCException.h:63
GENAPI_NAMESPACE::intfICommand
@ intfICommand
ICommand interface.
Definition: Types.h:194
std::ostringstream::str
std::string str()
GENAPI_NAMESPACE::intfICategory
@ intfICategory
ICategory interface.
Definition: Types.h:198
GENAPI_NAMESPACE::IString
GENICAM_INTERFACE GENAPI_DECL_ABSTRACT IString
Interface for string properties.
Definition: IString.h:61
rcg::formatValue
std::string formatValue(GenApi::IInteger *node, int64_t value)
Takes an integer value and formats it according to the specification in the node.
Definition: nodemap_out.cc:92
int64_t
__int64 int64_t
Definition: config-win32.h:21
rcg::editNodemap
bool editNodemap(const std::shared_ptr< GenApi::CNodeMapRef > &nodemap, const char root[])
Shows nodemap in a curses gui in the terminal and allows editing of parameters.
Definition: nodemap_edit.cc:1126
std::ostringstream
Definition: Portability.hh:42
nodemap_out.h
GENAPI_NAMESPACE::ICategory
GENICAM_INTERFACE GENAPI_DECL_ABSTRACT ICategory
Gives access to a category node.
Definition: ICategory.h:66
GENAPI_NAMESPACE::MACAddress
@ MACAddress
MAC-Address.
Definition: Types.h:96
GENAPI_NAMESPACE::StringList_t
GENICAM_NAMESPACE::gcstring_vector StringList_t
A list of strings.
Definition: Types.h:149
GENAPI_NAMESPACE::IEnumEntry
GENICAM_INTERFACE GENAPI_DECL_ABSTRACT IEnumEntry
Interface of single enum value.
Definition: IEnumEntry.h:60


rc_genicam_api
Author(s): Heiko Hirschmueller
autogenerated on Wed Dec 4 2024 03:10:11