Archive for July, 2009

Update: hacks repository

Tuesday, July 28th, 2009

I decided to move the svn-tools repository inside hacks.

hacks repository

Thursday, July 9th, 2009

I decided to create a repository containing the stuff i published without being part of a standalone repository; so this would be the shelter for scripts like pmv, rotating-cube, word-challenge-hacked ecc. ecc.

The name of the repository is hacks.

Mystipy screensaver

Thursday, July 9th, 2009


Mystipy is a port of the famous Mystify screensaver from Microsoft (Vista’s one is different from the Xp’s one: the port is of the Xp’s one). As the name suggests, it has been written in python /w gtk libraries.

 Button          Effect
-------- -----------------------
    f      enable/disable fps
    F    fullscreen/unfullscreen
    q             quit

I like the shading effect! Hope you too! Here is the code!

#!/usr/bin/env python

import time
import math
import random
import gtk
import gobject
import pygtk

SIZE = (340, 240)
SPEED = 10
N_SHAPES = 3
N_COLORS = 32
N_SHADES = 16
COLOR_REFRESH = 200
MOVE_REFRESH = 33

class Point:
	def __init__(self, point, size=None):
		if point is None:
			self.size  = size
			self.coord = (size[0]*random.random(),
					size[1]*random.random())
			self.speed = (SPEED*(2*random.random() - 1),
					SPEED*(2*random.random() - 1))
		else:
			self.size  = point.size
			self.coord = point.coord
			self.speed = point.speed

	def __getitem__(self, i):
		return self.coord[i]

	def move(self):
		x = self.coord[0] + self.speed[0]
		if x >= self.size[0]:
			x = self.size[0] - 1 - (x - self.size[0])
			self.speed = (-self.speed[0], self.speed[1])
		elif x < 0:
			x = -x
			self.speed = (-self.speed[0], self.speed[1])

		y = self.coord[1] + self.speed[1]
		if y >= self.size[1]:
			y = self.size[1] - 1 - (y - self.size[1])
			self.speed = (self.speed[0], -self.speed[1])
		elif y < 0:
			y = -y
			self.speed = (self.speed[0], -self.speed[1])

		self.coord = (x, y)

class Shape:
	def __init__(self, shape, n=None, size=None):
		self.points = []

		if shape is None:
			self.n = n
			for i in range(n):
				self.points.append(Point(None, size))

			self.color  = int(N_COLORS*random.random())
			self.shade  = N_SHADES - 1
			self.redraw = True
		else:
			self.n = shape.n
			for i in range(shape.n):
				self.points.append(Point(shape.points[i]))
			self.color  = shape.color
			self.shade  = shape.shade
			self.redraw = shape.redraw

	def change_color(self):
		self.color = (self.color + 1)%N_COLORS
		self.redraw = True

	def copy(self, shape):
		pass

	def fade_out(self):
		self.shade -= 1
		self.redraw = True
		if self.shade < 0:
			return False
		else:
			return True

	def get(self):
		if self.redraw:
			self.redraw = False

			list = []
			points = []
			n = len(self.points)
			for i in range(n):
				x = int(self.points[i][0])
				y = int(self.points[i][1])
				points.append((x, y))
				if i == n - 1:
					x1 = int(self.points[0][0])
					y1 = int(self.points[0][1])
				else:
					x1 = int(self.points[i + 1][0])
					y1 = int(self.points[i + 1][1])
				points.append((x1, y1))
			list.append((self.color, self.shade, points))

			return list
		else:
			return []

	def move(self):
		for p in self.points:
			p.move()

		self.redraw = True
		return True

