Path: blob/main/tools/contributed/sumopy/coremodules/scenario/wxgui.py
169689 views
# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo1# Copyright (C) 2016-2025 German Aerospace Center (DLR) and others.2# SUMOPy module3# Copyright (C) 2012-2021 University of Bologna - DICAM4# This program and the accompanying materials are made available under the5# terms of the Eclipse Public License 2.0 which is available at6# https://www.eclipse.org/legal/epl-2.0/7# This Source Code may also be made available under the following Secondary8# Licenses when the conditions for such availability set forth in the Eclipse9# Public License 2.0 are satisfied: GNU General Public License, version 210# or later which is available at11# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html12# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later1314# @file wxgui.py15# @author Joerg Schweizer16# @date 20121718import os1920import wx21import agilepy.lib_base.classman as cm22from coremodules.misc import shapeformat2324from agilepy.lib_wx.modulegui import ModuleGui25from agilepy.lib_wx.processdialog import ProcessDialog2627import scenario282930class WxGui(ModuleGui):31"""Contains functions that communicate between the widgets of the main wx gui32and the functions of the plugin.33"""3435def __init__(self, ident):36self._scenario = None37self._init_common(ident, priority=1,38icondirpath=os.path.join(os.path.dirname(__file__), 'images'))3940def set_module(self, scenario):41self._scenario = scenario4243def get_module(self):44return self._scenario4546def get_scenario(self):47return self._scenario4849def init_widgets(self, mainframe):50"""51Set mainframe and initialize widgets to various places.52"""53self._mainframe = mainframe54#self._neteditor = mainframe.add_view("Network", Neteditor)5556# mainframe.browse_obj(self._module)57self.make_menu()58self.make_toolbar()59args = mainframe.get_args()60del self._scenario61self._scenario = None62if len(args) == 3:63# command line provided rootname and dirpath64rootname = args[1]65dirpath = args[2]66name_scenario = rootname67self._scenario = scenario.Scenario(rootname, workdirpath=dirpath,68name_scenario=name_scenario,69logger=self._mainframe.get_logger())70self._scenario.import_xml()7172elif len(args) == 2:73filepath = args[1]74self._scenario = scenario.load_scenario(filepath, logger=self._mainframe.get_logger())75#self._scenario = cm.load_obj(filepath)7677if self._scenario is None:78# command line provided nothing79rootname = 'myscenario'80# None# this means no directory will be created os.path.join(os.path.expanduser("~"),'sumopy','myscenario')81dirpath = scenario.DIRPATH_SCENARIO82name_scenario = 'My Scenario'83self._scenario = scenario.Scenario(rootname, workdirpath=dirpath,84name_scenario=name_scenario,85logger=self._mainframe.get_logger())8687def refresh_widgets(self):88"""89Check through mainframe what the state of the application is90and reset widgets. For exampe enable/disable widgets91dependent on the availability of data.92"""93self.set_frametitle()94# if self._scenario != self._mainframe.get_modulegui('coremodules.scenario').get_module():95# del self._scenario96# self._scenario = self._mainframe.get_modulegui('coremodules.scenario').get_module()97# self._mainframe.set_title(self._scenario.get_ident()+"("+self._scenario.get_name()+")")98self._mainframe.browse_obj(self._scenario)99100def set_frametitle(self):101self._mainframe.set_title(self._scenario.rootname+" ("+self._scenario.name_scenario+")")102103def make_menu(self):104# event section105#wx.EVT_BUTTON(self._mainframe, 1003, self.on_close)106wx.EVT_CLOSE(self._mainframe, self.on_close)107#wx.EVT_IDLE(self._mainframe, self.on_idle)108109# print 'make_menu'110menubar = self._mainframe.menubar111menubar.append_menu('Scenario')112# menubar.append_menu( 'Scenario/import',113# bitmap = wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE,wx.ART_MENU),114# )115116menubar.append_menu('Scenario/create',117bitmap=wx.ArtProvider.GetBitmap(wx.ART_NEW, wx.ART_MENU),118)119120menubar.append_item('Scenario/create/new...',121self.on_create,122info='Create new, empty scenario.',123bitmap=wx.ArtProvider.GetBitmap(wx.ART_NEW, wx.ART_MENU),124)125126menubar.append_item('Scenario/create/create from xml...',127self.on_create_from_xml,128info='Create scenario from various sumo xml files.',129bitmap=wx.ArtProvider.GetBitmap(wx.ART_NEW, wx.ART_MENU),130)131132menubar.append_item('Scenario/open...',133self.on_open,134info='Open a new scenario from a Python binary file.',135bitmap=wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_MENU),136)137138menubar.append_item('Scenario/browse',139self.on_browse_obj, # common function in modulegui140info='View and browse Scenario in object panel.',141bitmap=self.get_agileicon('icon_browse_24px.png'), # ,142)143144menubar.append_item('Scenario/safe',145self.on_save, shortkey='Ctrl+S',146info='Save current scenario in a Python binary file.',147bitmap=wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE, wx.ART_MENU),148)149150menubar.append_item('Scenario/safe as...',151self.on_save_as,152info='Save as scenario in a Python binary file.',153bitmap=wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE_AS, wx.ART_MENU),154)155156menubar.append_item('Scenario/quit...',157self.on_close,158info='Quit Sumopy', shortkey='Ctrl+Q',159bitmap=wx.ArtProvider.GetBitmap(wx.ART_QUIT, wx.ART_MENU)160)161162def on_close(self, event):163# self.Close(True)164# pass165self.on_exit(event)166167def on_exit(self, event):168"""Called when the application is to be finished"""169dlg = wx.MessageDialog(self._mainframe,170'SUMOPy is about to close.\nDo you want to SAVE the current scenario before closing?',171'Closing SUMOPy',172wx.YES_NO | wx.CANCEL | wx.ICON_QUESTION)173ans = dlg.ShowModal()174dlg.Destroy()175# print ' ans,wx.ID_CANCEL,wx.ID_YES,wx.ID_NO',ans,wx.ID_CANCEL,wx.ID_YES,wx.ID_NO176if ans == wx.ID_CANCEL:177# print ' do not quit!'178pass179180elif ans == wx.ID_YES:181# print ' save and quit'182scenario = self.get_scenario()183cm.save_obj(scenario, scenario.get_rootfilepath()+'.obj',184is_not_save_parent=False)185self._mainframe.destroy()186187elif ans == wx.ID_NO:188# print 'quit immediately'189self._mainframe.destroy()190191def on_create_from_xml(self, event=None):192# print 'on_create_from_xml'193scenariocreator = scenario.ScenarioCreator(194workdirpath=scenario.DIRPATH_SCENARIO,195logger=self._mainframe.get_logger()196)197dlg = ProcessDialog(self._mainframe, scenariocreator)198199dlg.CenterOnScreen()200201# this does not return until the dialog is closed.202val = dlg.ShowModal()203# print ' val,val == wx.ID_OK',val,wx.ID_OK,wx.ID_CANCEL,val == wx.ID_CANCEL204# print ' status =',dlg.get_status()205if dlg.get_status() != 'success': # val == wx.ID_CANCEL:206# print ">>>>>>>>>Unsuccessful\n"207dlg.Destroy()208209if dlg.get_status() == 'success':210# print ">>>>>>>>>successful\n"211# apply current widget values to scenario instance212dlg.apply()213dlg.Destroy()214215del self._scenario216self._scenario = scenariocreator.get_scenario()217218self._scenario.import_xml()219self._mainframe.browse_obj(self._scenario)220# this should update all widgets for the new scenario!!221# print 'call self._mainframe.refresh_moduleguis()'222223self._mainframe.refresh_moduleguis()224225def on_create(self, event=None):226# print 'on_create'227scenariocreator = scenario.ScenarioCreator(logger=self._mainframe.get_logger(),228workdirpath=scenario.DIRPATH_SCENARIO,229)230dlg = ProcessDialog(self._mainframe, scenariocreator)231232dlg.CenterOnScreen()233234# this does not return until the dialog is closed.235val = dlg.ShowModal()236# print ' val,val == wx.ID_OK',val,wx.ID_OK,wx.ID_CANCEL,val == wx.ID_CANCEL237# print ' status =',dlg.get_status()238if dlg.get_status() != 'success': # val == wx.ID_CANCEL:239# print ">>>>>>>>>Unsuccessful\n"240dlg.Destroy()241242if dlg.get_status() == 'success':243# print ">>>>>>>>>successful\n"244# apply current widget values to scenario instance245dlg.apply()246dlg.Destroy()247248del self._scenario249self._scenario = scenariocreator.get_scenario()250self._mainframe.browse_obj(self._scenario)251252# this should update all widgets for the new scenario!!253# print 'call self._mainframe.refresh_moduleguis()'254self._mainframe.refresh_moduleguis()255256def on_open(self, event=None):257wildcards_all = "All files (*.*)|*.*"258wildcards_obj = "Python binary files (*.obj)|*.obj"259wildcards = wildcards_obj+"|"+wildcards_all260261# Finally, if the directory is changed in the process of getting files, this262# dialog is set up to change the current working directory to the path chosen.263dlg = wx.FileDialog(264self._mainframe, message="Open scenario file",265#defaultDir = scenario.get_workdirpath(),266#defaultFile = os.path.join(scenario.get_workdirpath(), scenario.format_ident()+'.obj'),267wildcard=wildcards,268style=wx.OPEN | wx.CHANGE_DIR269)270271# Show the dialog and retrieve the user response. If it is the OK response,272# process the data.273if dlg.ShowModal() == wx.ID_OK:274# This returns a Python list of files that were selected.275filepath = dlg.GetPath()276if len(filepath) > 0:277278del self._scenario279self._scenario = scenario.load_scenario(filepath, logger=self._mainframe.get_logger())280self._mainframe.browse_obj(self._scenario)281# this should update all widgets for the new scenario!!282# print 'call self._mainframe.refresh_moduleguis()'283self._mainframe.refresh_moduleguis()284285# Destroy the dialog. Don't do this until you are done with it!286# BAD things can happen otherwise!287dlg.Destroy()288289def on_save(self, event=None):290scenario = self.get_scenario().save()291if event:292event.Skip()293294def on_save_as(self, event=None):295scenario = self.get_scenario()296wildcards_all = "All files (*.*)|*.*"297wildcards_obj = "Python binary files (*.obj)|*.obj"298wildcards = wildcards_obj+"|"+wildcards_all299300# Finally, if the directory is changed in the process of getting files, this301# dialog is set up to change the current working directory to the path chosen.302dlg = wx.FileDialog(303self._mainframe, message="Save scenario to file",304defaultDir=scenario.get_workdirpath(),305#defaultFile = scenario.get_rootfilepath()+'.obj',306wildcard=wildcards,307style=wx.SAVE | wx.CHANGE_DIR308)309310# Show the dialog and retrieve the user response. If it is the OK response,311# process the data.312if dlg.ShowModal() == wx.ID_OK:313# This returns a Python list of files that were selected.314filepath = dlg.GetPath()315if len(filepath) > 0:316# now set new filename and workdir317318scenario.save(filepath)319self._mainframe.refresh_moduleguis()320321# Destroy the dialog. Don't do this until you are done with it!322# BAD things can happen otherwise!323dlg.Destroy()324325326