瀏覽代碼

initial commit

Thomas Buck 1 年之前
當前提交
1fbfa5d329
共有 9 個檔案被更改,包括 13148 行新增0 行删除
  1. 1
    0
      .gitignore
  2. 1
    0
      README.md
  3. 97
    0
      draw.py
  4. 12826
    0
      fonts/iv18x16u.bdf
  5. 53
    0
      manager.py
  6. 27
    0
      solid.py
  7. 32
    0
      splash.py
  8. 45
    0
      test.py
  9. 66
    0
      weather.py

+ 1
- 0
.gitignore 查看文件

@@ -0,0 +1 @@
1
+__pycache__

+ 1
- 0
README.md 查看文件

@@ -0,0 +1 @@
1
+Included font from https://github.com/farsil/ibmfonts

+ 97
- 0
draw.py 查看文件

@@ -0,0 +1,97 @@
1
+#!/usr/bin/env python
2
+
3
+from bdfparser import Font
4
+from PIL import Image
5
+import os
6
+import time
7
+
8
+class DrawText:
9
+    def __init__(self, g):
10
+        self.gui = g
11
+
12
+        scriptDir = os.path.dirname(os.path.realpath(__file__))
13
+        fontDir = os.path.join(scriptDir, "fonts")
14
+        self.fonts = []
15
+        for f in os.listdir(os.fsencode(fontDir)):
16
+            filename = os.fsdecode(f)
17
+
18
+            if not filename.lower().endswith(".bdf"):
19
+                continue
20
+
21
+            font = Font(os.path.join(fontDir, filename))
22
+            print(f"{filename} global size is "
23
+                f"{font.headers['fbbx']} x {font.headers['fbby']} (pixel), "
24
+                f"it contains {len(font)} glyphs.")
25
+
26
+            # TODO hard-coded per-font offsets
27
+            offset = 0
28
+            if filename == "iv18x16u.bdf":
29
+                offset = 6
30
+
31
+            data = (font, offset)
32
+            self.fonts.append(data)
33
+
34
+    def getGlyph(self, c):
35
+        f, o = self.fonts[0] # TODO selection of fonts
36
+        g = f.glyph(c).draw()
37
+
38
+        # invert color
39
+        g = g.replace(1, 2).replace(0, 1).replace(2, 0)
40
+
41
+        # render to pixel data
42
+        img = Image.frombytes('RGBA',
43
+                              (g.width(), g.height()),
44
+                              g.tobytes('RGBA'))
45
+        return (img, o)
46
+
47
+    def drawGlyph(self, g, xOff, yOff):
48
+        for x in range(0, g.width):
49
+            for y in range(0, g.height):
50
+                p = g.getpixel((x, y))
51
+                self.gui.set_pixel(xOff + x, yOff + y, p)
52
+
53
+    def text(self, s, offset = 0):
54
+        w = 0
55
+        for c in s:
56
+            g, y = self.getGlyph(c)
57
+            self.drawGlyph(g, -offset + w, y)
58
+            w += g.width
59
+        return w
60
+
61
+class ScrollText:
62
+    def __init__(self, g, t, i = 1, s = 100):
63
+        self.gui = g
64
+        self.drawer = DrawText(self.gui)
65
+        self.text = t
66
+        self.iterations = i
67
+        self.speed = 1.0 / s
68
+
69
+        self.width = self.drawer.text(self.text)
70
+        self.offset = -self.gui.width
71
+        self.last = time.time()
72
+        self.count = 0
73
+
74
+    def restart(self):
75
+        self.offset = -self.gui.width
76
+        self.last = time.time()
77
+        self.count = 0
78
+
79
+    def finished(self):
80
+        return (self.count >= self.iterations)
81
+
82
+    def draw(self):
83
+        if (time.time() - self.last) > self.speed:
84
+            self.offset = (self.offset + 1)
85
+            if self.offset >= self.width:
86
+                self.offset = -self.gui.width
87
+                self.count += 1
88
+
89
+            self.last = time.time()
90
+
91
+        self.drawer.text(self.text, self.offset)
92
+
93
+if __name__ == "__main__":
94
+    from test import TestGUI
95
+    t = TestGUI(32, 32)
96
+    d = ScrollText(t, "Hello, World!")
97
+    t.debug_loop(d.draw)

