1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
"""
@package gui_core.infobar
@brief Wrapper around wx.InfoBar
Classes:
- gui_core::InfoBar
(C) 2020 by the GRASS Development Team
This program is free software under the GNU General Public License
(>=v2). Read the file COPYING that comes with GRASS for details.
@author Linda Kladivova
@author Anna Petrasova <kratochanna gmail.com>
@author Vaclav Petras <wenzeslaus gmail.com>
"""
import sys
import wx
import wx.aui
try:
import wx.lib.agw.infobar as IB
except ImportError:
import wx.lib.infobar as IB
def GetCloseButtonBitmap(win, size, colBg, flags=0):
"""Workaround for missing DrawTitleBarBitmap method
of wx.RendererNative in certain wx versions.
See https://github.com/wxWidgets/Phoenix/issues/1425."""
renderer = wx.RendererNative.Get()
if hasattr(renderer, "DrawTitleBarBitmap"):
bmp = wx.Bitmap(*size)
dc = wx.MemoryDC()
dc.SelectObject(bmp)
dc.SetBackground(wx.Brush(colBg))
dc.Clear()
wx.RendererNative.Get().DrawTitleBarBitmap(
win, dc, wx.Rect(size), wx.TITLEBAR_BUTTON_CLOSE, flags
)
dc.SelectObject(wx.NullBitmap)
else:
bmp = wx.ArtProvider.GetBitmap(wx.ART_CLOSE, wx.ART_BUTTON)
return bmp
IB.GetCloseButtonBitmap = GetCloseButtonBitmap
class InfoBar(IB.InfoBar):
"""A customized and specialized info bar to used by default"""
def __init__(self, parent):
IB.InfoBar.__init__(self, parent)
self.button_ids = []
# color according to OS
if sys.platform == "win32":
bgcolor = wx.SYS_COLOUR_INFOBK
fgcolor = wx.SYS_COLOUR_INFOTEXT
else:
bgcolor = wx.SYS_COLOUR_HIGHLIGHT
fgcolor = wx.SYS_COLOUR_HIGHLIGHTTEXT
# set background and foreground color and remove alpha
self._background_color = wx.SystemSettings.GetColour(bgcolor).Get(False)
self._foreground_color = wx.SystemSettings.GetColour(fgcolor).Get(False)
self.SetBackgroundColour(self._background_color)
self.SetForegroundColour(self._foreground_color)
self._text.SetBackgroundColour(self._background_color)
self._text.SetForegroundColour(self._foreground_color)
self._button.SetBackgroundColour(self._background_color)
# layout
self._unInitLayout()
sizer = wx.BoxSizer(wx.VERTICAL)
subSizerText = wx.BoxSizer(wx.HORIZONTAL)
self.subSizerButtons = wx.BoxSizer(wx.HORIZONTAL)
subSizerText.Add(self._icon, wx.SizerFlags().Centre().Border())
subSizerText.Add(self._text, 1, wx.ALIGN_CENTER_VERTICAL)
self.subSizerButtons.AddStretchSpacer()
self.subSizerButtons.Add(self._button, wx.SizerFlags().Centre().Border())
sizer.Add(subSizerText, wx.SizerFlags().Expand())
sizer.Add(self.subSizerButtons, wx.SizerFlags().Expand())
self.SetSizer(sizer)
def _unInitLayout(self):
sizer = self.GetSizer()
children = sizer.GetChildren()
for i in reversed(range(len(children))):
if children[i].IsSpacer():
sizer.Remove(i)
else:
sizer.Detach(i)
def ShowMessage(self, message, icon, buttons=None):
"""Show message with buttons (optional).
Buttons are list of tuples (label, handler)"""
self.Hide()
self.RemoveButtons()
if buttons:
self.SetButtons(buttons)
super().ShowMessage(message, icon)
def AddButton(self, btnid, label):
"""
Adds a button to be shown in the info bar.
"""
sizer = self.GetSizer()
assert sizer is not None, "Sizer must be created first"
# user-added buttons replace the standard close button so remove it if we
# hadn't done it yet
if sizer.Detach(self._button):
self._button.Hide()
button = wx.Button(self, btnid, label)
button.SetBackgroundColour(self._background_color)
button.SetForegroundColour(self._foreground_color)
if wx.Platform == "__WXMAC__":
# smaller buttons look better in the(narrow)info bar under OS X
button.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)
num_items = self.subSizerButtons.GetItemCount()
if num_items == 1:
self.subSizerButtons.Add(button, wx.SizerFlags().Centre().Border())
self.subSizerButtons.Add(self._button, wx.SizerFlags().Centre().Border())
self._button.Show()
else:
self.subSizerButtons.Insert(
num_items - 1, button, wx.SizerFlags().Centre().Border()
)
if self.IsShown():
self.UpdateParent()
def SetButtons(self, buttons):
"""
Sets buttons for notification.
Parameter *buttons* is a list of tuples (button_name, event)
"""
for button_name, evt_handler in buttons:
button_id = wx.NewId()
self.button_ids.append(button_id)
self.AddButton(button_id, button_name)
self.Bind(wx.EVT_BUTTON, evt_handler, id=button_id)
def RemoveButtons(self):
"""
Removes buttons from info bar.
"""
items = self.subSizerButtons.GetChildren()
for item in reversed(items):
if not item.IsSpacer():
window = item.GetWindow()
if window.GetId() in self.button_ids:
self.subSizerButtons.Detach(window)
window.Destroy()
|