Path: blob/main/tools/contributed/sumopy/agilepy/lib_wx/mainframe.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 mainframe.py15# @author Joerg Schweizer16# @date 2012171819import wx20import wx.py as py # pyshell21import sys22import os23import string24import time25from collections import OrderedDict2627from wxmisc import KEYMAP, AgileMenuMixin, AgileToolbarFrameMixin, AgileStatusbar, AgileMenubar282930from os.path import *31from os import getcwd3233import objpanel34from agilepy.lib_base.logger import Logger3536# We first have to set an application-wide help provider. Normally you37# would do this in your app's OnInit or in other startup code...38provider = wx.SimpleHelpProvider()39wx.HelpProvider_Set(provider)404142def make_moduleguis(appdir, dirlist):43moduleguilist = []44for modulesdir in dirlist:45make_moduleguilist(appdir, moduleguilist, modulesdir)46# print 'make_moduleguis: moduleguilist=\n',moduleguilist4748moduleguilist.sort()49moduleguis = OrderedDict()50for initpriority, wxgui in moduleguilist:51moduleguis[wxgui.get_ident()] = wxgui52return moduleguis535455def make_moduleguilist(appdir, moduleguilist, modulesdir):56# print 'make_moduleguilist appdir,modulesdir',appdir,modulesdir57# print ' check dir',os.path.join(appdir, modulesdir)58# for modulename in os.listdir(modulesdir):59# is_noimport = (modulename in ['__init__.py',]) | (modulename.split('.')[-1] == 'pyc')60# is_dir = os.path.isdir(os.path.join(modulesdir, modulename))61# if (not is_noimport)& (not is_dir):62# mn = modulename.split('.')[0]63# for n in modulename.split('.')[1:-1]:64# mn += '.'+n65#66# lib = __import__(modulesdir + '.' + mn )67# #module = getattr(lib,mn)68# #print ' imported',mn,modulesdir+'.' + mn6970for modulename in os.listdir(os.path.join(appdir, modulesdir)): # use walk module to get recursive71# if os.path.isdir(os.path.join(os.getcwd(), pluginname)): # is never a dir???7273is_noimport = (modulename in ['__init__.py', ]) | (modulename.split('.')[-1] == 'pyc')74is_dir = os.path.isdir(os.path.join(appdir, modulesdir, modulename))7576# print ' GUI modulename',modulename,is_noimport,is_dir77if (not is_noimport) & is_dir:7879lib = __import__(modulesdir+'.'+modulename)80module = getattr(lib, modulename)81# print ' imported modulename',modulename,module,hasattr(module,'get_wxgui')82# has module gui support specified in __init__.py83if hasattr(module, 'get_wxgui'):84wxgui = module.get_wxgui()85if wxgui is not None:86# print ' append',(wxgui.get_initpriority(), wxgui.get_ident())87moduleguilist.append((wxgui.get_initpriority(), wxgui))888990class MainSplitter(wx.SplitterWindow):91def __init__(self, parent, ID=wx.ID_ANY):92wx.SplitterWindow.__init__(self, parent, ID,93style=wx.SP_LIVE_UPDATE94)9596self.SetMinimumPaneSize(20)9798#sty = wx.BORDER_SUNKEN99100#emptyobj = cm.BaseObjman('empty')101self._objbrowser = objpanel.NaviPanel(self,102None,103#show_title = False104#size = w.DefaultSize,105#style = wx.DEFAULT_DIALOG_STYLE|wx.MAXIMIZE_BOX|wx.RESIZE_BORDER,106# choose_id=False,choose_attr=False,107# func_choose_id=None,108# func_change_obj=None,109#panelstyle = 'default',110immediate_apply=True,111buttons=[],112standartbuttons=['apply', 'restore'],113#defaultbutton = defaultbutton,114)115116#p1 = wx.Window(splitter, style=sty)117# p1.SetBackgroundColour("pink")118#wx.StaticText(p1, -1, "Object", (50,50))119120#self.canvas = wx.Window(splitter, style=sty)121# self.canvas.SetBackgroundColour("green")122#wx.StaticText(self.canvas, -1, "Panel two", (50,50))123#self.canvas = WxGLTest2(splitter)124#self.canvas = WxGLTest_orig(splitter)125126#self._viewtabs = wx.Notebook(self,wx.ID_ANY, style=wx.CLIP_CHILDREN)127self._viewtabs = wx.Notebook(self, -1, size=(21, 21), style=wx.BK_DEFAULT128# wx.BK_TOP129# wx.BK_BOTTOM130# wx.BK_LEFT131# wx.BK_RIGHT132# | wx.NB_MULTILINE133)134135self._n_views = 0136self._viewnames = []137#nbpanel = wx.Panel(splitter)138#self._viewtabs = wx.Notebook(nbpanel,wx.ID_ANY, style=wx.CLIP_CHILDREN)139#sizer = wx.BoxSizer(wx.VERTICAL)140#sizer.Add(self._viewtabs, 1, wx.ALL|wx.EXPAND, 5)141# nbpanel.SetSizer(sizer)142# self.Layout()143144# finally, put the notebook in a sizer for the panel to manage145# the layout146#sizer = wx.BoxSizer()147#sizer.Add(self._viewtabs, 1, wx.EXPAND)148# self.SetSizer(sizer)149150#splitter.SplitVertically(self._objbrowser,self.canvas , -100)151self.SplitVertically(self._objbrowser, self._viewtabs, -100)152# self.SetSashGravity(0.2) # notebook too small153self.SetSashPosition(400, True)154self.Bind(wx.EVT_SPLITTER_SASH_POS_CHANGED, self.OnSashChanged)155self.Bind(wx.EVT_SPLITTER_SASH_POS_CHANGING, self.OnSashChanging)156157def add_view(self, name, ViewClass, **args):158"""159Add a new view to the notebook.160"""161# print 'context.add_view',ViewClass162# print ' args',args163view = ViewClass(self._viewtabs,164mainframe=self.GetParent(),165**args166)167168# Add network tab with editor169p = self._viewtabs.AddPage(view, name.title())170self._viewnames.append(name)171#self._views[name] = view172# self._viewtabs.SetSelection(p)173# self._viewtabs.Show(True)174return view175176def select_view(self, ind=0, name=None):177if name is not None:178if name in self._viewnames:179ind = self._viewnames.index(name)180self._viewtabs.ChangeSelection(ind)181else:182return False183else:184self._viewtabs.ChangeSelection(ind)185186def browse_obj(self, obj, **kwargs):187self._objbrowser.change_obj(obj, **kwargs)188189def OnSashChanged(self, evt):190#print("sash changed to %s\n" % str(evt.GetSashPosition()))191pass192193def OnSashChanging(self, evt):194#print("sash changing to %s\n" % str(evt.GetSashPosition()))195# uncomment this to not allow the change196# evt.SetSashPosition(-1)197# self.canvas.OnSize()198pass199200201class AgileMainframe(AgileToolbarFrameMixin, wx.Frame):202"""203Simple wx frame with some special features.204"""205206def __init__(self, parent=None, title='mainframe', appname=None,207moduledirs=[], args=[], appdir='',208is_maximize=False, is_centerscreen=True,209pos=wx.DefaultPosition, size=wx.DefaultSize,210style=wx.DEFAULT_FRAME_STYLE,211name='theframe', size_toolbaricons=(24, 24)):212213self._args = args214# print 'AgileMainframe.__init__',title,appdir215216# Forcing a specific style on the window.217# Should this include styles passed?218219if appname is not None:220self.appname = appname221else:222self.appname = title223wx.Frame.__init__(self, parent, wx.ID_ANY, self.appname,224pos, size=size, style=style, name=name)225226#super(GLFrame, self).__init__(parent, id, title, pos, size, style, name)227self._splitter = MainSplitter(self)228self._views = {}229#wx.EVT_SIZE (self, self.on_size)230# sizer=wx.BoxSizer(wx.VERTICAL)231# sizer.Add(p1,0, wx.ALL | wx.ALIGN_LEFT | wx.GROW, 4)# from NaviPanelTest232# sizer.Add(self.canvas,1,wx.GROW)# from NaviPanelTest233234# finish panel setup235# self.SetSizer(sizer)236# sizer.Fit(self)237# self.Show()238239# this is needed to initialize GL projections for unproject240# wx.CallAfter(self.on_size)241242#width,height = self.GetSize()243#self._splitter.SetSashPosition(300, True)244# maximize the frame245if is_maximize:246self.Maximize()247if is_centerscreen:248self.CenterOnScreen()249250#################################################################251# create statusbar252#self.statusbar = AgileStatusbar(self)253self.statusbar = AgileStatusbar(self)254self.SetStatusBar(self.statusbar)255# self.count=0.0256257#################################################################258# create toolbar259260self.init_toolbar(size=size_toolbaricons)261#262#new_bmp = wx.ArtProvider.GetBitmap(wx.ART_NEW, wx.ART_TOOLBAR, tsize)263#open_bmp = wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_TOOLBAR, tsize)264#save_bmp= wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE, wx.ART_TOOLBAR, tsize)265#cut_bmp = wx.ArtProvider.GetBitmap(wx.ART_CUT, wx.ART_TOOLBAR, tsize)266#copy_bmp = wx.ArtProvider.GetBitmap(wx.ART_COPY, wx.ART_TOOLBAR, tsize)267#paste_bmp= wx.ArtProvider.GetBitmap(wx.ART_PASTE, wx.ART_TOOLBAR, tsize)268269#self.add_tool('new',self.on_open,new_bmp,'create new doc')270#self.add_tool('open',self.on_open,open_bmp,'Open doc')271#self.add_tool('save',self.on_save,save_bmp,'Save doc')272# self.toolbar.AddSeparator()273# self.add_tool('cut',self.on_open,cut_bmp,'Cut')274# self.add_tool('copy',self.on_open,copy_bmp,'Copy')275# self.add_tool('paste',self.on_open,paste_bmp,'Paste')276277# self.SetToolBar(self.toolbar)278279#################################################################280# create the menu bar281282self.menubar = AgileMenubar(self)283# self.make_menu()284# self.menubar.append_menu('tools')285self.SetMenuBar(self.menubar)286# self.Show(True) #NO!!287288#################################################################289# init logger290self._logger = Logger()291self._logger.add_callback(self.write_message, 'message')292self._logger.add_callback(self.write_action, 'action')293self._logger.add_callback(self.show_progress, 'progress')294#################################################################295self._moduleguis = make_moduleguis(appdir, moduledirs)296297for modulename, modulegui in self._moduleguis.iteritems():298# print ' init gui of module',modulename299modulegui.init_widgets(self)300#################################################################301# event section: specify in App302303#wx.EVT_BUTTON(self, 1003, self.on_close)304# wx.EVT_CLOSE(self, self.on_close)305#wx.EVT_IDLE(self, self.on_idle)306307def set_title(self, titlename):308self.SetTitle(self.appname+' - '+titlename)309310def refresh_moduleguis(self):311# print 'refresh_moduleguis',len(self._moduleguis)312self.browse_obj(None)313for modulename, modulegui in self._moduleguis.iteritems():314# print ' refresh gui of module',modulename315modulegui.refresh_widgets()316317def get_modulegui(self, modulename):318return self._moduleguis[modulename]319320def write_message(self, text, **kwargs):321self.statusbar.write_message(text)322323def write_action(self, text, **kwargs):324self.statusbar.write_action(text)325self.statusbar.write_message('')326327def show_progress(self, percent, **kwargs):328self.statusbar.set_progress(percent)329330def get_logger(self):331return self._logger332333def set_logger(self, logger):334self._logger = logger335336def get_args(self):337return self._args338339def browse_obj(self, obj, **kwargs):340self._splitter.browse_obj(obj, **kwargs)341342def make_menu(self):343"""344Creates manu. To be overridden.345"""346self.menubar.append_menu('file')347self.menubar.append_menu('file/doc')348349self.menubar.append_item('file/doc/open', self.on_open,350shortkey='Ctrl+o', info='open it out')351352self.menubar.append_item('file/doc/save', self.on_save,353shortkey='Ctrl+s', info='save it out')354355# self.menubar.append_menu('edit')356# self.menubar.append_item('edit/cut',self.cut,\357# shortkey='Ctrl+c',info='cut it out')358359# self.menubar.append_item('edit/toggle',self.toggle_tools,\360# shortkey='Ctrl+t',info='toggle tools')361362def add_view(self, name, ViewClass, **args):363"""364Add a new view to the notebook.365"""366# print 'context.add_view',ViewClass367# print ' args',args368369view = self._splitter.add_view(name, ViewClass, **args)370self._views[name] = view371# self._viewtabs.SetSelection(p)372# self._splitter._viewtabs.Show(True)373return view374375def select_view(self, ind=0, name=None):376self._splitter.select_view(ind=ind, name=name)377378def on_size(self, event=None):379# print 'Mainframe.on_size'380# self.tc.SetSize(self.GetSize())381# self.tc.SetSize(self.GetSize())382# self._viewtabs.SetSize(self.GetSize())383# pass384#wx.LayoutAlgorithm().LayoutWindow(self, self.p1)385#wx.LayoutAlgorithm().LayoutWindow(self, self.p1)386387# important:388#wx.LayoutAlgorithm().LayoutWindow(self, self._viewtabs)389wx.LayoutAlgorithm().LayoutWindow(self, self._splitter)390# if event:391# event.Skip()392393def on_save(self, event):394print 'save it!!'395396def on_open(self, event):397"""Open a document"""398#wildcards = CreateWildCards() + "All files (*.*)|*.*"399print 'open it!!'400401def destroy(self):402"""Destroy this object"""403# self.theDocManager.theDestructor()404#imgPreferences.saveXml(self.GetStartDirectory() + "/" + imgINI_FILE_NAME)405##del self.thePrint406self.Destroy()407408def on_close(self, event):409# self.Close(True)410print 'Mainframe.on_close'411# pass412self.destroy()413414def on_exit(self, event):415"""Called when the application is to be finished"""416self.destroy()417418def on_idle(self, event):419pass420#self.count = self.count + 1421# if self.count >= 100:422# self.count = 0423424# self.statusbar.set_progress(self.count)425426def on_about(self, event):427"""Display the information about this application"""428#dlg = imgDlgAbout(self, -1, "")429# dlg.ShowModal()430# dlg.Destroy()431pass432433def write_to_statusbar(self, data, key='message'):434self.statusbar[key] = str(data)435436437