Package gui
[hide private]
[frames] | no frames]

Source Code for Package gui

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2009-2012,2022 Edward d'Auvergne                              # 
  4  #                                                                             # 
  5  # This file is part of the program relax (http://www.nmr-relax.com).          # 
  6  #                                                                             # 
  7  # This program is free software: you can redistribute it and/or modify        # 
  8  # it under the terms of the GNU General Public License as published by        # 
  9  # the Free Software Foundation, either version 3 of the License, or           # 
 10  # (at your option) any later version.                                         # 
 11  #                                                                             # 
 12  # This program is distributed in the hope that it will be useful,             # 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 15  # GNU General Public License for more details.                                # 
 16  #                                                                             # 
 17  # You should have received a copy of the GNU General Public License           # 
 18  # along with this program.  If not, see <http://www.gnu.org/licenses/>.       # 
 19  #                                                                             # 
 20  ############################################################################### 
 21   
 22  # Package docstring. 
 23  """Package for the Bieri GUI interface for relax. 
 24   
 25  This GUI was announced in the post at U{https://web.archive.org/web/https://mail.gna.org/public/relax-devel/2009-11/msg00005.html}. 
 26  """ 
 27   
 28  # Deps. 
 29  import dep_check 
 30   
 31  # Python module imports. 
 32  import sys 
 33  from time import sleep 
 34  if dep_check.wx_module: 
 35      import wx 
 36      if not dep_check.wx_classic: 
 37          import wx.adv 
 38   
 39  # relax module imports. 
 40  from graphics import IMAGE_PATH 
 41  from gui.uf_objects import Uf_storage; uf_store = Uf_storage() 
 42  from lib.errors import RelaxError 
 43  import pipe_control 
 44  from status import Status; status = Status() 
 45   
 46   
 47  __all__ = ['about', 
 48             'base_classes', 
 49             'controller', 
 50             'derived_wx_classes', 
 51             'errors', 
 52             'filedialog', 
 53             'fonts', 
 54             'icons', 
 55             'interpreter', 
 56             'menu', 
 57             'message', 
 58             'misc', 
 59             'paths', 
 60             'pipe_editor', 
 61             'references', 
 62             'relax_gui', 
 63             'relax_prompt', 
 64             'settings', 
 65             'wizard'] 
 66   
 67   
 68  # Size for the splash screen. 
 69  SPLASH_SIZE = (640, 460) 
 70   
 71   
 72   
