Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/tools/contributed/sumopy/agilepy/lib_wx/mainframe.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 mainframe.py
16
# @author Joerg Schweizer
17
# @date 2012
18
19
20
import wx
21
import wx.py as py # pyshell
22
import sys
23
import os
24
import string
25
import time
26
from collections import OrderedDict
27
28
from wxmisc import KEYMAP, AgileMenuMixin, AgileToolbarFrameMixin, AgileStatusbar, AgileMenubar
29
30
31
from os.path import *
32
from os import getcwd
33
34
import objpanel
35
from agilepy.lib_base.logger import Logger
36
37
# We first have to set an application-wide help provider. Normally you
38
# would do this in your app's OnInit or in other startup code...
39
provider = wx.SimpleHelpProvider()
40
wx.HelpProvider_Set(provider)
41
42
43
def make_moduleguis(appdir, dirlist):
44
moduleguilist = []
45
for modulesdir in dirlist:
46
make_moduleguilist(appdir, moduleguilist, modulesdir)
47
# print 'make_moduleguis: moduleguilist=\n',moduleguilist
48
49
moduleguilist.sort()
50
moduleguis = OrderedDict()
51
for initpriority, wxgui in moduleguilist:
52
moduleguis[wxgui.get_ident()] = wxgui
53
return moduleguis
54
55
56
def make_moduleguilist(appdir, moduleguilist, modulesdir):
57
# print 'make_moduleguilist appdir,modulesdir',appdir,modulesdir
58
# print ' check dir',os.path.join(appdir, modulesdir)
59
# for modulename in os.listdir(modulesdir):
60
# is_noimport = (modulename in ['__init__.py',]) | (modulename.split('.')[-1] == 'pyc')
61
# is_dir = os.path.isdir(os.path.join(modulesdir, modulename))
62
# if (not is_noimport)& (not is_dir):
63
# mn = modulename.split('.')[0]
64
# for n in modulename.split('.')[1:-1]:
65
# mn += '.'+n
66
#
67
# lib = __import__(modulesdir + '.' + mn )
68
# #module = getattr(lib,mn)
69
# #print ' imported',mn,modulesdir+'.' + mn
70
71
for modulename in os.listdir(os.path.join(appdir, modulesdir)): # use walk module to get recursive
72
# if os.path.isdir(os.path.join(os.getcwd(), pluginname)): # is never a dir???
73
74
is_noimport = (modulename in ['__init__.py', ]) | (modulename.split('.')[-1] == 'pyc')
75
is_dir = os.path.isdir(os.path.join(appdir, modulesdir, modulename))
76
77
# print ' GUI modulename',modulename,is_noimport,is_dir
78
if (not is_noimport) & is_dir:
79
80
lib = __import__(modulesdir+'.'+modulename)
81
module = getattr(lib, modulename)
82
# print ' imported modulename',modulename,module,hasattr(module,'get_wxgui')
83
# has module gui support specified in __init__.py
84
if hasattr(module, 'get_wxgui'):
85
wxgui = module.get_wxgui()
86
if wxgui is not None:
87
# print ' append',(wxgui.get_initpriority(), wxgui.get_ident())
88
moduleguilist.append((wxgui.get_initpriority(), wxgui))
89
90
91
class MainSplitter(wx.SplitterWindow):
92
def __init__(self, parent, ID=wx.ID_ANY):
93
wx.SplitterWindow.__init__(self, parent, ID,
94
style=wx.SP_LIVE_UPDATE
95
)
96
97
self.SetMinimumPaneSize(20)
98
99
#sty = wx.BORDER_SUNKEN
100
101
#emptyobj = cm.BaseObjman('empty')
102
self._objbrowser = objpanel.NaviPanel(self,
103
None,
104
#show_title = False
105
#size = w.DefaultSize,
106
#style = wx.DEFAULT_DIALOG_STYLE|wx.MAXIMIZE_BOX|wx.RESIZE_BORDER,
107
# choose_id=False,choose_attr=False,
108
# func_choose_id=None,
109
# func_change_obj=None,
110
#panelstyle = 'default',
111
immediate_apply=True,
112
buttons=[],
113
standartbuttons=['apply', 'restore'],
114
#defaultbutton = defaultbutton,
115
)
116
117
#p1 = wx.Window(splitter, style=sty)
118
# p1.SetBackgroundColour("pink")
119
#wx.StaticText(p1, -1, "Object", (50,50))
120
121
#self.canvas = wx.Window(splitter, style=sty)
122
# self.canvas.SetBackgroundColour("green")
123
#wx.StaticText(self.canvas, -1, "Panel two", (50,50))
124
#self.canvas = WxGLTest2(splitter)
125
#self.canvas = WxGLTest_orig(splitter)
126
127
#self._viewtabs = wx.Notebook(self,wx.ID_ANY, style=wx.CLIP_CHILDREN)
128
self._viewtabs = wx.Notebook(self, -1, size=(21, 21), style=wx.BK_DEFAULT
129
# wx.BK_TOP
130
# wx.BK_BOTTOM
131
# wx.BK_LEFT
132
# wx.BK_RIGHT
133
# | wx.NB_MULTILINE
134
)
135
136
self._n_views = 0
137
self._viewnames = []
138
#nbpanel = wx.Panel(splitter)
139
#self._viewtabs = wx.Notebook(nbpanel,wx.ID_ANY, style=wx.CLIP_CHILDREN)
140
#sizer = wx.BoxSizer(wx.VERTICAL)
141
#sizer.Add(self._viewtabs, 1, wx.ALL|wx.EXPAND, 5)
142
# nbpanel.SetSizer(sizer)
143
# self.Layout()
144
145
# finally, put the notebook in a sizer for the panel to manage
146
# the layout
147
#sizer = wx.BoxSizer()
148
#sizer.Add(self._viewtabs, 1, wx.EXPAND)
149
# self.SetSizer(sizer)
150
151
#splitter.SplitVertically(self._objbrowser,self.canvas , -100)
152
self.SplitVertically(self._objbrowser, self._viewtabs, -100)
153
# self.SetSashGravity(0.2) # notebook too small
154
self.SetSashPosition(400, True)
155
self.Bind(wx.EVT_SPLITTER_SASH_POS_CHANGED, self.OnSashChanged)
156
self.Bind(wx.EVT_SPLITTER_SASH_POS_CHANGING, self.OnSashChanging)
157
158
def add_view(self, name, ViewClass, **args):
159
"""
160
Add a new view to the notebook.
161
"""
162
# print 'context.add_view',ViewClass
163
# print ' args',args
164
view = ViewClass(self._viewtabs,
165
mainframe=self.GetParent(),
166
**args
167
)
168
169
# Add network tab with editor
170
p = self._viewtabs.AddPage(view, name.title())
171
self._viewnames.append(name)
172
#self._views[name] = view
173
# self._viewtabs.SetSelection(p)
174
# self._viewtabs.Show(True)
175
return view
176
177
def select_view(self, ind=0, name=None):
178
if name is not None:
179
if name in self._viewnames:
180
ind = self._viewnames.index(name)
181
self._viewtabs.ChangeSelection(ind)
182
else:
183
return False
184
else:
185
self._viewtabs.ChangeSelection(ind)
186
187
def browse_obj(self, obj, **kwargs):
188
self._objbrowser.change_obj(obj, **kwargs)
189
190
def OnSashChanged(self, evt):
191
#print("sash changed to %s\n" % str(evt.GetSashPosition()))
192
pass
193
194
def OnSashChanging(self, evt):
195
#print("sash changing to %s\n" % str(evt.GetSashPosition()))
196
# uncomment this to not allow the change
197
# evt.SetSashPosition(-1)
198
# self.canvas.OnSize()
199
pass
200
201
202
class AgileMainframe(AgileToolbarFrameMixin, wx.Frame):
203
"""
204
Simple wx frame with some special features.
205
"""
206
207
def __init__(self, parent=None, title='mainframe', appname=None,
208
moduledirs=[], args=[], appdir='',
209
is_maximize=False, is_centerscreen=True,
210
pos=wx.DefaultPosition, size=wx.DefaultSize,
211
style=wx.DEFAULT_FRAME_STYLE,
212
name='theframe', size_toolbaricons=(24, 24)):
213
214
self._args = args
215
# print 'AgileMainframe.__init__',title,appdir
216
217
# Forcing a specific style on the window.
218
# Should this include styles passed?
219
220
if appname is not None:
221
self.appname = appname
222
else:
223
self.appname = title
224
wx.Frame.__init__(self, parent, wx.ID_ANY, self.appname,
225
pos, size=size, style=style, name=name)
226
227
#super(GLFrame, self).__init__(parent, id, title, pos, size, style, name)
228
self._splitter = MainSplitter(self)
229
self._views = {}
230
#wx.EVT_SIZE (self, self.on_size)
231
# sizer=wx.BoxSizer(wx.VERTICAL)
232
# sizer.Add(p1,0, wx.ALL | wx.ALIGN_LEFT | wx.GROW, 4)# from NaviPanelTest
233
# sizer.Add(self.canvas,1,wx.GROW)# from NaviPanelTest
234
235
# finish panel setup
236
# self.SetSizer(sizer)
237
# sizer.Fit(self)
238
# self.Show()
239
240
# this is needed to initialize GL projections for unproject
241
# wx.CallAfter(self.on_size)
242
243
#width,height = self.GetSize()
244
#self._splitter.SetSashPosition(300, True)
245
# maximize the frame
246
if is_maximize:
247
self.Maximize()
248
if is_centerscreen:
249
self.CenterOnScreen()
250
251
#################################################################
252
# create statusbar
253
#self.statusbar = AgileStatusbar(self)
254
self.statusbar = AgileStatusbar(self)
255
self.SetStatusBar(self.statusbar)
256
# self.count=0.0
257
258
#################################################################
259
# create toolbar
260
261
self.init_toolbar(size=size_toolbaricons)
262
#
263
#new_bmp = wx.ArtProvider.GetBitmap(wx.ART_NEW, wx.ART_TOOLBAR, tsize)
264
#open_bmp = wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_TOOLBAR, tsize)
265
#save_bmp= wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE, wx.ART_TOOLBAR, tsize)
266
#cut_bmp = wx.ArtProvider.GetBitmap(wx.ART_CUT, wx.ART_TOOLBAR, tsize)
267
#copy_bmp = wx.ArtProvider.GetBitmap(wx.ART_COPY, wx.ART_TOOLBAR, tsize)
268
#paste_bmp= wx.ArtProvider.GetBitmap(wx.ART_PASTE, wx.ART_TOOLBAR, tsize)
269
270
#self.add_tool('new',self.on_open,new_bmp,'create new doc')
271
#self.add_tool('open',self.on_open,open_bmp,'Open doc')
272
#self.add_tool('save',self.on_save,save_bmp,'Save doc')
273
# self.toolbar.AddSeparator()
274
# self.add_tool('cut',self.on_open,cut_bmp,'Cut')
275
# self.add_tool('copy',self.on_open,copy_bmp,'Copy')
276
# self.add_tool('paste',self.on_open,paste_bmp,'Paste')
277
278
# self.SetToolBar(self.toolbar)
279
280
#################################################################
281
# create the menu bar
282
283
self.menubar = AgileMenubar(self)
284
# self.make_menu()
285
# self.menubar.append_menu('tools')
286
self.SetMenuBar(self.menubar)
287
# self.Show(True) #NO!!
288
289
#################################################################
290
# init logger
291
self._logger = Logger()
292
self._logger.add_callback(self.write_message, 'message')
293
self._logger.add_callback(self.write_action, 'action')
294
self._logger.add_callback(self.show_progress, 'progress')
295
#################################################################
296
self._moduleguis = make_moduleguis(appdir, moduledirs)
297
298
for modulename, modulegui in self._moduleguis.iteritems():
299
# print ' init gui of module',modulename
300
modulegui.init_widgets(self)
301
#################################################################
302
# event section: specify in App
303
304
#wx.EVT_BUTTON(self, 1003, self.on_close)
305
# wx.EVT_CLOSE(self, self.on_close)
306
#wx.EVT_IDLE(self, self.on_idle)
307
308
def set_title(self, titlename):
309
self.SetTitle(self.appname+' - '+titlename)
310
311
def refresh_moduleguis(self):
312
# print 'refresh_moduleguis',len(self._moduleguis)
313
self.browse_obj(None)
314
for modulename, modulegui in self._moduleguis.iteritems():
315
# print ' refresh gui of module',modulename
316
modulegui.refresh_widgets()
317
318
def get_modulegui(self, modulename):
319
return self._moduleguis[modulename]
320
321
def write_message(self, text, **kwargs):
322
self.statusbar.write_message(text)
323
324
def write_action(self, text, **kwargs):
325
self.statusbar.write_action(text)
326
self.statusbar.write_message('')
327
328
def show_progress(self, percent, **kwargs):
329
self.statusbar.set_progress(percent)
330
331
def get_logger(self):
332
return self._logger
333
334
def set_logger(self, logger):
335
self._logger = logger
336
337
def get_args(self):
338
return self._args
339
340
def browse_obj(self, obj, **kwargs):
341
self._splitter.browse_obj(obj, **kwargs)
342
343
def make_menu(self):
344
"""
345
Creates manu. To be overridden.
346
"""
347
self.menubar.append_menu('file')
348
self.menubar.append_menu('file/doc')
349
350
self.menubar.append_item('file/doc/open', self.on_open,
351
shortkey='Ctrl+o', info='open it out')
352
353
self.menubar.append_item('file/doc/save', self.on_save,
354
shortkey='Ctrl+s', info='save it out')
355
356
# self.menubar.append_menu('edit')
357
# self.menubar.append_item('edit/cut',self.cut,\
358
# shortkey='Ctrl+c',info='cut it out')
359
360
# self.menubar.append_item('edit/toggle',self.toggle_tools,\
361
# shortkey='Ctrl+t',info='toggle tools')
362
363
def add_view(self, name, ViewClass, **args):
364
"""
365
Add a new view to the notebook.
366
"""
367
# print 'context.add_view',ViewClass
368
# print ' args',args
369
370
view = self._splitter.add_view(name, ViewClass, **args)
371
self._views[name] = view
372
# self._viewtabs.SetSelection(p)
373
# self._splitter._viewtabs.Show(True)
374
return view
375
376
def select_view(self, ind=0, name=None):
377
self._splitter.select_view(ind=ind, name=name)
378
379
def on_size(self, event=None):
380
# print 'Mainframe.on_size'
381
# self.tc.SetSize(self.GetSize())
382
# self.tc.SetSize(self.GetSize())
383
# self._viewtabs.SetSize(self.GetSize())
384
# pass
385
#wx.LayoutAlgorithm().LayoutWindow(self, self.p1)
386
#wx.LayoutAlgorithm().LayoutWindow(self, self.p1)
387
388
# important:
389
#wx.LayoutAlgorithm().LayoutWindow(self, self._viewtabs)
390
wx.LayoutAlgorithm().LayoutWindow(self, self._splitter)
391
# if event:
392
# event.Skip()
393
394
def on_save(self, event):
395
print 'save it!!'
396
397
def on_open(self, event):
398
"""Open a document"""
399
#wildcards = CreateWildCards() + "All files (*.*)|*.*"
400
print 'open it!!'
401
402
def destroy(self):
403
"""Destroy this object"""
404
# self.theDocManager.theDestructor()
405
#imgPreferences.saveXml(self.GetStartDirectory() + "/" + imgINI_FILE_NAME)
406
##del self.thePrint
407
self.Destroy()
408
409
def on_close(self, event):
410
# self.Close(True)
411
print 'Mainframe.on_close'
412
# pass
413
self.destroy()
414
415
def on_exit(self, event):
416
"""Called when the application is to be finished"""
417
self.destroy()
418
419
def on_idle(self, event):
420
pass
421
#self.count = self.count + 1
422
# if self.count >= 100:
423
# self.count = 0
424
425
# self.statusbar.set_progress(self.count)
426
427
def on_about(self, event):
428
"""Display the information about this application"""
429
#dlg = imgDlgAbout(self, -1, "")
430
# dlg.ShowModal()
431
# dlg.Destroy()
432
pass
433
434
def write_to_statusbar(self, data, key='message'):
435
self.statusbar[key] = str(data)
436
437