class ScreenSaver:
	def __init__(self):
		self.window = gtk.Window()
		self.window.set_size_request(SIZE[0], SIZE[1])
		self.window.connect("delete-event", gtk.main_quit)
		self.window.connect("key-press-event", self.key_press_event_cb)

		self.vbox = gtk.VBox()
		self.window.add(self.vbox)

		self.darea = gtk.DrawingArea()
		self.darea.connect("configure-event", self.configure_event_cb)
		self.darea.connect("expose-event", self.expose_event_cb)
		self.vbox.pack_start(self.darea)

		self.status  = gtk.Statusbar()
		self.status.set_no_show_all(True)
		self.vbox.pack_start(self.status, False, False)

		self.context = self.status.get_context_id("")

		self.window.show_all()

		self.fullscreen = False
		self.enable_fps = False

		gobject.timeout_add(1000, self.update_fps)
		gobject.timeout_add(COLOR_REFRESH, self.change_color)
		gobject.idle_add(self.move)
		gobject.idle_add(self.draw_scene)

		self.counter = 0

	def change_color(self):
		for list in self.shapes:
			for shape in list:
				shape.change_color()

		return True

	def configure_event_cb(self, widget, event):
		x, y, width, height = widget.get_allocation()

		self.style    = widget.get_style()
		self.colormap = widget.get_colormap()

		# initialize the palette
		self.init_palette(N_COLORS, N_SHADES)

		# initialize the shapes
		self.shapes = []
		for i in range(N_SHAPES):
			self.shapes.append(
					[Shape(None, 3 + i, (width, height))])

		return True

	def expose_event_cb(self, widget, event):
		x , y, width, height = event.area

		widget.window.draw_rectangle(
				self.style.black_gc,
				True, x, y, width, height)
		return False

	def draw_scene(self):
		# draw the objects
		lines = []
		for i in range(N_COLORS):
			lines.append([])
			for j in range(N_SHADES):
				lines[i].append([])

		# get the lines from the objects
		for list in self.shapes:
			for shape in list:
				for color, shade, points in shape.get():
					lines[color][shade] += points

		# draw the dark lines before
		changed = False
		for j in range(N_SHADES):
			for i in range(N_COLORS):
				if len(lines[i][j]) == 0:
					continue
				changed = True
				self.darea.window.draw_lines(
						self.palette[i][j],
						lines[i][j])

		# update the fps counter
		if changed == True:
			self.counter += 1

		return True

	def key_press_event_cb(self, widget, event):
		keyname = gtk.gdk.keyval_name(event.keyval)
		if keyname == 'f':
			if self.enable_fps:
				self.status.hide()
				self.enable_fps = False
			else:
				self.status.show()
				self.enable_fps = True
		elif keyname == 'F':
			if self.fullscreen:
				self.window.unfullscreen()
				self.fullscreen = False
			else:
				self.window.fullscreen()
				self.fullscreen = True
		elif keyname == 'q':
			gtk.main_quit()

	def move(self):
		for i in range(len(self.shapes)):
			self.shapes[i].insert(0, Shape(self.shapes[i][0]))
			self.shapes[i][0].move()

			for j in range(1, len(self.shapes[i])):
				if not self.shapes[i][j].fade_out():
					self.shapes[i].pop(j)

		return True

	def init_palette(self, colors, shades):
		w0 = 2*math.pi/colors
		A = 65535/2
		fi0 = 0
		fi1 = 2*math.pi/3
		fi2 = 4*math.pi/3

		self.palette = []
		for i in range(colors):
			r = int(A*math.sin(w0*i + fi0) + A)
			g = int(A*math.sin(w0*i + fi1) + A)
			b = int(A*math.sin(w0*i + fi2) + A)

			shade = []
			for j in range(shades):
				gc = self.darea.window.new_gc()
				color = self.colormap.alloc_color(
						r*j/shades,
						g*j/shades,
						b*j/shades)
				gc.set_foreground(color)
				shade.append(gc)
			self.palette.append(shade)

	def update_fps(self):
		if self.enable_fps:
			fps = "fps: %d" % self.counter
			self.status.push(self.context, fps)

		self.counter = 0

		return True

if __name__ == '__main__':
	random.seed()

	ScreenSaver()

	gtk.main()

Here is a small screenshot of the ported screensaver in action: click here.