+ 12826
- 0
fonts/iv18x16u.bdf
文件差異過大導致無法顯示
查看文件


+ 53
- 0
manager.py 查看文件

@@ -0,0 +1,53 @@
1
+#!/usr/bin/env python
2
+
3
+import time
4
+
5
+class Manager:
6
+    def __init__(self, g):
7
+        self.gui = g
8
+        self.screens = []
9
+        self.index = 0
10
+        self.lastTime = time.time()
11
+
12
+    def add(self, s, d = None):
13
+        v = (s, d)
14
+        self.screens.append(v)
15
+
16
+    def loop(self):
17
+        self.screens[self.index][0].draw()
18
+
19
+        if self.screens[self.index][1] == None:
20
+            if self.screens[self.index][0].finished():
21
+                self.index = (self.index + 1) % len(self.screens)
22
+                self.lastTime = time.time()
23
+                self.screens[self.index][0].restart()
24
+        else:
25
+            # use given timeout
26
+            if (time.time() - self.lastTime) > self.screens[self.index][1]:
27
+                self.index = (self.index + 1) % len(self.screens)
28
+                self.lastTime = time.time()
29
+                self.screens[self.index][0].restart()
30
+
31
+if __name__ == "__main__":
32
+    from test import TestGUI
33
+    from splash import SplashScreen
34
+    #from weather import WeatherScreen
35
+    from draw import ScrollText
36
+    from solid import Solid
37
+
38
+    t = TestGUI(32, 32)
39
+    m = Manager(t)
40
+
41
+    m.add(SplashScreen(t), 2)
42
+    m.add(Solid(t, 3.0))
43
+
44
+    #m.add(WeatherScreen(t), 4)
45
+    #m.add(Solid(t, 3.0))
46
+
47
+    m.add(ScrollText(t, "This appears once"))
48
+    m.add(Solid(t, 3.0))
49
+
50
+    m.add(ScrollText(t, "And this twice...", 2))
51
+    m.add(Solid(t, 3.0))
52
+
53
+    t.debug_loop(m.loop)

+ 27
- 0
solid.py 查看文件

@@ -0,0 +1,27 @@
1
+#!/usr/bin/env python
2
+
3
+import time
4
+
5
+class Solid:
6
+    def __init__(self, g, t = 1.0, c = (0, 0, 0)):
7
+        self.gui = g
8
+        self.time = t
9
+        self.color = c
10
+        self.start = time.time()
11
+
12
+    def restart(self):
13
+        self.start = time.time()
14
+
15
+    def finished(self):
16
+        return (time.time() - self.start) >= self.time
17
+
18
+    def draw(self):
19
+        for x in range(0, self.gui.width):
20
+            for y in range(0, self.gui.height):
21
+                self.gui.set_pixel(x, y, self.color)
22
+
23
+if __name__ == "__main__":
24
+    from test import TestGUI
25
+    t = TestGUI(32, 32)
26
+    d = ScrollText(t, "Hello, World!")
27
+    t.debug_loop(d.draw)

+ 32
- 0
splash.py 查看文件

@@ -0,0 +1,32 @@
1
+#!/usr/bin/env python
2
+
3
+class SplashScreen:
4
+    def __init__(self, g, width = 32, height = 32):
5
+        self.gui = g
6
+        self.width = width
7
+        self.height = height
8
+
9
+    def draw(self):
10
+        self.gui.set_pixel(             0,               0, (255, 255, 255))
11
+        self.gui.set_pixel(             0, self.height - 1, (  0,   0, 255))
12
+        self.gui.set_pixel(self.width - 1,               0, (255,   0,   0))
13
+        self.gui.set_pixel(self.width - 1, self.height - 1, (  0, 255,   0))
14
+
15
+        for i in range(0, int(min(self.width, self.height) / 3)):
16
+            self.gui.set_pixel((self.width / 2) - 1 + i, (self.height / 2) - 1 + i, (255, 255, 255))
17
+            self.gui.set_pixel((self.width / 2) - 1 - i, (self.height / 2) - 1 - i, (255, 255, 255))
18
+            self.gui.set_pixel((self.width / 2) - 1 + i, (self.height / 2) - 1 - i, (255, 255, 255))
19
+            self.gui.set_pixel((self.width / 2) - 1 - i, (self.height / 2) - 1 + i, (255, 255, 255))
20
+
21
+    def finished(self):
22
+        return True
23
+
24
+    def restart(self):
25
+        pass
26
+
27
+if __name__ == "__main__":
28
+    from test import TestGUI
29
+    t = TestGUI()
30
+    s = SplashScreen(t)
31
+    s.draw()
32
+    t.debug_loop(s.draw)

