item.hpp
Go to the documentation of this file.
1 #ifndef RADIAL_MENU_MODEL_ITEM_HPP
2 #define RADIAL_MENU_MODEL_ITEM_HPP
3 
4 #include <cstdint>
5 #include <memory>
6 #include <string>
7 #include <vector>
8 
10 #include <ros/console.h>
11 
12 namespace radial_menu_model {
13 
14 // pointer types
15 
16 class Item;
17 typedef std::shared_ptr< Item > ItemPtr;
18 typedef std::shared_ptr< const Item > ItemConstPtr;
19 
20 // menu item.
21 // state of Item cannot be changed after construction by itemsFromDescription()
22 // because all methods of Item is const.
23 
24 class Item : public std::enable_shared_from_this< Item > {
25 public:
27 
28 protected:
29  Item() {}
30 
31 public:
32  virtual ~Item() {}
33 
34  // propaties
35 
36  std::int32_t itemId() const { return item_id_; }
37 
38  const std::string &name() const { return name_; }
39 
40  std::string path(const char separator = '.') const {
41  const ItemConstPtr p(parent());
42  return p ? (p->path() + separator + name_) : name_;
43  }
44 
46 
47  const std::string &altTxt() const { return alt_txt_; }
48 
49  const std::string &imgURL() const { return img_url_; }
50 
51  // root
52 
53  ItemConstPtr root() const {
54  const ItemConstPtr p(parent());
55  return p ? p->root() : shared_from_this();
56  }
57 
58  // parent
59 
60  ItemConstPtr parent() const { return parent_.lock(); }
61 
62  ItemConstPtr parentLevel() const {
63  const ItemConstPtr p(parent());
64  return p ? p->sibilingLevel() : ItemConstPtr();
65  }
66 
67  // sibilings
68 
69  int numSibilings() const {
70  const ItemConstPtr p(parent());
71  return p ? p->children_.size() : 1;
72  }
73 
74  std::vector< ItemConstPtr > sibilings() const {
75  const ItemConstPtr p(parent());
76  return p ? p->children_ : std::vector< ItemConstPtr >(1, shared_from_this());
77  }
78 
79  ItemConstPtr sibiling(const int sid) const {
80  const ItemConstPtr p(parent());
81  if (p && sid >= 0 && sid < p->children_.size()) {
82  return p->children_[sid];
83  } else if (!p && sid == 0) {
84  return shared_from_this();
85  } else {
86  return ItemConstPtr();
87  }
88  }
89 
90  ItemConstPtr sibilingLevel() const {
91  const ItemConstPtr p(parent());
92  if (p) {
93  for (const ItemConstPtr &s : p->children_) {
94  if (s) {
95  return s;
96  }
97  }
98  }
99  return shared_from_this();
100  }
101 
102  int depth() const {
103  const ItemConstPtr p(parent());
104  return p ? p->depth() + 1 : 0;
105  }
106 
107  // children
108 
109  int numChildren() const { return children_.size(); }
110 
111  const std::vector< ItemConstPtr > &children() const { return children_; }
112 
113  ItemConstPtr child(const int cid) const {
114  return (cid >= 0 && cid < children_.size()) ? children_[cid] : ItemConstPtr();
115  }
116 
117  ItemConstPtr childLevel() const {
118  for (const ItemConstPtr &c : children_) {
119  if (c) {
120  return c;
121  }
122  }
123  return ItemConstPtr();
124  }
125 
126  // factory
127 
128  static std::vector< ItemConstPtr > itemsFromDescription(const std::string &desc) {
129  struct Internal {
130  static bool appendItems(const XmlElement &elm, std::vector< ItemConstPtr > *const items,
131  const ItemPtr &parent_item = ItemPtr(), const int default_row = 0) {
132  // is the element name "item"?
133  if (elm.name() != "item") {
134  ROS_ERROR_STREAM("Item::itemsFromDescription(): Unexpected element '" << elm.name()
135  << "'");
136  return false;
137  }
138 
139  // create an item and append it to the given list
140  const ItemPtr item(new Item());
141  item->item_id_ = items->size();
142  items->push_back(item);
143 
144  // associate the item with the parent
145  if (parent_item) {
146  const int row(elm.attribute("row", default_row));
147  if (row < 0 || row >= parent_item->children_.size()) {
148  ROS_ERROR_STREAM("Item::itemsFromDescription(): '" << row << "' is out of row range");
149  return false;
150  }
151  if (parent_item->children_[row]) {
152  ROS_ERROR_STREAM("Item::itemsFromDescription(): Multiple items in the row '" << row
153  << "'");
154  return false;
155  }
156  parent_item->children_[row] = item;
157  item->parent_ = parent_item;
158  }
159 
160  // load the item name from the attribute
161  if (!elm.getAttribute("name", &item->name_)) {
162  ROS_ERROR("Item::itemsFromDescription(): No attribute 'name'");
163  return false;
164  }
165 
166  // load the display type from the attribute
167  const std::string display(elm.attribute< std::string >("display", "name"));
168  if (display == "name") {
169  item->display_type_ = Item::Name;
170  } else if (display == "alttxt") {
171  item->display_type_ = Item::AltTxt;
172  if (!elm.getAttribute("alttxt", &item->alt_txt_)) {
173  ROS_ERROR("Item::itemsFromDescription(): No attribute 'alttxt'");
174  return false;
175  }
176  } else if (display == "image") {
177  item->display_type_ = Item::Image;
178  if (!elm.getAttribute("imgurl", &item->img_url_)) {
179  ROS_ERROR("Item::itemsFromDescription(): No attribute 'imgurl'");
180  return false;
181  }
182  } else {
183  ROS_ERROR_STREAM("Item::itemsFromDescription(): Unknown display type '" << display
184  << "'");
185  return false;
186  }
187 
188  // allocate child items
189  const int rows(elm.attribute("rows", elm.numChildElements()));
190  if (rows < 0) {
191  ROS_ERROR_STREAM("Item::itemsFromDescription(): Invalid row size '" << rows << "'");
192  return false;
193  }
194  item->children_.resize(rows);
195 
196  // recursively update the given list
197  const std::vector< XmlElementConstPtr > child_elms(elm.childElements());
198  for (std::size_t i = 0; i < child_elms.size(); ++i) {
199  if (!appendItems(*child_elms[i], items, item, i)) {
200  return false;
201  }
202  }
203 
204  return true;
205  }
206  };
207 
208  // parse the given xml description
210  if (!elm) {
211  return std::vector< ItemConstPtr >();
212  }
213 
214  // populate items by parsing the root xml element
215  std::vector< ItemConstPtr > items;
216  if (!Internal::appendItems(*elm, &items)) {
217  return std::vector< ItemConstPtr >();
218  }
219 
220  return items;
221  }
222 
223 protected:
224  typedef std::weak_ptr< const Item > ItemWeakConstPtr;
225 
226  std::int32_t item_id_; // int32_t is the type of ids in State msg
227  std::string name_;
229  std::string alt_txt_, img_url_;
230  ItemWeakConstPtr parent_;
231  std::vector< ItemConstPtr > children_;
232 };
233 } // namespace radial_menu_model
234 
235 #endif
int numSibilings() const
Definition: item.hpp:69
ItemConstPtr sibiling(const int sid) const
Definition: item.hpp:79
std::vector< ItemConstPtr > children_
Definition: item.hpp:231
const std::string & imgURL() const
Definition: item.hpp:49
const std::vector< ItemConstPtr > & children() const
Definition: item.hpp:111
std::shared_ptr< const Item > ItemConstPtr
Definition: item.hpp:18
static XmlElementConstPtr fromString(const std::string &str)
Definition: xml_element.hpp:69
std::vector< ItemConstPtr > sibilings() const
Definition: item.hpp:74
bool getAttribute(const std::string &key, T *const val) const
Definition: xml_element.hpp:40
std::shared_ptr< Item > ItemPtr
Definition: item.hpp:16
ItemConstPtr parent() const
Definition: item.hpp:60
std::int32_t item_id_
Definition: item.hpp:226
DisplayType display_type_
Definition: item.hpp:228
int numChildren() const
Definition: item.hpp:109
ItemConstPtr root() const
Definition: item.hpp:53
ItemConstPtr parentLevel() const
Definition: item.hpp:62
XmlRpcServer s
std::string img_url_
Definition: item.hpp:229
const std::string & name() const
Definition: xml_element.hpp:32
T attribute(const std::string &key, const T &default_val) const
Definition: xml_element.hpp:35
std::size_t numChildElements() const
Definition: xml_element.hpp:49
static std::vector< ItemConstPtr > itemsFromDescription(const std::string &desc)
Definition: item.hpp:128
DisplayType displayType() const
Definition: item.hpp:45
std::int32_t itemId() const
Definition: item.hpp:36
ItemConstPtr child(const int cid) const
Definition: item.hpp:113
std::string path(const char separator='.') const
Definition: item.hpp:40
std::vector< XmlElementConstPtr > childElements() const
Definition: xml_element.hpp:59
ItemWeakConstPtr parent_
Definition: item.hpp:230
ItemConstPtr sibilingLevel() const
Definition: item.hpp:90
int depth() const
Definition: item.hpp:102
#define ROS_ERROR_STREAM(args)
std::weak_ptr< const Item > ItemWeakConstPtr
Definition: item.hpp:224
std::string name_
Definition: item.hpp:227
std::string alt_txt_
Definition: item.hpp:229
const std::string & name() const
Definition: item.hpp:38
const std::string & altTxt() const
Definition: item.hpp:47
#define ROS_ERROR(...)
std::shared_ptr< const XmlElement > XmlElementConstPtr
Definition: xml_element.hpp:20
ItemConstPtr childLevel() const
Definition: item.hpp:117


radial_menu_model
Author(s):
autogenerated on Mon Feb 28 2022 23:22:00