source: sasview/sansguiframe/src/sans/guiframe/gui_statusbar.py @ 6184b4e

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 6184b4e was 6184b4e, checked in by Mathieu Doucet <doucetm@…>, 12 years ago

Tweak status bar

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