Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/tools/contributed/sumopy/coremodules/scenario/wxgui.py
169689 views
1
# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
2
# Copyright (C) 2016-2025 German Aerospace Center (DLR) and others.
3
# SUMOPy module
4
# Copyright (C) 2012-2021 University of Bologna - DICAM
5
# This program and the accompanying materials are made available under the
6
# terms of the Eclipse Public License 2.0 which is available at
7
# https://www.eclipse.org/legal/epl-2.0/
8
# This Source Code may also be made available under the following Secondary
9
# Licenses when the conditions for such availability set forth in the Eclipse
10
# Public License 2.0 are satisfied: GNU General Public License, version 2
11
# or later which is available at
12
# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
13
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
14
15
# @file wxgui.py
16
# @author Joerg Schweizer
17
# @date 2012
18
19
import os
20
21
import wx
22
import agilepy.lib_base.classman as cm
23
from coremodules.misc import shapeformat
24
25
from agilepy.lib_wx.modulegui import ModuleGui
26
from agilepy.lib_wx.processdialog import ProcessDialog
27
28
import scenario
29
30
31
class WxGui(ModuleGui):
32
"""Contains functions that communicate between the widgets of the main wx gui
33
and the functions of the plugin.
34
"""
35
36
def __init__(self, ident):
37
self._scenario = None
38
self._init_common(ident, priority=1,
39
icondirpath=os.path.join(os.path.dirname(__file__), 'images'))
40
41
def set_module(self, scenario):
42
self._scenario = scenario
43
44
def get_module(self):
45
return self._scenario
46
47
def get_scenario(self):
48
return self._scenario
49
50
def init_widgets(self, mainframe):
51
"""
52
Set mainframe and initialize widgets to various places.
53
"""
54
self._mainframe = mainframe
55
#self._neteditor = mainframe.add_view("Network", Neteditor)
56
57
# mainframe.browse_obj(self._module)
58
self.make_menu()
59
self.make_toolbar()
60
args = mainframe.get_args()
61
del self._scenario
62
self._scenario = None
63
if len(args) == 3:
64
# command line provided rootname and dirpath
65
rootname = args[1]
66
dirpath = args[2]
67
name_scenario = rootname
68
self._scenario = scenario.Scenario(rootname, workdirpath=dirpath,
69
name_scenario=name_scenario,
70
logger=self._mainframe.get_logger())
71
self._scenario.import_xml()
72
73
elif len(args) == 2:
74
filepath = args[1]
75
self._scenario = scenario.load_scenario(filepath, logger=self._mainframe.get_logger())
76
#self._scenario = cm.load_obj(filepath)
77
78
if self._scenario is None:
79
# command line provided nothing
80
rootname = 'myscenario'
81
# None# this means no directory will be created os.path.join(os.path.expanduser("~"),'sumopy','myscenario')
82
dirpath = scenario.DIRPATH_SCENARIO
83
name_scenario = 'My Scenario'
84
self._scenario = scenario.Scenario(rootname, workdirpath=dirpath,
85
name_scenario=name_scenario,
86
logger=self._mainframe.get_logger())
87
88
def refresh_widgets(self):
89
"""
90
Check through mainframe what the state of the application is
91
and reset widgets. For exampe enable/disable widgets
92
dependent on the availability of data.
93
"""
94
self.set_frametitle()
95
# if self._scenario != self._mainframe.get_modulegui('coremodules.scenario').get_module():
96
# del self._scenario
97
# self._scenario = self._mainframe.get_modulegui('coremodules.scenario').get_module()
98
# self._mainframe.set_title(self._scenario.get_ident()+"("+self._scenario.get_name()+")")
99
self._mainframe.browse_obj(self._scenario)
100
101
def set_frametitle(self):
102
self._mainframe.set_title(self._scenario.rootname+" ("+self._scenario.name_scenario+")")
103
104
def make_menu(self):
105
# event section
106
#wx.EVT_BUTTON(self._mainframe, 1003, self.on_close)
107
wx.EVT_CLOSE(self._mainframe, self.on_close)
108
#wx.EVT_IDLE(self._mainframe, self.on_idle)
109
110
# print 'make_menu'
111
menubar = self._mainframe.menubar
112
menubar.append_menu('Scenario')
113
# menubar.append_menu( 'Scenario/import',
114
# bitmap = wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE,wx.ART_MENU),
115
# )
116
117
menubar.append_menu('Scenario/create',
118
bitmap=wx.ArtProvider.GetBitmap(wx.ART_NEW, wx.ART_MENU),
119
)
120
121
menubar.append_item('Scenario/create/new...',
122
self.on_create,
123
info='Create new, empty scenario.',
124
bitmap=wx.ArtProvider.GetBitmap(wx.ART_NEW, wx.ART_MENU),
125
)
126
127
menubar.append_item('Scenario/create/create from xml...',
128
self.on_create_from_xml,
129
info='Create scenario from various sumo xml files.',
130
bitmap=wx.ArtProvider.GetBitmap(wx.ART_NEW, wx.ART_MENU),
131
)
132
133
menubar.append_item('Scenario/open...',
134
self.on_open,
135
info='Open a new scenario from a Python binary file.',
136
bitmap=wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_MENU),
137
)
138
139
menubar.append_item('Scenario/browse',
140
self.on_browse_obj, # common function in modulegui
141
info='View and browse Scenario in object panel.',
142
bitmap=self.get_agileicon('icon_browse_24px.png'), # ,
143
)
144
145
menubar.append_item('Scenario/safe',
146
self.on_save, shortkey='Ctrl+S',
147
info='Save current scenario in a Python binary file.',
148
bitmap=wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE, wx.ART_MENU),
149
)
150
151
menubar.append_item('Scenario/safe as...',
152
self.on_save_as,
153
info='Save as scenario in a Python binary file.',
154
bitmap=wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE_AS, wx.ART_MENU),
155
)
156
157
menubar.append_item('Scenario/quit...',
158
self.on_close,
159
info='Quit Sumopy', shortkey='Ctrl+Q',
160
bitmap=wx.ArtProvider.GetBitmap(wx.ART_QUIT, wx.ART_MENU)
161
)
162
163
def on_close(self, event):
164
# self.Close(True)
165
# pass
166
self.on_exit(event)
167
168
def on_exit(self, event):
169
"""Called when the application is to be finished"""
170
dlg = wx.MessageDialog(self._mainframe,
171
'SUMOPy is about to close.\nDo you want to SAVE the current scenario before closing?',
172
'Closing SUMOPy',
173
wx.YES_NO | wx.CANCEL | wx.ICON_QUESTION)
174
ans = dlg.ShowModal()
175
dlg.Destroy()
176
# print ' ans,wx.ID_CANCEL,wx.ID_YES,wx.ID_NO',ans,wx.ID_CANCEL,wx.ID_YES,wx.ID_NO
177
if ans == wx.ID_CANCEL:
178
# print ' do not quit!'
179
pass
180
181
elif ans == wx.ID_YES:
182
# print ' save and quit'
183
scenario = self.get_scenario()
184
cm.save_obj(scenario, scenario.get_rootfilepath()+'.obj',
185
is_not_save_parent=False)
186
self._mainframe.destroy()
187
188
elif ans == wx.ID_NO:
189
# print 'quit immediately'
190
self._mainframe.destroy()
191
192
def on_create_from_xml(self, event=None):
193
# print 'on_create_from_xml'
194
scenariocreator = scenario.ScenarioCreator(
195
workdirpath=scenario.DIRPATH_SCENARIO,
196
logger=self._mainframe.get_logger()
197
)
198
dlg = ProcessDialog(self._mainframe, scenariocreator)
199
200
dlg.CenterOnScreen()
201
202
# this does not return until the dialog is closed.
203
val = dlg.ShowModal()
204
# print ' val,val == wx.ID_OK',val,wx.ID_OK,wx.ID_CANCEL,val == wx.ID_CANCEL
205
# print ' status =',dlg.get_status()
206
if dlg.get_status() != 'success': # val == wx.ID_CANCEL:
207
# print ">>>>>>>>>Unsuccessful\n"
208
dlg.Destroy()
209
210
if dlg.get_status() == 'success':
211
# print ">>>>>>>>>successful\n"
212
# apply current widget values to scenario instance
213
dlg.apply()
214
dlg.Destroy()
215
216
del self._scenario
217
self._scenario = scenariocreator.get_scenario()
218
219
self._scenario.import_xml()
220
self._mainframe.browse_obj(self._scenario)
221
# this should update all widgets for the new scenario!!
222
# print 'call self._mainframe.refresh_moduleguis()'
223
224
self._mainframe.refresh_moduleguis()
225
226
def on_create(self, event=None):
227
# print 'on_create'
228
scenariocreator = scenario.ScenarioCreator(logger=self._mainframe.get_logger(),
229
workdirpath=scenario.DIRPATH_SCENARIO,
230
)
231
dlg = ProcessDialog(self._mainframe, scenariocreator)
232
233
dlg.CenterOnScreen()
234
235
# this does not return until the dialog is closed.
236
val = dlg.ShowModal()
237
# print ' val,val == wx.ID_OK',val,wx.ID_OK,wx.ID_CANCEL,val == wx.ID_CANCEL
238
# print ' status =',dlg.get_status()
239
if dlg.get_status() != 'success': # val == wx.ID_CANCEL:
240
# print ">>>>>>>>>Unsuccessful\n"
241
dlg.Destroy()
242
243
if dlg.get_status() == 'success':
244
# print ">>>>>>>>>successful\n"
245
# apply current widget values to scenario instance
246
dlg.apply()
247
dlg.Destroy()
248
249
del self._scenario
250
self._scenario = scenariocreator.get_scenario()
251
self._mainframe.browse_obj(self._scenario)
252
253
# this should update all widgets for the new scenario!!
254
# print 'call self._mainframe.refresh_moduleguis()'
255
self._mainframe.refresh_moduleguis()
256
257
def on_open(self, event=None):
258
wildcards_all = "All files (*.*)|*.*"
259
wildcards_obj = "Python binary files (*.obj)|*.obj"
260
wildcards = wildcards_obj+"|"+wildcards_all
261
262
# Finally, if the directory is changed in the process of getting files, this
263
# dialog is set up to change the current working directory to the path chosen.
264
dlg = wx.FileDialog(
265
self._mainframe, message="Open scenario file",
266
#defaultDir = scenario.get_workdirpath(),
267
#defaultFile = os.path.join(scenario.get_workdirpath(), scenario.format_ident()+'.obj'),
268
wildcard=wildcards,
269
style=wx.OPEN | wx.CHANGE_DIR
270
)
271
272
# Show the dialog and retrieve the user response. If it is the OK response,
273
# process the data.
274
if dlg.ShowModal() == wx.ID_OK:
275
# This returns a Python list of files that were selected.
276
filepath = dlg.GetPath()
277
if len(filepath) > 0:
278
279
del self._scenario
280
self._scenario = scenario.load_scenario(filepath, logger=self._mainframe.get_logger())
281
self._mainframe.browse_obj(self._scenario)
282
# this should update all widgets for the new scenario!!
283
# print 'call self._mainframe.refresh_moduleguis()'
284
self._mainframe.refresh_moduleguis()
285
286
# Destroy the dialog. Don't do this until you are done with it!
287
# BAD things can happen otherwise!
288
dlg.Destroy()
289
290
def on_save(self, event=None):
291
scenario = self.get_scenario().save()
292
if event:
293
event.Skip()
294
295
def on_save_as(self, event=None):
296
scenario = self.get_scenario()
297
wildcards_all = "All files (*.*)|*.*"
298
wildcards_obj = "Python binary files (*.obj)|*.obj"
299
wildcards = wildcards_obj+"|"+wildcards_all
300
301
# Finally, if the directory is changed in the process of getting files, this
302
# dialog is set up to change the current working directory to the path chosen.
303
dlg = wx.FileDialog(
304
self._mainframe, message="Save scenario to file",
305
defaultDir=scenario.get_workdirpath(),
306
#defaultFile = scenario.get_rootfilepath()+'.obj',
307
wildcard=wildcards,
308
style=wx.SAVE | wx.CHANGE_DIR
309
)
310
311
# Show the dialog and retrieve the user response. If it is the OK response,
312
# process the data.
313
if dlg.ShowModal() == wx.ID_OK:
314
# This returns a Python list of files that were selected.
315
filepath = dlg.GetPath()
316
if len(filepath) > 0:
317
# now set new filename and workdir
318
319
scenario.save(filepath)
320
self._mainframe.refresh_moduleguis()
321
322
# Destroy the dialog. Don't do this until you are done with it!
323
# BAD things can happen otherwise!
324
dlg.Destroy()
325
326