source: sasview/src/sans/guiframe/gui_statusbar.py @ caf8dd4

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

Tweak console button font

  • Property mode set to 100644
File size: 14.0 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.bitmap_bt_warning = wx.Button(self, wx.NewId(), "", 
136                                 size=(width, height), style=wx.NO_BORDER)
137        self.bitmap_bt_warning.SetBackgroundColour(GREEN)
138
139        # Create the button used to show the console dialog
140        self.console_button = wx.Button(self, wx.NewId(), "Console", 
141                                 size=(console_btn_width, 10),
142                                 style=wx.BU_EXACTFIT)
143        font = self.console_button.GetFont()
144        _, pixel_h = font.GetPixelSize()
145        font.SetPixelSize(wx.Size(0,int(pixel_h*0.9)))
146        self.console_button.SetFont(font)
147        self.console_button.SetToolTipString("History of status bar messages")
148        self.console_button.Bind(wx.EVT_BUTTON, self._onMonitor,
149                                id=self.console_button.GetId())
150       
151        self.reposition()
152        ## Current progress value of the bar
153        self.nb_start = 0
154        self.nb_progress = 0
155        self.nb_stop = 0
156        self.frame = None
157        self.list_msg = []
158        self.frame = Console(parent=self)
159        if hasattr(self.frame, "IsIconized"):
160            if not self.frame.IsIconized():
161                try:
162                    icon = self.parent.GetIcon()
163                    self.frame.SetIcon(icon)
164                except:
165                    try:
166                        FRAME_ICON = wx.Icon(GUIFRAME_ICON.FRAME_ICON_PATH,
167                                              wx.BITMAP_TYPE_ICON)
168                        self.frame.SetIcon(FRAME_ICON)
169                    except:
170                        pass
171        self.frame.set_multiple_messages(self.list_msg)
172        self.frame.Hide()
173        self.progress = 0
174        self.timer = wx.Timer(self, -1)
175        self.timer_stop = wx.Timer(self, -1)
176        self.thread = None
177        self.Bind(wx.EVT_TIMER, self._on_time, self.timer) 
178        self.Bind(wx.EVT_TIMER, self._on_time_stop, self.timer_stop) 
179        self.Bind(wx.EVT_SIZE, self.OnSize)
180        self.Bind(wx.EVT_IDLE, self.OnIdle)
181       
182    def reposition(self):
183        """
184            Place the various fields in their proper position
185        """
186        rect = self.GetFieldRect(GAUGE_POSITION)
187        self.gauge.SetPosition((rect.x, rect.y))
188        rect = self.GetFieldRect(ICON_POSITION)
189        self.bitmap_bt_warning.SetPosition((rect.x, rect.y))
190        rect = self.GetFieldRect(CONSOLE_POSITION)
191        self.console_button.SetPosition((rect.x, rect.y))
192        self.sizeChanged = False
193       
194    def OnIdle(self, event):
195        """
196        """
197        if self.sizeChanged:
198            self.reposition()
199           
200    def OnSize(self, evt):
201        """
202        """
203        self.reposition() 
204        self.sizeChanged = True
205       
206    def get_msg_position(self):
207        """
208        """
209        return self.msg_position
210   
211    def SetStatusText(self, text="", number=MSG_POSITION, event=None):
212        """
213        """
214        wxStatusB.SetStatusText(self, text, number)
215        self.list_msg.append(text)
216        self.bitmap_bt_warning.SetBackgroundColour(GREEN)
217
218        if self.frame is not None :
219            self.frame.set_message(status=text, event=event)
220       
221    def PopStatusText(self, *args, **kwds):
222        """
223        Override status bar
224        """
225        wxStatusB.PopStatusText(self, field=MSG_POSITION)
226       
227    def PushStatusText(self, *args, **kwds):
228        """
229        PushStatusText
230        """
231        text = "PushStatusText: What is this string?"
232        wxStatusB.PushStatusText(self, field=MSG_POSITION, string=text)
233       
234    def enable_clear_gauge(self):
235        """
236        clear the progress bar
237        """
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
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        """
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
284        """
285        if hasattr(event, "status"):
286            status = str(event.status)
287            if status.strip() == "":
288                return
289        else:
290            return
291        if not hasattr(event, "info"):
292            return 
293       
294        # Get the size of the button images
295        height = STATUS_BAR_ICON_SIZE
296       
297        msg = event.info.lower()
298        if msg == "warning":
299            self.bitmap_bt_warning.SetBackgroundColour(YELLOw)
300        elif msg == "error":
301            self.bitmap_bt_warning.SetBackgroundColour(RED)
302        else:
303            self.bitmap_bt_warning.SetBackgroundColour(GREEN)
304   
305    def set_dialog(self, event):
306        """
307        Display dialogbox
308        """
309        if not hasattr(event, "info"):
310            return 
311        msg = event.info.lower()
312        if msg == "error":
313            e_msg = "Error(s) Occurred:\n"
314            e_msg += event.status
315            wx.MessageBox(e_msg, style=wx.ICON_ERROR)
316
317    def set_message(self, event):
318        """
319        display received message on the statusbar
320        """
321        if hasattr(event, "status"):
322            self.SetStatusText(text=str(event.status), event=event)
323       
324    def set_gauge(self, event):
325        """
326        change the state of the gauge according the state of the current job
327        """
328        if not hasattr(event, "type"):
329            return
330        type = event.type
331        self.gauge.Show(True)
332        if type.lower() == "start":
333            self.nb_start += 1
334            #self.timer.Stop()
335            self.progress += 5
336            self.gauge.SetValue(int(self.progress)) 
337            self.progress += 5
338            if self.progress < self.gauge.GetRange() - 20:
339                self.gauge.SetValue(int(self.progress)) 
340        if type.lower() == "progress":
341            self.nb_progress += 1
342            self.timer.Start(1)
343            self.gauge.Pulse()
344        if type.lower() == "update":
345            self.progress += 5
346            if self.progress < self.gauge.GetRange()- 20:
347                self.gauge.SetValue(int(self.progress))   
348        if type.lower() == "stop":
349            self.nb_stop += 1
350            self.gauge.Show(True)
351            if self.enable_clear_gauge():
352                self.timer.Stop()
353                self.progress = 0
354                self.gauge.SetValue(100) 
355                self.timer_stop.Start(5) 
356                   
357    def set_status(self, event):
358        """
359        Update the status bar .
360       
361        :param type: type of message send.
362            type  must be in ["start","progress","update","stop"]
363        :param msg: the message itself  as string
364        :param thread: if updatting using a thread status
365       
366        """
367        self.set_message(event=event)
368        self.set_icon(event=event)
369        self.set_gauge(event=event)
370        # dialog on error
371        self.set_dialog(event=event)
372       
373    def _onMonitor(self, event):
374        """
375        Pop up a frame with messages sent to the status bar
376        """
377        self.frame.Show(False)
378        self.frame.Show(True)
379       
380       
381class SPageStatusbar(wxStatusB):
382    def __init__(self, parent, timeout=None, *args, **kwds):
383        wxStatusB.__init__(self, parent, *args, **kwds)
384        self.SetFieldsCount(1) 
385        self.timeout = timeout
386        width, height = parent.GetSizeTuple()
387        self.gauge = wx.Gauge(self, style=wx.GA_HORIZONTAL, 
388                              size=(width, height/10))
389        rect = self.GetFieldRect(0)
390        self.gauge.SetPosition((rect.x , rect.y ))
391        if self.timeout is not None:
392            self.gauge.SetRange(int(self.timeout))
393        self.timer = wx.Timer(self, -1) 
394        self.Bind(wx.EVT_TIMER, self._on_time, self.timer) 
395        self.timer.Start(1)
396        self.pos = 0
397       
398    def _on_time(self, evt): 
399        """
400        Update the progress bar while the timer is running
401       
402        :param evt: wx.EVT_TIMER
403 
404        """ 
405        # Check stop flag that can be set from non main thread
406        if self.timeout is None and self.timer.IsRunning(): 
407            self.gauge.Pulse()
408           
409       
410if __name__ == "__main__":
411    app = wx.PySimpleApp()
412    frame = wx.Frame(None, wx.ID_ANY, 'test frame')
413    #statusBar = StatusBar(frame, wx.ID_ANY)
414    statusBar = SPageStatusbar(frame)
415    frame.SetStatusBar(statusBar)
416    frame.Show(True)
417    #event = MessageEvent()
418    #event.type = "progress"
419    #event.status  = "statusbar...."
420    #event.info = "error"
421    #statusBar.set_status(event=event)
422    app.MainLoop()
423
Note: See TracBrowser for help on using the repository browser.