$search
00001 # Software License Agreement (BSD License) 00002 # 00003 # Copyright (c) 2009, Willow Garage, Inc. 00004 # All rights reserved. 00005 # 00006 # Redistribution and use in source and binary forms, with or without 00007 # modification, are permitted provided that the following conditions 00008 # are met: 00009 # 00010 # * Redistributions of source code must retain the above copyright 00011 # notice, this list of conditions and the following disclaimer. 00012 # * Redistributions in binary form must reproduce the above 00013 # copyright notice, this list of conditions and the following 00014 # disclaimer in the documentation and/or other materials provided 00015 # with the distribution. 00016 # * Neither the name of Willow Garage, Inc. nor the names of its 00017 # contributors may be used to endorse or promote products derived 00018 # from this software without specific prior written permission. 00019 # 00020 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00021 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00022 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00023 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00024 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00025 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00026 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00027 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00028 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00029 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00030 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00031 # POSSIBILITY OF SUCH DAMAGE. 00032 00033 PKG = 'rxbag' 00034 import roslib; roslib.load_manifest(PKG) 00035 00036 import wx 00037 00038 from util.base_frame import BaseFrame 00039 00040 class TimelinePopupMenu(wx.Menu): 00041 """ 00042 Timeline popup menu. Allows user to manipulate the timeline view, and open new message views. 00043 """ 00044 def __init__(self, timeline): 00045 wx.Menu.__init__(self) 00046 00047 self.parent = timeline 00048 self.timeline = timeline 00049 00050 # Reset Timeline 00051 self.reset_timeline_menu = wx.MenuItem(self, wx.NewId(), 'Reset Timeline') 00052 self.AppendItem(self.reset_timeline_menu) 00053 self.Bind(wx.EVT_MENU, lambda e: self.timeline.reset_timeline(), id=self.reset_timeline_menu.Id) 00054 00055 # Play All Messages 00056 self.play_all_menu = wx.MenuItem(self, wx.NewId(), 'Play All Messages', kind=wx.ITEM_CHECK) 00057 self.AppendItem(self.play_all_menu) 00058 self.play_all_menu.Check(self.timeline.play_all) 00059 self.Bind(wx.EVT_MENU, lambda e: self.timeline.toggle_play_all(), id=self.play_all_menu.Id) 00060 00061 topics = self.timeline.topics 00062 00063 if len(topics) == 0: 00064 return 00065 00066 # --- 00067 self.AppendSeparator() 00068 00069 renderers = self.timeline.get_renderers() 00070 00071 # Thumbnails... 00072 if len(renderers) > 0: 00073 self.thumbnail_menu = wx.Menu() 00074 self.AppendSubMenu(self.thumbnail_menu, 'Thumbnails...', 'View message thumbnails') 00075 00076 # Thumbnails... / Show All 00077 self.show_thumbnails_menu = wx.MenuItem(self.thumbnail_menu, wx.NewId(), 'Show All') 00078 self.thumbnail_menu.AppendItem(self.show_thumbnails_menu) 00079 self.thumbnail_menu.Bind(wx.EVT_MENU, lambda e: self.timeline.set_renderers_active(True), id=self.show_thumbnails_menu.Id) 00080 00081 # Thumbnails... / Hide All 00082 self.hide_thumbnails_menu = wx.MenuItem(self.thumbnail_menu, wx.NewId(), 'Hide All') 00083 self.thumbnail_menu.AppendItem(self.hide_thumbnails_menu) 00084 self.thumbnail_menu.Bind(wx.EVT_MENU, lambda e: self.timeline.set_renderers_active(False), id=self.hide_thumbnails_menu.Id) 00085 00086 # Thumbnails... / --- 00087 self.thumbnail_menu.AppendSeparator() 00088 00089 # Thumbnails... / topic 00090 for topic, renderer in renderers: 00091 renderer_item = self.TimelineRendererMenuItem(self.thumbnail_menu, wx.NewId(), topic.lstrip('/'), topic, renderer, self.timeline) 00092 self.thumbnail_menu.AppendItem(renderer_item) 00093 00094 renderer_item.Check(self.timeline.is_renderer_active(topic)) 00095 00096 # View (by topic)... 00097 self.view_topic_menu = wx.Menu() 00098 self.AppendSubMenu(self.view_topic_menu, 'View (by Topic)...', 'View message detail') 00099 00100 for topic in topics: 00101 datatype = self.timeline.get_datatype(topic) 00102 00103 # View... / topic 00104 topic_menu = wx.Menu() 00105 self.view_topic_menu.AppendSubMenu(topic_menu, topic.lstrip('/'), topic) 00106 00107 viewer_types = self.timeline.get_viewer_types(datatype) 00108 00109 # View... / topic / Viewer 00110 for viewer_type in viewer_types: 00111 topic_menu.AppendItem(self.TopicViewMenuItem(topic_menu, wx.NewId(), viewer_type.name, topic, viewer_type, self.timeline)) 00112 00113 # View (by datatype)... 00114 self.view_datatype_menu = wx.Menu() 00115 self.AppendSubMenu(self.view_datatype_menu, 'View (by Type)...', 'View message detail') 00116 00117 topics_by_datatype = self.timeline.topics_by_datatype 00118 00119 for datatype in sorted(topics_by_datatype): 00120 # View... / datatype 00121 datatype_menu = wx.Menu() 00122 self.view_datatype_menu.AppendSubMenu(datatype_menu, datatype, datatype) 00123 00124 datatype_topics = topics_by_datatype[datatype] 00125 00126 viewer_types = self.timeline.get_viewer_types(datatype) 00127 00128 for topic in [t for t in topics if t in datatype_topics]: # use timeline ordering 00129 topic_menu = wx.Menu() 00130 datatype_menu.AppendSubMenu(topic_menu, topic.lstrip('/'), topic) 00131 00132 # View... / datatype / topic / Viewer 00133 for viewer_type in viewer_types: 00134 topic_menu.AppendItem(self.TopicViewMenuItem(topic_menu, wx.NewId(), viewer_type.name, topic, viewer_type, self.timeline)) 00135 00136 # --- 00137 self.AppendSeparator() 00138 00139 # Publish... 00140 self.publish_menu = wx.Menu() 00141 self.AppendSubMenu(self.publish_menu, 'Publish...', 'Publish Messages') 00142 00143 # Publish... / Publish All 00144 self.publish_menu.AppendItem(self.PublishAllMenuItem(self.publish_menu, wx.NewId(), 'Publish All', True, self.timeline)) 00145 00146 # Publish... / Publish None 00147 self.publish_menu.AppendItem(self.PublishAllMenuItem(self.publish_menu, wx.NewId(), 'Publish None', False, self.timeline)) 00148 00149 # Publish... / --- 00150 self.publish_menu.AppendSeparator() 00151 00152 for topic in topics: 00153 # Publish... / topic 00154 publish_topic_menu = self.PublishTopicMenuItem(self.publish_menu, wx.NewId(), topic, self.timeline) 00155 self.publish_menu.AppendItem(publish_topic_menu) 00156 publish_topic_menu.Check(self.timeline.is_publishing(topic)) 00157 00158 # Copy region to bag... 00159 self.copy_region_menu = wx.MenuItem(self, wx.NewId(), 'Copy Region To Bag...') 00160 self.AppendItem(self.copy_region_menu) 00161 self.Bind(wx.EVT_MENU, lambda e: self.timeline.copy_region_to_bag(), id=self.copy_region_menu.Id) 00162 if self.timeline.selected_left is None or self.timeline.selected_right is None: 00163 self.copy_region_menu.Enable(False) 00164 00165 class PlayAllMenuItem(wx.MenuItem): 00166 def __init__(self, parent, id, label, timeline): 00167 wx.MenuItem.__init__(self, parent, id, label, kind=wx.ITEM_CHECK) 00168 00169 self.timeline = timeline 00170 00171 parent.Bind(wx.EVT_MENU, self.on_menu, id=self.Id) 00172 00173 def on_menu(self, event): 00174 self.timeline.play_all = not self.timeline.play_all 00175 00176 class TimelineRendererMenuItem(wx.MenuItem): 00177 def __init__(self, parent, id, label, topic, renderer, timeline): 00178 wx.MenuItem.__init__(self, parent, id, label, kind=wx.ITEM_CHECK) 00179 00180 self.topic = topic 00181 self.renderer = renderer 00182 self.timeline = timeline 00183 00184 parent.Bind(wx.EVT_MENU, self.on_menu, id=self.Id) 00185 00186 def on_menu(self, event): 00187 self.timeline.set_renderer_active(self.topic, not self.timeline.is_renderer_active(self.topic)) 00188 00189 class TopicViewMenuItem(wx.MenuItem): 00190 def __init__(self, parent, id, label, topic, viewer_type, timeline): 00191 wx.MenuItem.__init__(self, parent, id, label) 00192 00193 self.topic = topic 00194 self.viewer_type = viewer_type 00195 self.timeline = timeline 00196 00197 parent.Bind(wx.EVT_MENU, self.on_menu, id=self.Id) 00198 00199 def on_menu(self, event): 00200 frame = BaseFrame(None, 'rxbag', self.topic, title='rxbag - %s [%s]' % (self.topic.lstrip('/'), self.viewer_type.name), pos=(4, 4), size=(640, 480)) 00201 view = self.viewer_type(self.timeline, frame) 00202 self.timeline.add_view(self.topic, view) 00203 frame.Show() 00204 00205 class PublishTopicMenuItem(wx.MenuItem): 00206 def __init__(self, parent, id, topic, timeline): 00207 wx.MenuItem.__init__(self, parent, id, topic.lstrip('/'), kind=wx.ITEM_CHECK) 00208 00209 self.topic = topic 00210 self.timeline = timeline 00211 00212 parent.Bind(wx.EVT_MENU, self.on_menu, id=self.Id) 00213 00214 def on_menu(self, event): 00215 if self.timeline.is_publishing(self.topic): 00216 self.timeline.stop_publishing(self.topic) 00217 else: 00218 self.timeline.start_publishing(self.topic) 00219 00220 class PublishAllMenuItem(wx.MenuItem): 00221 def __init__(self, parent, id, label, start, timeline): 00222 wx.MenuItem.__init__(self, parent, id, label) 00223 00224 self.timeline = timeline 00225 self.start = start 00226 00227 parent.Bind(wx.EVT_MENU, self.on_menu, id=self.Id) 00228 00229 def on_menu(self, event): 00230 if self.start: 00231 for topic in self.timeline.topics: 00232 if not self.timeline.start_publishing(topic): 00233 break 00234 else: 00235 for topic in self.timeline.topics: 00236 self.timeline.stop_publishing(topic)