73 -class App(wx.App):
74 """The relax GUI wx application.""" 75
76 - def __init__(self, script_file=None, redirect=False, filename=None, useBestVisual=False, clearSigInt=True):
77 """Initialise the wx.App. 78 79 @keyword redirect: Should sys.stdout and sys.stderr be redirected? Defaults to True on Windows and Mac, False otherwise. If filename is None then output will be redirected to a window that pops up as needed. (You can control what kind of window is created for the output by resetting the class variable outputWindowClass to a class of your choosing.) 80 @type redirect: bool 81 @keyword filename: The name of a file to redirect output to, if redirect is True. 82 @type filename: file object 83 @keyword useBestVisual: Should the app try to use the best available visual provided by the system (only relevant on systems that have more than one visual.) This parameter must be used instead of calling SetUseBestVisual later on because it must be set before the underlying GUI toolkit is initialized. 84 @type useBestVisual: bool 85 @keyword clearSigInt: Should SIGINT be cleared? This allows the app to terminate upon a Ctrl-C in the console like other GUI apps will. 86 @type clearSigInt: bool 87 @keyword script_file: The path of a relax script to execute. 88 @type script_file: str 89 """ 90 91 # First run the script before the GUI is built. 92 if script_file: 93 pipe_control.script.script(script_file) 94 95 # Execute the base class method. 96 super(App, self).__init__(redirect=redirect, filename=filename, useBestVisual=useBestVisual, clearSigInt=clearSigInt)
97 98
99 - def OnInit(self):
100 """Build the application, showing a splash screen first.""" 101 102 # Import here to break a circular import which is killing Epydoc! 103 from gui import relax_gui 104 105 # Build the GUI. 106 self.gui = relax_gui.Main(parent=None, id=-1, title="") 107 108 # Make it the main application component. 109 self.SetTopWindow(self.gui) 110 111 # Only show the GUI if requested. 112 if status.show_gui: 113 # Wait a little while :) 114 sleep(1) 115 116 # Show it. 117 self.gui.Show() 118 119 # Show the splash screen. 120 splash = RelaxSplash(self.gui) 121 splash.CenterOnScreen(wx.BOTH) 122 123 # All is good! 124 return True
125 126 127
128 -class RelaxSplash(wx.Frame):
129 """A special splash screen for the relax GUI.""" 130
131 - def __init__(self, parent):
132 """Set up the splash screen.""" 133 134 # Set up the frame. 135 super(RelaxSplash, self).__init__(parent=parent, id=-1, title="RelaxSplash", size=SPLASH_SIZE, style=wx.FRAME_SHAPED | wx.BORDER_NONE | wx.FRAME_NO_TASKBAR | wx.STAY_ON_TOP) 136 self.SetBackgroundColour("white") 137 138 self.Show(True) 139 140 # Start the timer. 141 self.timer = wx.Timer(self) 142 self.timer.Start(4000) 143 self.Bind(wx.EVT_TIMER, self.handler_timer, self.timer) 144 145 # Set up the foreground and background panels. 146 panel_bg = RelaxBackgroundPanel(self) 147 panel_fg = RelaxForegroundPanel(self) 148 149 # Main sizer. 150 main_sizer = wx.BoxSizer(wx.VERTICAL) 151 main_sizer.Add(panel_bg, 1, wx.EXPAND, 20) 152 main_sizer.Add(panel_fg, 1, wx.EXPAND, 20) 153 self.SetSizer(main_sizer) 154 155 # Set the cursor as busy. 156 wx.BeginBusyCursor() 157 158 # Bind events. 159 self.Bind(wx.EVT_LEFT_DOWN, self.mouse_events) 160 self.Bind(wx.EVT_MIDDLE_DOWN, self.mouse_events) 161 self.Bind(wx.EVT_RIGHT_DOWN, self.mouse_events)
162 163
164 - def Destroy(self, event):
165 """Override the class method.""" 166 167 # Stop the busy cursor. 168 wx.CallAfter(wx.EndBusyCursor) 169 170 # Stop the timer. 171 self.timer.Stop() 172 173 # Destroy the splash window. 174 super(RelaxSplash, self).Destroy()
175 176
177 - def handler_timer(self, event):
178 """Close the splash screen.""" 179 180 self.Destroy(event)
181 182
183 - def mouse_events(self, event):
184 """Close the splash on mouse button clicks.""" 185 186 self.Destroy(event) 187 event.Skip()
188 189 190
191 -class RelaxBackgroundPanel(wx.Panel):
192 """Custom panel for the animation part of the splash screen.""" 193
194 - def __init__(self, parent=None):
195 """Set up the custom panel.""" 196 197 # Initialise the parent. 198 wx.Panel.__init__(self, parent, -1) 199 self.parent = parent 200 201 # Animation. 202 self.gif = wx.adv.Animation(IMAGE_PATH+'movie_mode1_relax.gif') 203 ani_ctrl = wx.adv.AnimationCtrl(self, id=-1, anim=self.gif, size=(480,428)) 204 ani_ctrl.Play() 205 206 # Layout. 207 sizer = wx.BoxSizer(wx.HORIZONTAL) 208 sizer2 = wx.BoxSizer(wx.VERTICAL) 209 sizer.AddSpacer(10) 210 sizer2.AddSpacer(20) 211 sizer2.Add(ani_ctrl) 212 sizer.Add(sizer2) 213 self.SetSizerAndFit(sizer) 214 self.Show()
215 216 217
218 -class RelaxForegroundPanel(wx.Panel):
219 """Custom panel for the bitmap part of the splash screen.""" 220
221 - def __init__(self, parent=None):
222 """Set up the custom panel.""" 223 224 # Initialise the parent. 225 wx.Panel.__init__(self, parent, -1, style=wx.TRANSPARENT_WINDOW) 226 self.parent = parent 227 228 # Background image. 229 bmp = wx.Bitmap(IMAGE_PATH+'relaxGUI_splash.png', wx.BITMAP_TYPE_ANY) 230 image = wx.StaticBitmap(self, -1, bmp) 231 232 # Layout. 233 sizer = wx.BoxSizer(wx.VERTICAL) 234 sizer.Add(image) 235 self.SetSizerAndFit(sizer) 236 237 # Send mouse clicks to the parent. 238 image.Bind(wx.EVT_MOUSE_EVENTS, self.mouse_events)
239 240
241 - def mouse_events(self, event):
242 """Send all mouse events to the parent.""" 243 244 wx.PostEvent(self.parent, event) 245 event.Skip()
246