+ 45
- 0
test.py 查看文件

@@ -0,0 +1,45 @@
1
+#!/usr/bin/env python
2
+
3
+import pygame
4
+
5
+class TestGUI:
6
+    def __init__(self, width = 32, height = 32, multiplier = 16):
7
+        self.width = width
8
+        self.height = height
9
+        self.multiplier = multiplier
10
+
11
+        pygame.display.init()
12
+        self.screen = pygame.display.set_mode((self.width * self.multiplier, self.height * self.multiplier))
13
+        self.clock = pygame.time.Clock()
14
+        self.running = True
15
+
16
+    def exit(self):
17
+        pygame.quit()
18
+
19
+    def loop_start(self):
20
+        for event in pygame.event.get():
21
+            if event.type == pygame.QUIT:
22
+                return True
23
+
24
+        self.screen.fill("black")
25
+        return False
26
+
27
+    def loop_end(self):
28
+        pygame.display.flip()
29
+        self.clock.tick(60)
30
+
31
+    def debug_loop(self, func = None):
32
+        while True:
33
+            if self.loop_start():
34
+                break
35
+            if func != None:
36
+                func()
37
+            self.loop_end()
38
+        self.exit()
39
+
40
+    def set_pixel(self, x, y, color):
41
+        pygame.draw.rect(self.screen, color, pygame.Rect(x * self.multiplier, y * self.multiplier, self.multiplier, self.multiplier))
42
+
43
+if __name__ == "__main__":
44
+    t = TestGUI(32, 32)
45
+    t.debug_loop(lambda: t.set_pixel(15, 15, (255, 255, 255)))

+ 66
- 0
weather.py 查看文件

@@ -0,0 +1,66 @@
1
+#!/usr/bin/env python
2
+
3
+from pyowm.owm import OWM
4
+from pyowm.utils.config import get_default_config
5
+
6
+import time
7
+
8
+api_key = "API_KEY_HERE"
9
+
10
+class WeatherScreen:
11
+    def __init__(self, gui, latitude = 47.7174, longitude = 9.3924, language = "de", refresh = 600, width = 32, height = 32):
12
+        self.gui = gui
13
+        self.latitude = latitude
14
+        self.longitude = longitude
15
+        self.language = language
16
+        self.refresh = refresh
17
+        self.width = width
18
+        self.height = height
19
+
20
+        self.lastTime = time.time()
21
+        self.data = ""
22
+
23
+        self.fetchData()
24
+
25
+    def fetchData(self):
26
+        config_dict = get_default_config()
27
+        config_dict['language'] = self.language
28
+        owm = OWM(api_key, config_dict)
29
+        mgr = owm.weather_manager()
30
+
31
+        observation = mgr.weather_at_place("Tuttlingen, DE")
32
+        print(observation.weather.rain)
33
+        print(observation.weather.snow)
34
+        print(observation.weather.wind)
35
+        print(observation.weather.humidity)
36
+        print(observation.weather.pressure)
37
+        print(observation.weather.temperature)
38
+        print(observation.weather.clouds)
39
+        print(observation.weather.status)
40
+        print(observation.weather.detailed_status)
41
+        print(observation.weather.weather_icon_name)
42
+        print(observation.weather.precipitation_probability)
43
+
44
+        #self.data = mgr.one_call(lat=self.latitude, lon=self.longitude)
45
+        #print(self.data.forecast_hourly[0].wind().get("speed", 0))
46
+
47
+    def draw(self):
48
+        if (time.time() - self.lastTime) > self.refresh:
49
+            self.fetchData()
50
+            self.lastTime = time.time()
51
+
52
+        # TODO text location
53
+        # TODO text data
54
+
55
+    def finished(self):
56
+        return True
57
+
58
+    def restart(self):
59
+        pass
60
+
61
+if __name__ == "__main__":
62
+    from test import TestGUI
63
+    t = TestGUI()
64
+    s = WeatherScreen(t)
65
+    s.draw()
66
+    t.debug_loop(s.draw)

Loading…
取消
儲存