source: sasview/src/sas/guiframe/gui_statusbar.py @ 9701348

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 9701348 was 79492222, checked in by krzywon, 10 years ago

Changed the file and folder names to remove all SANS references.

  • Property mode set to 100644
File size: 14.1 KB
RevLine 
[010c251]1import wx
[804a7db]2import sys
[010c251]3from wx import StatusBar as wxStatusB
4from wx.lib import newevent
[2d98490]5import wx.richtext
[79492222]6from sas.guiframe.gui_style import GUIFRAME_ICON
[caf273b]7
8# Number of fields on the status bar
[010c251]9NB_FIELDS = 4
10#position of the status bar's fields
11ICON_POSITION = 0
12MSG_POSITION  = 1
13GAUGE_POSITION  = 2
14CONSOLE_POSITION  = 3
15BUTTON_SIZE = 40
[caf273b]16STATUS_BAR_ICON_SIZE = 12
[2d98490]17CONSOLE_WIDTH = 500
[199fdec]18CONSOLE_HEIGHT = 300
[804a7db]19if sys.platform.count("win32") > 0:
20    FONT_VARIANT = 0
21else:
22    FONT_VARIANT = 1
[010c251]23
[b50b057]24GREEN = wx.Colour(95, 190, 95)
25YELLOW = wx.Colour(247, 214, 49)
26RED = wx.Colour(234, 89, 78)
27
[010c251]28class ConsolePanel(wx.Panel):
29    """
30    """
31    def __init__(self, parent, *args, **kwargs):
32        """
33        """
34        wx.Panel.__init__(self, parent=parent, *args, **kwargs)
35        self.parent = parent
36        self.sizer = wx.BoxSizer(wx.VERTICAL)
[2d98490]37       
38        self.msg_txt = wx.richtext.RichTextCtrl(self, size=(CONSOLE_WIDTH-40,
39                                                CONSOLE_HEIGHT-60),
40                                   style=wx.VSCROLL|wx.HSCROLL|wx.NO_BORDER)
41       
[010c251]42        self.msg_txt.SetEditable(False)
43        self.msg_txt.SetValue('No message available')
44        self.sizer.Add(self.msg_txt, 1, wx.EXPAND|wx.ALL, 10)
45        self.SetSizer(self.sizer)
46       
[2d98490]47    def set_message(self, status="", event=None):
[010c251]48        """
49        """
[2d98490]50        status = str(status)
51        if status.strip() == "":
52            return
53        color = (0, 0, 0) #black
54        icon_bmp =  wx.ArtProvider.GetBitmap(wx.ART_INFORMATION,
[caf273b]55                                             wx.ART_TOOLBAR)
[2d98490]56        if hasattr(event, "info"):
57            icon_type = event.info.lower()
58            if icon_type == "warning":
59                color = (0, 0, 255) # blue
60                icon_bmp =  wx.ArtProvider.GetBitmap(wx.ART_WARNING,
[caf273b]61                                                     wx.ART_TOOLBAR)
[2d98490]62            if icon_type == "error":
63                color = (255, 0, 0) # red
64                icon_bmp =  wx.ArtProvider.GetBitmap(wx.ART_ERROR, 
65                                                     wx.ART_TOOLBAR)
66            if icon_type == "info":
67                icon_bmp =  wx.ArtProvider.GetBitmap(wx.ART_INFORMATION,
68                                                     wx.ART_TOOLBAR)
69        self.msg_txt.Newline()
70        self.msg_txt.WriteBitmap(icon_bmp)
71        self.msg_txt.BeginTextColour(color)
72        self.msg_txt.WriteText("\t")
73        self.msg_txt.AppendText(status)
74        self.msg_txt.EndTextColour()
75       
[010c251]76       
77class Console(wx.Frame):
78    """
79    """
80    def __init__(self, parent=None, status="", *args, **kwds):
81        kwds["size"] = (CONSOLE_WIDTH, CONSOLE_HEIGHT)
82        kwds["title"] = "Console"
83        wx.Frame.__init__(self, parent=parent, *args, **kwds)
[804a7db]84        self.SetWindowVariant(FONT_VARIANT)
[010c251]85        self.panel = ConsolePanel(self)
86        self.panel.set_message(status=status)
[bfa73ca]87        wx.EVT_CLOSE(self, self.Close)
[783940c]88       
[010c251]89    def set_multiple_messages(self, messages=[]):
90        """
91        """
92        if messages:
93            for status in messages:
[2d98490]94                self.panel.set_message(status=status)
[010c251]95               
[2d98490]96    def set_message(self, status, event=None):
[bfa73ca]97        """
98        """
[2d98490]99        self.panel.set_message(status=str(status), event=event)
[bfa73ca]100       
101    def Close(self, event):
[010c251]102        """
103        """
[bfa73ca]104        self.Hide()
[010c251]105       
106class StatusBar(wxStatusB):
107    """
[6e4d543]108        Application status bar
[010c251]109    """
[6e4d543]110    def __init__(self, parent, id):
111        wxStatusB.__init__(self, parent, id)
[010c251]112        self.parent = parent
113        self.parent.SetStatusBarPane(MSG_POSITION)
[6e4d543]114
[010c251]115        #Layout of status bar
[caf273b]116        width = STATUS_BAR_ICON_SIZE
117        height = STATUS_BAR_ICON_SIZE
[010c251]118        self.SetFieldsCount(NB_FIELDS) 
[6e4d543]119        # Leave some space for the resize handle in the last field
[beda555]120        console_btn_width = 80
121        self.SetStatusWidths([width+4, -2, -1, width+console_btn_width])
[b716dd8]122        self.SetMinHeight(height)
[6e4d543]123       
[010c251]124        #display default message
125        self.msg_position = MSG_POSITION
[6e4d543]126       
127        # Create progress bar
[804a7db]128        gauge_width = 5 * width
129        self.gauge = wx.Gauge(self, size=(gauge_width, height),
[010c251]130                               style=wx.GA_HORIZONTAL)
131        self.gauge.Hide()
[6e4d543]132       
133        # Create status bar icon reflecting the type of status
134        # for the last message
[8001331]135        self.status_color = wx.StaticText(self, id=wx.NewId(), label="   ", size=wx.Size(15,15))
[1d4e2e7]136        self.status_color.SetBackgroundColour(GREEN)
[7e44299]137        self.status_color.SetForegroundColour(GREEN)
[beda555]138
[6e4d543]139        # Create the button used to show the console dialog
[b50b057]140        self.console_button = wx.Button(self, wx.NewId(), "Console", 
[f330d67]141                                 size=(console_btn_width, -1))
[b50b057]142        font = self.console_button.GetFont()
[caf8dd4]143        _, pixel_h = font.GetPixelSize()
144        font.SetPixelSize(wx.Size(0,int(pixel_h*0.9)))
[b50b057]145        self.console_button.SetFont(font)
146        self.console_button.SetToolTipString("History of status bar messages")
147        self.console_button.Bind(wx.EVT_BUTTON, self._onMonitor,
148                                id=self.console_button.GetId())
[bfa73ca]149       
[010c251]150        self.reposition()
151        ## Current progress value of the bar
152        self.nb_start = 0
153        self.nb_progress = 0
154        self.nb_stop = 0
155        self.frame = None
156        self.list_msg = []
[bfa73ca]157        self.frame = Console(parent=self)
[07dd0b4]158        if hasattr(self.frame, "IsIconized"):
159            if not self.frame.IsIconized():
160                try:
161                    icon = self.parent.GetIcon()
162                    self.frame.SetIcon(icon)
163                except:
164                    try:
165                        FRAME_ICON = wx.Icon(GUIFRAME_ICON.FRAME_ICON_PATH,
166                                              wx.BITMAP_TYPE_ICON)
167                        self.frame.SetIcon(FRAME_ICON)
168                    except:
169                        pass
[bfa73ca]170        self.frame.set_multiple_messages(self.list_msg)
171        self.frame.Hide()
[caf273b]172        self.progress = 0
173        self.timer = wx.Timer(self, -1)
174        self.timer_stop = wx.Timer(self, -1)
[010c251]175        self.thread = None
176        self.Bind(wx.EVT_TIMER, self._on_time, self.timer) 
177        self.Bind(wx.EVT_TIMER, self._on_time_stop, self.timer_stop) 
178        self.Bind(wx.EVT_SIZE, self.OnSize)
179        self.Bind(wx.EVT_IDLE, self.OnIdle)
180       
181    def reposition(self):
182        """
[b716dd8]183            Place the various fields in their proper position
[010c251]184        """
185        rect = self.GetFieldRect(GAUGE_POSITION)
[6e4d543]186        self.gauge.SetPosition((rect.x, rect.y))
[010c251]187        rect = self.GetFieldRect(ICON_POSITION)
[1d4e2e7]188        self.status_color.SetPosition((rect.x, rect.y))
[010c251]189        rect = self.GetFieldRect(CONSOLE_POSITION)
[b50b057]190        self.console_button.SetPosition((rect.x, rect.y))
[010c251]191        self.sizeChanged = False
192       
193    def OnIdle(self, event):
194        """
195        """
196        if self.sizeChanged:
197            self.reposition()
198           
199    def OnSize(self, evt):
200        """
201        """
202        self.reposition() 
203        self.sizeChanged = True
204       
205    def get_msg_position(self):
206        """
207        """
208        return self.msg_position
209   
[2d98490]210    def SetStatusText(self, text="", number=MSG_POSITION, event=None):
[010c251]211        """
212        """
[0e29289]213        wxStatusB.SetStatusText(self, text.split('\n',1)[0], number)
[010c251]214        self.list_msg.append(text)
[1d4e2e7]215        self.status_color.SetBackgroundColour(GREEN)
[7e44299]216        self.status_color.SetForegroundColour(GREEN)
[caf273b]217
[bfa73ca]218        if self.frame is not None :
[2d98490]219            self.frame.set_message(status=text, event=event)
[bfa73ca]220       
[010c251]221    def PopStatusText(self, *args, **kwds):
222        """
223        Override status bar
224        """
225        wxStatusB.PopStatusText(self, field=MSG_POSITION)
[986da97]226       
[010c251]227    def PushStatusText(self, *args, **kwds):
228        """
[3fc01c5]229        PushStatusText
[010c251]230        """
[3fc01c5]231        text = "PushStatusText: What is this string?"
232        wxStatusB.PushStatusText(self, field=MSG_POSITION, string=text)
[010c251]233       
234    def enable_clear_gauge(self):
235        """
236        clear the progress bar
237        """
[940aca7]238        flag = True
239        # Why we do this?
240        #if (self.nb_start <= self.nb_stop) or \
241        #    (self.nb_progress <= self.nb_stop):
242        #    flag = True
[010c251]243        return flag
244   
245    def _on_time_stop(self, evt): 
246        """
247        Clear the progress bar
248       
249        :param evt: wx.EVT_TIMER
250 
251        """ 
252        count = 0
253        while(count <= 100):
254            count += 1
255        self.timer_stop.Stop() 
256        self.clear_gauge(msg="")
257        self.nb_progress = 0 
258        self.nb_start = 0 
259        self.nb_stop = 0
260       
261    def _on_time(self, evt): 
262        """
263        Update the progress bar while the timer is running
264       
265        :param evt: wx.EVT_TIMER
266 
267        """ 
268        # Check stop flag that can be set from non main thread
269        if self.timer.IsRunning(): 
270            self.gauge.Pulse()
271   
272    def clear_gauge(self, msg=""):
273        """
274        Hide the gauge
275        """
276        self.progress = 0
277        self.gauge.SetValue(0)
278        self.gauge.Hide() 
279         
280    def set_icon(self, event):
281        """
[2d98490]282        Display icons related to the type of message sent to the statusbar
283        when available. No icon is displayed if the message is empty
[010c251]284        """
[2d98490]285        if hasattr(event, "status"):
[07dd0b4]286            status = str(event.status)
[2d98490]287            if status.strip() == "":
288                return
289        else:
290            return
[010c251]291        if not hasattr(event, "info"):
292            return 
[6e4d543]293       
[b716dd8]294        # Get the size of the button images
[caf273b]295        height = STATUS_BAR_ICON_SIZE
[6e4d543]296       
[010c251]297        msg = event.info.lower()
298        if msg == "warning":
[1d4e2e7]299            self.status_color.SetBackgroundColour(YELLOW)
[7e44299]300            self.status_color.SetForegroundColour(YELLOW)
[6e4d543]301        elif msg == "error":
[1d4e2e7]302            self.status_color.SetBackgroundColour(RED)
[7e44299]303            self.status_color.SetForegroundColour(RED)
[6e4d543]304        else:
[1d4e2e7]305            self.status_color.SetBackgroundColour(GREEN)
[7e44299]306            self.status_color.SetForegroundColour(GREEN)
[010c251]307   
[7d89e50]308    def set_dialog(self, event):
309        """
310        Display dialogbox
311        """
312        if not hasattr(event, "info"):
313            return 
314        msg = event.info.lower()
315        if msg == "error":
316            e_msg = "Error(s) Occurred:\n"
317            e_msg += event.status
318            wx.MessageBox(e_msg, style=wx.ICON_ERROR)
319
[010c251]320    def set_message(self, event):
321        """
322        display received message on the statusbar
323        """
324        if hasattr(event, "status"):
[2d98490]325            self.SetStatusText(text=str(event.status), event=event)
[bfa73ca]326       
[010c251]327    def set_gauge(self, event):
328        """
329        change the state of the gauge according the state of the current job
330        """
331        if not hasattr(event, "type"):
332            return
333        type = event.type
334        self.gauge.Show(True)
335        if type.lower() == "start":
336            self.nb_start += 1
337            #self.timer.Stop()
[804a7db]338            self.progress += 5
[010c251]339            self.gauge.SetValue(int(self.progress)) 
[804a7db]340            self.progress += 5
[010c251]341            if self.progress < self.gauge.GetRange() - 20:
342                self.gauge.SetValue(int(self.progress)) 
343        if type.lower() == "progress":
344            self.nb_progress += 1
345            self.timer.Start(1)
346            self.gauge.Pulse()
347        if type.lower() == "update":
[804a7db]348            self.progress += 5
[010c251]349            if self.progress < self.gauge.GetRange()- 20:
350                self.gauge.SetValue(int(self.progress))   
351        if type.lower() == "stop":
352            self.nb_stop += 1
353            self.gauge.Show(True)
354            if self.enable_clear_gauge():
355                self.timer.Stop()
356                self.progress = 0
[3c965fd]357                self.gauge.SetValue(100) 
[804a7db]358                self.timer_stop.Start(5) 
[010c251]359                   
360    def set_status(self, event):
361        """
362        Update the status bar .
363       
364        :param type: type of message send.
365            type  must be in ["start","progress","update","stop"]
366        :param msg: the message itself  as string
367        :param thread: if updatting using a thread status
368       
369        """
370        self.set_message(event=event)
371        self.set_icon(event=event)
372        self.set_gauge(event=event)
[7d89e50]373        # dialog on error
374        self.set_dialog(event=event)
375       
[010c251]376    def _onMonitor(self, event):
377        """
378        Pop up a frame with messages sent to the status bar
379        """
[96683dc]380        self.frame.Show(False)
[010c251]381        self.frame.Show(True)
382       
383       
[7a955a9]384class SPageStatusbar(wxStatusB):
385    def __init__(self, parent, timeout=None, *args, **kwds):
386        wxStatusB.__init__(self, parent, *args, **kwds)
387        self.SetFieldsCount(1) 
388        self.timeout = timeout
[43cc1ad2]389        width, height = parent.GetSizeTuple()
390        self.gauge = wx.Gauge(self, style=wx.GA_HORIZONTAL, 
391                              size=(width, height/10))
[7a955a9]392        rect = self.GetFieldRect(0)
393        self.gauge.SetPosition((rect.x , rect.y ))
394        if self.timeout is not None:
395            self.gauge.SetRange(int(self.timeout))
396        self.timer = wx.Timer(self, -1) 
397        self.Bind(wx.EVT_TIMER, self._on_time, self.timer) 
398        self.timer.Start(1)
399        self.pos = 0
400       
401    def _on_time(self, evt): 
402        """
403        Update the progress bar while the timer is running
404       
405        :param evt: wx.EVT_TIMER
406 
407        """ 
408        # Check stop flag that can be set from non main thread
409        if self.timeout is None and self.timer.IsRunning(): 
410            self.gauge.Pulse()
411           
412       
[010c251]413if __name__ == "__main__":
414    app = wx.PySimpleApp()
415    frame = wx.Frame(None, wx.ID_ANY, 'test frame')
[7a955a9]416    #statusBar = StatusBar(frame, wx.ID_ANY)
417    statusBar = SPageStatusbar(frame)
[010c251]418    frame.SetStatusBar(statusBar)
419    frame.Show(True)
[7a955a9]420    #event = MessageEvent()
421    #event.type = "progress"
422    #event.status  = "statusbar...."
423    #event.info = "error"
424    #statusBar.set_status(event=event)
[010c251]425    app.MainLoop()
426
Note: See TracBrowser for help on using the repository browser.