Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python -OO
- '''
- tray icon battery indicator
- adapted from http://ubuntuforums.org/showthread.php?t=1153951 and
- http://code.activestate.com/recipes/475155-dynamic-system-tray-icon-wxpython/
- any original code Copyright (c) 2013 jc.unternet.net
- licensing GPL3 or later
- '''
- import sys, os, wx, subprocess, re, time
- ACPI_PATTERN = '^Battery 0:\s+(\w+), (\d+)%'
- COLORS = {
- 'Full': 'green',
- 'Charging': 'green',
- 'Discharging': 'yellow',
- }
- UPDATE_TIME = 5 # seconds
- MILLISECONDS = 1000 # multiplier for seconds
- UPDATER = wx.NewEventType() # returns unique (to this app) ID
- WIDTH, HEIGHT = 16, 16 # must be multiples of 5 + 1; only 16 works right
- BORDER_WIDTH = BORDER_HEIGHT = 1 # black border -- width and height the same
- PADDING_WIDTH = 3 # transparent pixels
- BATTERY_WIDTH = WIDTH - (PADDING_WIDTH * 2) - (BORDER_WIDTH * 2)
- TRANSPARENT = 'white'
- WARNING_LEVEL = 3 # show red when this many lines
- class Icon(wx.Frame):
- def __init__(self, parent, ID, title):
- wx.Frame.__init__(self, parent, ID, title, wx.DefaultPosition, wx.DefaultSize)
- self.updateIcon()
- # bind frame onQuit to window close
- self.Bind(wx.EVT_CLOSE, self.onQuit)
- # bind frame onUp to mouseup on taskbar icon
- self.icon.Bind(wx.EVT_TASKBAR_LEFT_UP, self.onUp)
- width, height = self.GetSize()
- debug('frame size: (%d, %d)' % (width, height))
- self.timer = wx.Timer(self, UPDATER)
- self.timer.Start(UPDATE_TIME * MILLISECONDS)
- wx.EVT_TIMER(self, UPDATER, self.updateIcon)
- debug('initialization complete')
- def onQuit(self, event):
- self.timer.Stop() # maybe not necessary but can't hurt
- self.icon.Destroy()
- self.Destroy()
- def onUp(self, event):
- iconized = self.IsIconized()
- if not iconized:
- self.Iconize()
- self.Hide()
- else:
- self.Restore()
- self.Show()
- def updateIcon(self, event = None):
- acpistring = acpi()
- debug('acpi: %s' % acpistring)
- status = re.compile(ACPI_PATTERN).match(acpistring)
- debug('status: %s' % status)
- color, charge = icon_data(*status.groups()) if status else ('red', 5)
- pixels = build_image(color, charge)
- image = wx.EmptyImage(WIDTH, HEIGHT)
- image.SetData(pixels)
- bitmap = image.ConvertToBitmap()
- bitmap.SetMask(wx.Mask(bitmap, color_tuple(TRANSPARENT)))
- icon_image = wx.EmptyIcon()
- icon_image.CopyFromBitmap(bitmap)
- if not hasattr(self, 'icon'):
- self.icon = wx.TaskBarIcon()
- self.icon.SetIcon(icon = icon_image, tooltip = "Battery 0 State")
- # put text of acpi string in frame
- if not hasattr(self, 'statusline'):
- self.statusline = wx.StaticText(self, label = acpistring)
- else:
- self.statusline.SetLabel(acpistring)
- class IconApp(wx.App):
- def OnInit(self):
- frame = Icon(None, -1, "Battery 0 State")
- frame.Show() # shows just momentarily before we iconize it
- self.SetTopWindow(frame)
- frame.Iconize()
- return True
- def build_image(color, charge):
- battery_height = HEIGHT - (2 * BORDER_HEIGHT)
- charge_height = int((float(charge) / 100) * battery_height)
- if color == 'yellow' and charge_height <= WARNING_LEVEL:
- color = 'red'
- padding_left = (pixel(TRANSPARENT) * PADDING_WIDTH) + pixel('black')
- padding_right = pixel('black') + (pixel(TRANSPARENT) * PADDING_WIDTH)
- pixels = padding_left + (pixel('black') * BATTERY_WIDTH) + padding_right
- for i in range(battery_height):
- rowcolor = color
- if (battery_height - 1 - i) > charge_height:
- rowcolor = TRANSPARENT
- pixels += padding_left + (pixel(rowcolor) * BATTERY_WIDTH) + padding_right
- pixels += padding_left + (pixel('black') * BATTERY_WIDTH) + padding_right
- return pixels
- def color_tuple(color):
- if type(color) == str:
- return wx.NamedColour(color).asTuple()
- else:
- return tuple(color)
- def pixel(color):
- return ''.join(map(chr, color_tuple(color)))
- def debug(message = None):
- if __debug__:
- if message:
- print >>sys.stderr, message
- return True
- def acpi():
- output = subprocess.Popen(['acpi'], stdout = subprocess.PIPE).communicate()[0]
- return output
- def icon_data(word, number):
- return COLORS.get(word, 'yellow'), int(number)
- if __name__ == '__main__':
- IconApp(0).MainLoop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement