Last active
June 29, 2021 22:07
-
-
Save livibetter/127287ca94164e38cb09 to your computer and use it in GitHub Desktop.
Christmas terminal
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
# Xmas Terminal | |
# Copyright (C) 2012, 2015 Yu-Jie Lin | |
# | |
# Modified from urwid's code by Yu-Jie Lin | |
# | |
# Blog: http://blog.yjl.im/2012/12/christmas-terminal.html | |
# Gist: https://gist.github.com/livibetter/127287ca94164e38cb09 | |
# Video: https://www.youtube.com/watch?v=jiBcaV0FqTg | |
# | |
# Urwid terminal emulation widget | |
# Copyright (C) 2010 aszlig | |
# Copyright (C) 2011 Ian Ward | |
# Urwid terminal emulation widget example app | |
# Copyright (C) 2010 aszlig | |
# | |
# This library is free software; you can redistribute it and/or | |
# modify it under the terms of the GNU Lesser General Public | |
# License as published by the Free Software Foundation; either | |
# version 2.1 of the License, or (at your option) any later version. | |
# | |
# This library is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
# Lesser General Public License for more details. | |
# | |
# You should have received a copy of the GNU Lesser General Public | |
# License along with this library; if not, write to the Free Software | |
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
# | |
# Urwid web site: http://excess.org/urwid/ | |
import sys | |
import time | |
from functools import reduce | |
from itertools import cycle | |
from random import randint | |
import urwid | |
import urwid.vterm | |
from urwid import AttrSpec | |
if sys.version_info.major == 2: | |
from itertools import imap | |
elif sys.version_info.major >= 3: | |
imap = map | |
recolor = lambda l, c: (c, ) + l[1:] | |
snow = [] | |
MAX_SNOW = 20 | |
r = AttrSpec('light red', 'default', 16) | |
b = AttrSpec('light blue', 'default', 16) | |
g = AttrSpec('light green', 'default', 16) | |
y = AttrSpec('yellow', 'default', 16) | |
w = AttrSpec('white', 'default', 16) | |
snow_text = (w, None, b'*') | |
c = (r, b, g, y) * 2 | |
n = len(c) // 2 | |
color_seq = tuple( | |
reduce(tuple.__add__, ((x, ) * 2 for x in c[i:i + n])) | |
for i in range(n) | |
) | |
def fall(w, h): | |
global snow | |
if len(snow) < MAX_SNOW and not randint(0, 3): | |
snow.append([randint(0, w - 1), -1]) | |
for s in snow: | |
if randint(0, 9): | |
s[1] += 1 | |
f = lambda s: s[1] < h and w > s[0] >= 0 | |
# remove snow | |
snow = list(filter(f, snow)) | |
def content(self, trim_left=0, trim_right=0, cols=None, rows=None, | |
attr_map=None): | |
_row = 0 | |
n = len(color_seq) | |
offset = int(time.time() % n) | |
if self.scrolling_up == 0: | |
for line in self.term: | |
i = _row + offset | |
newline = list(imap(recolor, line, cycle(color_seq[i % n]))) | |
for s in (s for s in snow if s[1] == _row): | |
newline[s[0]] = snow_text | |
yield newline | |
_row += 1 | |
else: | |
buf = self.scrollback_buffer + self.term | |
for line in buf[-(self.height + self.scrolling_up):-self.scrolling_up]: | |
yield line | |
urwid.vterm.TermCanvas.content = content | |
def update_timer(loop, term): | |
loop.draw_screen() | |
loop.set_alarm_in(0.5, update_timer, term) | |
fall(term.width, term.height) | |
def main(): | |
term = urwid.Terminal(None) | |
def quit(*args, **kwargs): | |
raise urwid.ExitMainLoop() | |
urwid.connect_signal(term, 'closed', quit) | |
loop = urwid.MainLoop(term, handle_mouse=False) | |
term.main_loop = loop | |
loop.set_alarm_in(1, update_timer, term) | |
loop.run() | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment