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

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 c09ace41 was 96683dc, checked in by Jae Cho <jhjcho@…>, 13 years ago

better refresh of console on show

  • Property mode set to 100644
File size: 13.1 KB
RevLine 
[010c251]1import wx
2from wx import StatusBar as wxStatusB
3from wx.lib import newevent
[2d98490]4import wx.richtext
[a195ac9]5import time
[07dd0b4]6from sans.guiframe.gui_style import GUIFRAME_ICON
[010c251]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
[2d98490]16CONSOLE_WIDTH = 500
17CONSOLE_HEIGHT = 300
[010c251]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)
[2d98490]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       
[010c251]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       
[2d98490]38    def set_message(self, status="", event=None):
[010c251]39        """
40        """
[2d98490]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           
[010c251]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)
[bfa73ca]78        wx.EVT_CLOSE(self, self.Close)
[783940c]79       
[010c251]80       
81    def set_multiple_messages(self, messages=[]):
82        """
83        """
84        if messages:
85            for status in messages:
[2d98490]86                self.panel.set_message(status=status)
[010c251]87               
[2d98490]88    def set_message(self, status, event=None):
[bfa73ca]89        """
90        """
[2d98490]91        self.panel.set_message(status=str(status), event=event)
[bfa73ca]92       
93    def Close(self, event):
[010c251]94        """
95        """
[bfa73ca]96        self.Hide()
[010c251]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)
[5f15492]122        console_bmp = wx.ArtProvider.GetBitmap(wx.ART_TIP, wx.ART_TOOLBAR,
123                                                size = (16,16))
[010c251]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())
[bfa73ca]131       
[010c251]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 = []
[bfa73ca]139        self.frame = Console(parent=self)
[07dd0b4]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
[bfa73ca]152        self.frame.set_multiple_messages(self.list_msg)
153        self.frame.Hide()
[010c251]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 - 2))
168        rect = self.GetFieldRect(ICON_POSITION)
169        self.bitmap_bt_warning.SetPosition((rect.x + 5, rect.y - 2))
170        rect = self.GetFieldRect(CONSOLE_POSITION)
171        self.bitmap_bt_console.SetPosition((rect.x - 5, rect.y - 2))
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   
[2d98490]191    def SetStatusText(self, text="", number=MSG_POSITION, event=None):
[010c251]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)
[bfa73ca]198     
199        if self.frame is not None :
[2d98490]200            self.frame.set_message(status=text, event=event)
[bfa73ca]201       
[010c251]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        """
[2d98490]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
[010c251]262        """
[2d98490]263        if hasattr(event, "status"):
[07dd0b4]264            status = str(event.status)
[2d98490]265            if status.strip() == "":
266                return
267        else:
268            return
[010c251]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"):
[2d98490]288            self.SetStatusText(text=str(event.status), event=event)
[bfa73ca]289       
290 
[010c251]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        """
[96683dc]342        self.frame.Show(False)
[010c251]343        self.frame.Show(True)
344       
345       
[7a955a9]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        self.gauge = wx.Gauge(self,style=wx.GA_HORIZONTAL, size=parent.GetSize())
352        rect = self.GetFieldRect(0)
353        self.gauge.SetPosition((rect.x , rect.y ))
354        if self.timeout is not None:
355            self.gauge.SetRange(int(self.timeout))
356        self.timer = wx.Timer(self, -1) 
357        self.Bind(wx.EVT_TIMER, self._on_time, self.timer) 
358        self.timer.Start(1)
359        self.pos = 0
360       
361    def _on_time(self, evt): 
362        """
363        Update the progress bar while the timer is running
364       
365        :param evt: wx.EVT_TIMER
366 
367        """ 
368        # Check stop flag that can be set from non main thread
369        if self.timeout is None and self.timer.IsRunning(): 
370            self.gauge.Pulse()
371           
372       
[010c251]373if __name__ == "__main__":
374    app = wx.PySimpleApp()
375    frame = wx.Frame(None, wx.ID_ANY, 'test frame')
[7a955a9]376    #statusBar = StatusBar(frame, wx.ID_ANY)
377    statusBar = SPageStatusbar(frame)
[010c251]378    frame.SetStatusBar(statusBar)
379    frame.Show(True)
[7a955a9]380    #event = MessageEvent()
381    #event.type = "progress"
382    #event.status  = "statusbar...."
383    #event.info = "error"
384    #statusBar.set_status(event=event)
[010c251]385    app.MainLoop()
386
Note: See TracBrowser for help on using the repository browser.