Skip to content

Instantly share code, notes, and snippets.

@livibetter
Last active June 29, 2021 22:07
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save livibetter/127287ca94164e38cb09 to your computer and use it in GitHub Desktop.
Save livibetter/127287ca94164e38cb09 to your computer and use it in GitHub Desktop.
Christmas terminal
#!/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