menu_handler.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011, Willow Garage, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Willow Garage, Inc. nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *
29  * Author: David Gossow
30  */
31 
33 
34 #include <boost/bind.hpp>
35 #include <boost/make_shared.hpp>
36 
37 namespace interactive_markers
38 {
39 
41  current_handle_(1)
42 {
43 
44 }
45 
47  const FeedbackCallback &feedback_cb )
48 {
49  EntryHandle handle = doInsert( title, visualization_msgs::MenuEntry::FEEDBACK, "", feedback_cb );
50  top_level_handles_.push_back( handle );
51  return handle;
52 }
53 
55  const uint8_t command_type,
56  const std::string &command )
57 {
58  EntryHandle handle = doInsert( title, command_type, command, FeedbackCallback() );
59  top_level_handles_.push_back( handle );
60  return handle;
61 }
62 
63 
64 MenuHandler::EntryHandle MenuHandler::insert( EntryHandle parent, const std::string &title,
65  const FeedbackCallback &feedback_cb )
66 {
67  boost::unordered_map<EntryHandle, EntryContext>::iterator parent_context =
68  entry_contexts_.find( parent );
69 
70  ROS_ASSERT_MSG ( parent_context != entry_contexts_.end(), "Parent menu entry %u not found.", parent );
71 
72  EntryHandle handle = doInsert( title, visualization_msgs::MenuEntry::FEEDBACK, "", feedback_cb );
73  parent_context->second.sub_entries.push_back( handle );
74  return handle;
75 }
76 
77 
78 MenuHandler::EntryHandle MenuHandler::insert( EntryHandle parent, const std::string &title,
79  const uint8_t command_type,
80  const std::string &command )
81 {
82  boost::unordered_map<EntryHandle, EntryContext>::iterator parent_context =
83  entry_contexts_.find( parent );
84 
85  ROS_ASSERT_MSG ( parent_context != entry_contexts_.end(), "Parent menu entry %u not found.", parent );
86 
87  EntryHandle handle = doInsert( title, command_type, command, FeedbackCallback() );
88  parent_context->second.sub_entries.push_back( handle );
89  return handle;
90 }
91 
92 
93 bool MenuHandler::setVisible( EntryHandle handle, bool visible )
94 {
95  boost::unordered_map<EntryHandle, EntryContext>::iterator context =
96  entry_contexts_.find( handle );
97 
98  if ( context == entry_contexts_.end() )
99  {
100  return false;
101  }
102 
103  context->second.visible = visible;
104  return true;
105 }
106 
107 
109 {
110  boost::unordered_map<EntryHandle, EntryContext>::iterator context =
111  entry_contexts_.find( handle );
112 
113  if ( context == entry_contexts_.end() )
114  {
115  return false;
116  }
117 
118  context->second.check_state = check_state;
119  return true;
120 }
121 
122 
123 bool MenuHandler::getCheckState( EntryHandle handle, CheckState &check_state ) const
124 {
125  boost::unordered_map<EntryHandle, EntryContext>::const_iterator context =
126  entry_contexts_.find( handle );
127 
128  if ( context == entry_contexts_.end() )
129  {
130  check_state = NO_CHECKBOX;
131  return false;
132  }
133 
134  check_state = context->second.check_state;
135  return true;
136 }
137 
138 
139 bool MenuHandler::apply( InteractiveMarkerServer &server, const std::string &marker_name )
140 {
141  visualization_msgs::InteractiveMarker int_marker;
142 
143  if ( !server.get( marker_name, int_marker ) )
144  {
145  // This marker has been deleted on the server, so forget it.
146  managed_markers_.erase( marker_name );
147  return false;
148  }
149 
150  int_marker.menu_entries.clear();
151 
152  pushMenuEntries( top_level_handles_, int_marker.menu_entries, 0 );
153 
154  server.insert( int_marker );
155  server.setCallback( marker_name, boost::bind( &MenuHandler::processFeedback, this, _1 ), visualization_msgs::InteractiveMarkerFeedback::MENU_SELECT );
156  managed_markers_.insert( marker_name );
157  return true;
158 }
159 
160 bool MenuHandler::pushMenuEntries( std::vector<EntryHandle>& handles_in,
161  std::vector<visualization_msgs::MenuEntry>& entries_out,
162  EntryHandle parent_handle )
163 {
164  for ( unsigned t = 0; t < handles_in.size(); t++ )
165  {
166  EntryHandle handle = handles_in[t];
167  boost::unordered_map<EntryHandle, EntryContext>::iterator context_it =
168  entry_contexts_.find( handle );
169 
170  if ( context_it == entry_contexts_.end() )
171  {
172  ROS_ERROR( "Internal error: context handle not found! This is a bug in MenuHandler." );
173  return false;
174  }
175 
176  EntryContext& context = context_it->second;
177 
178  if ( !context.visible )
179  {
180  continue;
181  }
182 
183  entries_out.push_back( makeEntry( context, handle, parent_handle ));
184  if( false == pushMenuEntries( context.sub_entries, entries_out, handle ))
185  {
186  return false;
187  }
188  }
189  return true;
190 }
191 
193 {
194  bool success = true;
195  std::set<std::string>::iterator it = managed_markers_.begin();
196  while ( it != managed_markers_.end() )
197  {
198  // apply() may delete the entry "it" is pointing to, so
199  // pre-compute the next iterator.
200  std::set<std::string>::iterator next_it = it;
201  next_it++;
202  success = apply( server, *it ) && success;
203  it = next_it;
204  }
205  return success;
206 }
207 
209  const uint8_t command_type,
210  const std::string &command,
211  const FeedbackCallback &feedback_cb )
212 {
213  EntryHandle handle = current_handle_;
214  current_handle_++;
215 
216  EntryContext context;
217  context.title = title;
218  context.command = command;
219  context.command_type = command_type;
220  context.visible = true;
221  context.check_state = NO_CHECKBOX;
222  context.feedback_cb = feedback_cb;
223 
224  entry_contexts_[handle] = context;
225  return handle;
226 }
227 
228 visualization_msgs::MenuEntry MenuHandler::makeEntry( EntryContext& context, EntryHandle handle, EntryHandle parent_handle )
229 {
230  visualization_msgs::MenuEntry menu_entry;
231 
232  switch ( context.check_state )
233  {
234  case NO_CHECKBOX:
235  menu_entry.title = context.title;
236  break;
237  case CHECKED:
238  menu_entry.title = "[x] "+context.title;
239  break;
240  case UNCHECKED:
241  menu_entry.title = "[ ] "+context.title;
242  break;
243  }
244 
245  menu_entry.command = context.command;
246  menu_entry.command_type = context.command_type;
247  menu_entry.id = handle;
248  menu_entry.parent_id = parent_handle;
249 
250  return menu_entry;
251 }
252 
253 
254 void MenuHandler::processFeedback( const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback )
255 {
256  boost::unordered_map<EntryHandle, EntryContext>::iterator context =
257  entry_contexts_.find( (EntryHandle) feedback->menu_entry_id );
258 
259  if ( context != entry_contexts_.end() && context->second.feedback_cb )
260  {
261  context->second.feedback_cb( feedback );
262  }
263 }
264 
265 bool MenuHandler::getTitle( EntryHandle handle, std::string &title ) const
266 {
267  boost::unordered_map<EntryHandle, EntryContext>::const_iterator context =
268  entry_contexts_.find( handle );
269 
270  if ( context == entry_contexts_.end() )
271  {
272  return false;
273  }
274 
275  title = context->second.title;
276  return true;
277 }
278 
279 
280 
281 }
EntryHandle doInsert(const std::string &title, const uint8_t command_type, const std::string &command, const FeedbackCallback &feedback_cb)
bool pushMenuEntries(std::vector< EntryHandle > &handles_in, std::vector< visualization_msgs::MenuEntry > &entries_out, EntryHandle parent_handle)
visualization_msgs::MenuEntry makeEntry(EntryContext &context, EntryHandle handle, EntryHandle parent_handle)
bool getCheckState(EntryHandle handle, CheckState &check_state) const
void processFeedback(const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback)
boost::shared_ptr< interactive_markers::InteractiveMarkerServer > server
Definition: bursty_tf.cpp:40
bool apply(InteractiveMarkerServer &server, const std::string &marker_name)
bool getTitle(EntryHandle handle, std::string &title) const
bool setVisible(EntryHandle handle, bool visible)
Specify if an entry should be visible or hidden.
bool setCheckState(EntryHandle handle, CheckState check_state)
Specify if an entry is checked or can&#39;t be checked at all.
#define ROS_ASSERT_MSG(cond,...)
bool get(std::string name, visualization_msgs::InteractiveMarker &int_marker) const
EntryHandle insert(const std::string &title, const FeedbackCallback &feedback_cb)
Insert top-level entry with feedback function.
void insert(const visualization_msgs::InteractiveMarker &int_marker)
bool setCallback(const std::string &name, FeedbackCallback feedback_cb, uint8_t feedback_type=DEFAULT_FEEDBACK_CB)
boost::function< void(const FeedbackConstPtr &) > FeedbackCallback
Definition: menu_handler.h:53
std::set< std::string > managed_markers_
Definition: menu_handler.h:138
bool reApply(InteractiveMarkerServer &server)
Re-apply to all markers that this was applied to previously.
std::vector< EntryHandle > top_level_handles_
Definition: menu_handler.h:132
#define ROS_ERROR(...)
boost::unordered_map< EntryHandle, EntryContext > entry_contexts_
Definition: menu_handler.h:134


interactive_markers
Author(s): David Gossow
autogenerated on Sun Feb 3 2019 03:24:09