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


rc_genicam_api
Author(s): Heiko Hirschmueller
autogenerated on Sun Jun 18 2023 02:43:55