source: sasview/src/sans/guiframe/gui_statusbar.py @ 1d4e2e7

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 1d4e2e7 was 1d4e2e7, checked in by Mathieu Doucet <doucetm@…>, 10 years ago

change useless button to color swatch

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