mirror of
https://github.com/jtgans/g13gui.git
synced 2025-06-20 00:14:09 -04:00
Merge pull request #22 from jtgans/clock-enhancements
clock: Add 24-hour toggle, load, ram graphs
This commit is contained in:
commit
e51c7ca0fc
@ -1,15 +1,26 @@
|
|||||||
import gi
|
import gi
|
||||||
import time
|
import time
|
||||||
|
import enum
|
||||||
|
import psutil
|
||||||
|
|
||||||
from g13gui.applet.applet import Applet
|
from g13gui.applet.applet import Applet
|
||||||
|
from g13gui.applet.applet import Buttons
|
||||||
from g13gui.applet.applet import RunApplet
|
from g13gui.applet.applet import RunApplet
|
||||||
from g13gui.bitwidgets.label import Label
|
from g13gui.bitwidgets.label import Label
|
||||||
from g13gui.bitwidgets.fonts import Fonts
|
from g13gui.bitwidgets.fonts import Fonts
|
||||||
|
from g13gui.bitwidgets.button import LabelButton
|
||||||
|
from g13gui.bitwidgets.graph import Graph
|
||||||
|
from g13gui.bitwidgets import DISPLAY_WIDTH
|
||||||
|
|
||||||
gi.require_version('GLib', '2.0')
|
gi.require_version('GLib', '2.0')
|
||||||
from gi.repository import GLib
|
from gi.repository import GLib
|
||||||
|
|
||||||
|
|
||||||
|
class ClockMode(enum.Enum):
|
||||||
|
HOUR_12 = 1
|
||||||
|
HOUR_24 = 2
|
||||||
|
|
||||||
|
|
||||||
class ClockApplet(Applet):
|
class ClockApplet(Applet):
|
||||||
NAME = 'Clock'
|
NAME = 'Clock'
|
||||||
|
|
||||||
@ -20,22 +31,84 @@ class ClockApplet(Applet):
|
|||||||
self._timeLabel.showAll()
|
self._timeLabel.showAll()
|
||||||
self.screen.addChild(self._timeLabel)
|
self.screen.addChild(self._timeLabel)
|
||||||
|
|
||||||
self._updateTimeLabel()
|
self._modeButtons = {
|
||||||
|
ClockMode.HOUR_12: LabelButton('12 hour'),
|
||||||
|
ClockMode.HOUR_24: LabelButton('24 hour')
|
||||||
|
}
|
||||||
|
self._clockMode = ClockMode.HOUR_24
|
||||||
|
self._onModeSwitch()
|
||||||
|
|
||||||
def _updateTimeLabel(self):
|
self._loadGraphToggle = LabelButton('Load', isToggleable=True)
|
||||||
|
self._ramGraphToggle = LabelButton('RAM', isToggleable=True)
|
||||||
|
self.screen.buttonBar.addChild(self._loadGraphToggle)
|
||||||
|
self.screen.buttonBar.addChild(self._ramGraphToggle)
|
||||||
|
self.screen.buttonBar.showAll()
|
||||||
|
|
||||||
|
self._loadGraph = Graph(1, 18,
|
||||||
|
DISPLAY_WIDTH // 2 - 5, 12)
|
||||||
|
self.screen.addChild(self._loadGraph)
|
||||||
|
|
||||||
|
self._ramGraph = Graph(DISPLAY_WIDTH // 2 + 5, 18,
|
||||||
|
DISPLAY_WIDTH // 2 - 7, 12)
|
||||||
|
self.screen.addChild(self._ramGraph)
|
||||||
|
|
||||||
|
self._update()
|
||||||
|
|
||||||
|
def _update(self):
|
||||||
(tm_year, tm_month, tm_mday, tm_hour,
|
(tm_year, tm_month, tm_mday, tm_hour,
|
||||||
tm_min, tm_sec, tm_wday, tm_yday, tm_isdst) = time.localtime()
|
tm_min, tm_sec, tm_wday, tm_yday, tm_isdst) = time.localtime()
|
||||||
self._timeLabel.text = '%d:%0.2d:%0.2d' % (tm_hour, tm_min, tm_sec)
|
ampm = ''
|
||||||
|
|
||||||
|
if self._clockMode == ClockMode.HOUR_12:
|
||||||
|
ampm = ' AM'
|
||||||
|
if tm_hour >= 12:
|
||||||
|
ampm = ' PM'
|
||||||
|
if tm_hour > 12:
|
||||||
|
tm_hour -= 12
|
||||||
|
|
||||||
|
self._timeLabel.text = '%d:%0.2d:%0.2d%s' % (
|
||||||
|
tm_hour, tm_min, tm_sec, ampm)
|
||||||
|
|
||||||
|
(w, h) = self._timeLabel.bounds
|
||||||
|
x = (DISPLAY_WIDTH // 2) - (w // 2)
|
||||||
|
self._timeLabel.position = (x, 0)
|
||||||
|
|
||||||
|
self._loadGraph.addValue(psutil.cpu_percent())
|
||||||
|
self._ramGraph.addValue(psutil.virtual_memory().percent / 100)
|
||||||
|
|
||||||
def _pushTime(self):
|
def _pushTime(self):
|
||||||
self._updateTimeLabel()
|
self._update()
|
||||||
self.maybePresentScreen()
|
self.maybePresentScreen()
|
||||||
return self.screen.visible
|
return self.screen.visible
|
||||||
|
|
||||||
def onShown(self, timestamp):
|
def onShown(self, timestamp):
|
||||||
self._updateTimeLabel()
|
self._update()
|
||||||
GLib.timeout_add_seconds(1, self._pushTime)
|
GLib.timeout_add_seconds(1, self._pushTime)
|
||||||
|
|
||||||
|
def onUpdateScreen(self):
|
||||||
|
self._update()
|
||||||
|
|
||||||
|
def _onModeSwitch(self):
|
||||||
|
if self._clockMode == ClockMode.HOUR_12:
|
||||||
|
self._clockMode = ClockMode.HOUR_24
|
||||||
|
button = self._modeButtons[ClockMode.HOUR_12]
|
||||||
|
elif self._clockMode == ClockMode.HOUR_24:
|
||||||
|
self._clockMode = ClockMode.HOUR_12
|
||||||
|
button = self._modeButtons[ClockMode.HOUR_24]
|
||||||
|
|
||||||
|
button.show()
|
||||||
|
self.screen.buttonBar.setButton(0, button)
|
||||||
|
|
||||||
|
def onKeyReleased(self, timestamp, key):
|
||||||
|
if key == Buttons.L1:
|
||||||
|
self._onModeSwitch()
|
||||||
|
elif key == Buttons.L2:
|
||||||
|
self._loadGraphToggle.toggle()
|
||||||
|
self._loadGraph.visible = self._loadGraphToggle.isOn
|
||||||
|
elif key == Buttons.L3:
|
||||||
|
self._ramGraphToggle.toggle()
|
||||||
|
self._ramGraph.visible = self._ramGraphToggle.isOn
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
RunApplet(ClockApplet)
|
RunApplet(ClockApplet)
|
||||||
|
@ -1,14 +1,18 @@
|
|||||||
from builtins import property
|
from builtins import property
|
||||||
|
|
||||||
from g13gui.bitwidgets.widget import Widget
|
from g13gui.bitwidgets.widget import Widget
|
||||||
|
from g13gui.bitwidgets.label import Label
|
||||||
from g13gui.bitwidgets.glyph import Glyph
|
from g13gui.bitwidgets.glyph import Glyph
|
||||||
|
from g13gui.bitwidgets.glyph import Glyphs
|
||||||
from g13gui.bitwidgets.rectangle import Rectangle
|
from g13gui.bitwidgets.rectangle import Rectangle
|
||||||
|
from g13gui.bitwidgets.fonts import Fonts
|
||||||
from g13gui.observer.subject import ChangeType
|
from g13gui.observer.subject import ChangeType
|
||||||
|
|
||||||
|
|
||||||
class Button(Widget):
|
class Button(Widget):
|
||||||
def __init__(self, glyph, fill=True):
|
def __init__(self, glyph, fill=True):
|
||||||
Widget.__init__(self)
|
Widget.__init__(self)
|
||||||
|
|
||||||
self._rect = Rectangle(*self.position, *self.bounds, fill=False)
|
self._rect = Rectangle(*self.position, *self.bounds, fill=False)
|
||||||
self._rect.show()
|
self._rect.show()
|
||||||
self.addChild(self._rect)
|
self.addChild(self._rect)
|
||||||
@ -60,3 +64,94 @@ class Button(Widget):
|
|||||||
@glyph.setter
|
@glyph.setter
|
||||||
def glyph(self, glyph):
|
def glyph(self, glyph):
|
||||||
self.setProperty('glyph', glyph)
|
self.setProperty('glyph', glyph)
|
||||||
|
|
||||||
|
|
||||||
|
class LabelButton(Button):
|
||||||
|
def __init__(self, text, isToggleable=False, hasMore=False, fill=True):
|
||||||
|
Button.__init__(self, Glyphs.BLANK, fill)
|
||||||
|
|
||||||
|
self._isOn = False
|
||||||
|
self._isToggleable = isToggleable
|
||||||
|
self._hasMore = hasMore
|
||||||
|
|
||||||
|
self.removeChild(self._glyph)
|
||||||
|
self._glyph = Label(*self.position, text, font=Fonts.TINY)
|
||||||
|
self._glyph.show()
|
||||||
|
self.addChild(self._glyph)
|
||||||
|
|
||||||
|
self._moreGlyph = Glyph(0, 0, Glyphs.CHEVRON_RIGHT)
|
||||||
|
self.addChild(self._moreGlyph)
|
||||||
|
self._toggleGlyph = Glyph(0, 0, Glyphs.BOX)
|
||||||
|
self.addChild(self._toggleGlyph)
|
||||||
|
self.updateGlyphs()
|
||||||
|
|
||||||
|
def updateGlyphs(self):
|
||||||
|
if self.isOn:
|
||||||
|
self._toggleGlyph.glyph = Glyphs.FILLED_BOX
|
||||||
|
else:
|
||||||
|
self._toggleGlyph.glyph = Glyphs.BOX
|
||||||
|
|
||||||
|
self._moreGlyph.visible = self.hasMore
|
||||||
|
self._toggleGlyph.visible = self.isToggleable
|
||||||
|
|
||||||
|
def _updatePositionAndBounds(self, subject, changeType, key, data):
|
||||||
|
super()._updatePositionAndBounds(subject, changeType, key, data)
|
||||||
|
|
||||||
|
(x, y) = self.position
|
||||||
|
(w, h) = self.bounds
|
||||||
|
(glyphW, glyphH) = self._moreGlyph.bounds
|
||||||
|
|
||||||
|
moreX = x + w - glyphW - 1
|
||||||
|
moreY = y + (h // 2) - (glyphH // 2)
|
||||||
|
self._moreGlyph.position = (moreX, moreY)
|
||||||
|
|
||||||
|
toggleX = x + 1
|
||||||
|
toggleY = y + (h // 2) - (glyphH // 2)
|
||||||
|
self._toggleGlyph.position = (toggleX, toggleY)
|
||||||
|
|
||||||
|
(labelX, labelY) = self._glyph.position
|
||||||
|
labelY += 1
|
||||||
|
self._glyph.position = (labelX, labelY)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def isToggleable(self):
|
||||||
|
return self._isToggleable
|
||||||
|
|
||||||
|
@isToggleable.setter
|
||||||
|
def isToggleable(self, value):
|
||||||
|
self.setProperty('isToggleable', value)
|
||||||
|
self.updateGlyphs()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def isOn(self):
|
||||||
|
return self._isOn
|
||||||
|
|
||||||
|
@isOn.setter
|
||||||
|
def isOn(self, value):
|
||||||
|
self.setProperty('isOn', value)
|
||||||
|
self.updateGlyphs()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def isOff(self):
|
||||||
|
return not self._isOn
|
||||||
|
|
||||||
|
def toggle(self):
|
||||||
|
self.setProperty('isOn', not self.isOn)
|
||||||
|
self.updateGlyphs()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def hasMore(self):
|
||||||
|
return self._hasMore
|
||||||
|
|
||||||
|
@hasMore.setter
|
||||||
|
def hasMore(self, value):
|
||||||
|
self.setProperty('hasMore', value)
|
||||||
|
self.updateGlyphs()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def text(self):
|
||||||
|
return self._glyph.text
|
||||||
|
|
||||||
|
@text.setter
|
||||||
|
def text(self, text):
|
||||||
|
self._glyph.text = text
|
||||||
|
@ -5,8 +5,9 @@ from g13gui.bitwidgets.display import Display
|
|||||||
from g13gui.bitwidgets.x11displaydevice import X11DisplayDevice
|
from g13gui.bitwidgets.x11displaydevice import X11DisplayDevice
|
||||||
from g13gui.bitwidgets.screen import Screen
|
from g13gui.bitwidgets.screen import Screen
|
||||||
from g13gui.bitwidgets.button import Button
|
from g13gui.bitwidgets.button import Button
|
||||||
from g13gui.bitwidgets.button import Glyphs
|
from g13gui.bitwidgets.button import LabelButton
|
||||||
from g13gui.bitwidgets.button import Glyph
|
from g13gui.bitwidgets.glyph import Glyphs
|
||||||
|
from g13gui.bitwidgets.glyph import Glyph
|
||||||
from g13gui.bitwidgets.label import Label
|
from g13gui.bitwidgets.label import Label
|
||||||
from g13gui.bitwidgets.fonts import Fonts
|
from g13gui.bitwidgets.fonts import Fonts
|
||||||
|
|
||||||
@ -72,7 +73,7 @@ class ButtonTests(unittest.TestCase):
|
|||||||
|
|
||||||
def testLabelButton(self):
|
def testLabelButton(self):
|
||||||
self.dd.name = 'testLabelButton'
|
self.dd.name = 'testLabelButton'
|
||||||
testButton = Label(0, 0, "Test", font=Fonts.TINY)
|
testButton = LabelButton("Test")
|
||||||
self.screen.buttonBar.addChild(testButton)
|
self.screen.buttonBar.addChild(testButton)
|
||||||
self.screen.buttonBar.showAll()
|
self.screen.buttonBar.showAll()
|
||||||
self.screen.nextFrame()
|
self.screen.nextFrame()
|
||||||
|
59
g13gui/bitwidgets/graph.py
Normal file
59
g13gui/bitwidgets/graph.py
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
from builtins import property
|
||||||
|
|
||||||
|
from g13gui.bitwidgets.widget import Widget
|
||||||
|
from g13gui.bitwidgets.rectangle import Rectangle
|
||||||
|
|
||||||
|
|
||||||
|
class Graph(Widget):
|
||||||
|
def __init__(self, x, y, w, h):
|
||||||
|
Widget.__init__(self)
|
||||||
|
|
||||||
|
self._rect = Rectangle(x, y, w, h, fill=True)
|
||||||
|
self.addChild(self._rect)
|
||||||
|
|
||||||
|
self.position = (x, y)
|
||||||
|
self.bounds = (w, h)
|
||||||
|
|
||||||
|
self._timeseries = [0] * w
|
||||||
|
|
||||||
|
def addValue(self, value):
|
||||||
|
if value > 1 or value < 0:
|
||||||
|
value = 0
|
||||||
|
|
||||||
|
(w, h) = self.bounds
|
||||||
|
self._timeseries.append(value)
|
||||||
|
if len(self._timeseries) > w:
|
||||||
|
del self._timeseries[0]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def bounds(self):
|
||||||
|
return self._bounds
|
||||||
|
|
||||||
|
@bounds.setter
|
||||||
|
def bounds(self, wh):
|
||||||
|
self.setProperty('bounds', wh)
|
||||||
|
self._rect.bounds = wh
|
||||||
|
self._timeseries = [0] * wh[0]
|
||||||
|
|
||||||
|
def draw(self, ctx):
|
||||||
|
super().draw(ctx)
|
||||||
|
|
||||||
|
(x, y) = self.position
|
||||||
|
(w, h) = self.bounds
|
||||||
|
(t, b, l, r) = (y, y + h, x, x + w)
|
||||||
|
tl = (l, t)
|
||||||
|
bl = (l, b)
|
||||||
|
br = (r, b)
|
||||||
|
|
||||||
|
if self.visible:
|
||||||
|
ctx.line(tl+bl, fill=1)
|
||||||
|
ctx.line(bl+br, fill=1)
|
||||||
|
|
||||||
|
for idx, value in enumerate(self._timeseries):
|
||||||
|
xoffs = idx + x
|
||||||
|
scaledValue = int(value * h)
|
||||||
|
yoffs = b - scaledValue
|
||||||
|
|
||||||
|
points = (xoffs, yoffs,
|
||||||
|
xoffs, b)
|
||||||
|
ctx.line(points, fill=1)
|
@ -21,14 +21,14 @@ class Label(Widget):
|
|||||||
align=Alignment.LEFT,
|
align=Alignment.LEFT,
|
||||||
strokeWidth=0):
|
strokeWidth=0):
|
||||||
Widget.__init__(self)
|
Widget.__init__(self)
|
||||||
self.position = (x, y)
|
self._position = (x, y)
|
||||||
self.text = text
|
self._text = text
|
||||||
self.font = font
|
self._font = font
|
||||||
self.fill = fill
|
self._fill = fill
|
||||||
self.spacing = spacing
|
self._spacing = spacing
|
||||||
self.align = align
|
self._align = align
|
||||||
self.strokeWidth = strokeWidth
|
self._strokeWidth = strokeWidth
|
||||||
self.bounds = FontManager.getFont(self.font).getsize(self.text)
|
self._bounds = FontManager.getFont(self.font).getsize(self.text)
|
||||||
|
|
||||||
def draw(self, ctx):
|
def draw(self, ctx):
|
||||||
if self._visible:
|
if self._visible:
|
||||||
@ -62,14 +62,17 @@ class Label(Widget):
|
|||||||
@text.setter
|
@text.setter
|
||||||
def text(self, text):
|
def text(self, text):
|
||||||
self.setProperty('text', text)
|
self.setProperty('text', text)
|
||||||
|
self.bounds = FontManager.getFont(self.font).getsize(self.text)
|
||||||
|
|
||||||
@font.setter
|
@font.setter
|
||||||
def font(self, font):
|
def font(self, font):
|
||||||
self.setProperty('font', font)
|
self.setProperty('font', font)
|
||||||
|
self.bounds = FontManager.getFont(self.font).getsize(self.text)
|
||||||
|
|
||||||
@spacing.setter
|
@spacing.setter
|
||||||
def spacing(self, spacing):
|
def spacing(self, spacing):
|
||||||
self.setProperty('spacing', spacing)
|
self.setProperty('spacing', spacing)
|
||||||
|
self.bounds = FontManager.getFont(self.font).getsize(self.text)
|
||||||
|
|
||||||
@align.setter
|
@align.setter
|
||||||
def align(self, align):
|
def align(self, align):
|
||||||
|
Loading…
Reference in New Issue
Block a user