On Tue, 2008-06-17 at 11:06 +0200, Frédéric Mantegazza wrote:
> On mardi 17 juin 2008, John Stowers wrote:
> 
> > > > bzr branch http://johnstowers.co.nz/bzr/pygtk-lcd-widget/
> > >
> > > Many thanks, but I can't get the package: bzr waits forever, after
> > > creating the pygtk-lcd-widget/ dir and .bzr/ sub-dir...
> >
> > Are you sure?
> >
> > I just did a fresh checkout on another pc and it worked fine
> 
> With this command?:
> 
> $ bzr branch http://johnstowers.co.nz/bzr/pygtk-lcd-widget/
> 
> (I'm not familiar with bazar...). As I said, some files are first 
> downloaded (I can see a progressbar going to 100%), then, it does nothing, 
> and does not return...

Weird, maybe a bzr bug. What does the output with 

bzr branch http://johnstowers.co.nz/bzr/pygtk-lcd-widget/ --verbose

say? Can anyone else test this. You can zoom in and out with scroll
wheel (and change brightness with ctrl+scroll). Double click to change
text.

I attached the files also.



> 
# Character set for the Squeezebox display

00
00000
00000
00000
00000
00000
00000
00000

01
00000
00000
00000
00000
00000
00000
00000

02
00000
00000
00000
00000
00000
00000
00000

03
00000
00000
00000
00000
00000
00000
00000

04
00000
00000
00000
00000
00000
00000
00000

05
00000
00000
00000
00000
00000
00000
00000

06
00000
00000
00000
00000
00000
00000
00000

07
00000
00000
00000
00000
00000
00000
00000

08
00000
00000
00000
00000
00000
00000
00000

09
00000
00000
00000
00000
00000
00000
00000

0a
00000
00000
00000
00000
00000
00000
00000

0b
00000
00000
00000
00000
00000
00000
00000

0c
00000
00000
00000
00000
00000
00000
00000

0d
00000
00000
00000
00000
00000
00000
00000

0e
00000
00000
00000
00000
00000
00000
00000

0f
00000
00000
00000
00000
00000
00000
00000

10
10000
10000
10000
10000
10000
10000
10000

11
11000
11000
11000
11000
11000
11000
11000

12
11100
11100
11100
11100
11100
11100
11100

13
11110
11110
11110
11110
11110
11110
11110

14
11111
11111
11111
11111
11111
11111
11111

15
01111
01111
01111
01111
01111
01111
01111

16
00111
00111
00111
00111
00111
00111
00111

17
00011
00011
00011
00011
00011
00011
00011

18
00001
00001
00001
00001
00001
00001
00001

19
00100
00110
00101
00101
01101
11100
01100

1a
11000
11000
00000
00111
01000
01000
00111

1b
11000
11000
00000
01111
01000
01110
01000

1c
00000
00000
11111
01110
00100
00000
00000

1d
00000
01000
01100
01110
01100
01000
00000

1e
00000
00010
00110
01110
00110
00010
00000

1f
00000
00000
00100
01110
11111
00000
00000

20
00000
00000
00000
00000
00000
00000
00000

21
00100
00100
00100
00100
00000
00000
00100

22
01010
01010
01010
00000
00000
00000
00000

23
01010
01010
11111
01010
11111
01010
01010

24
00100
01111
10100
01110
00101
11110
00100

25
11000
11001
00010
00100
01000
10011
00011

26
01100
10010
10100
01000
10101
10010
01101

27
01100
00100
01000
00000
00000
00000
00000

28
00010
00100
01000
01000
01000
00100
00010

29
10000
01000
00100
00100
00100
01000
10000

2a
00000
00100
10101
01110
10101
00100
00000

2b
00000
00100
00100
11111
00100
00100
00000

2c
00000
00000
00000
00000
01100
00100
01000

2d
00000
00000
00000
11111
00000
00000
00000

2e
00000
00000
00000
00000
00000
11000
11000

2f
00000
00001
00010
00100
01000
10000
00000

30
01110
10001
10011
10101
11001
10001
01110

31
00100
01100
00100
00100
00100
00100
01110

32
01110
10001
00001
00010
00100
01000
11111

33
11111
00010
00100
00010
00001
10001
01110

34
00010
00110
01010
10010
11111
00010
00010

35
11111
10000
11110
00001
00001
10001
01110

36
00110
01000
10000
11110
10001
10001
01110

37
11111
00001
00010
00100
01000
01000
01000

38
01110
10001
10001
01110
10001
10001
01110

39
01110
10001
10001
01111
00001
00010
01100

3a
00000
01100
01100
00000
01100
01100
00000

3b
00000
01100
01100
00000
01100
00100
01000

3c
00010
00100
01000
10000
01000
00100
00010

3d
00000
00000
11111
00000
11111
00000
00000

3e
10000
01000
00100
00010
00100
01000
10000

3f
01110
10001
00001
00010
00100
00000
00100

40
01110
10001
00001
01101
10101
10101
01110

41
01110
10001
10001
10001
11111
10001
10001

42
11110
10001
10001
11110
10001
10001
11110

43
01110
10001
10000
10000
10000
10001
01110

44
11100
10010
10001
10001
10001
10010
11100

45
11111
10000
10000
11110
10000
10000
11111

46
11111
10000
10000
11110
10000
10000
10000

47
01110
10001
10000
10111
10001
10001
01111

48
10001
10001
10001
11111
10001
10001
10001

49
01110
00100
00100
00100
00100
00100
01110

4a
00111
00010
00010
00010
00010
10010
01100

4b
10001
10010
10100
11000
10100
10010
10001

4c
10000
10000
10000
10000
10000
10000
11111

4d
10001
11011
10101
10101
10001
10001
10001

4e
10001
10001
11001
10101
10011
10001
10001

4f
01110
10001
10001
10001
10001
10001
01110

50
11110
10001
10001
11110
10000
10000
10000

51
01110
10001
10001
10001
10101
10010
01101

52
11110
10001
10001
11110
10100
10010
10001

53
01111
10000
10000
01110
00001
00001
11110

54
11111
00100
00100
00100
00100
00100
00100

55
10001
10001
10001
10001
10001
10001
01110

56
10001
10001
10001
10001
10001
01010
00100

57
10001
10001
10001
10101
10101
10101
01010

58
10001
10001
01010
00100
01010
10001
10001

59
10001
10001
10001
01010
00100
00100
00100

5a
11111
00001
00010
00100
01000
10000
11111

5b
01110
01000
01000
01000
01000
01000
01110

5c
10001
01010
11111
00100
11111
00100
00100

5d
01110
00010
00010
00010
00010
00010
01110

5e
00100
01010
10001
00000
00000
00000
00000

5f
00000
00000
00000
00000
00000
00000
11111

60
01000
00100
00010
00000
00000
00000
00000

61
00000
00000
01110
00001
01111
10001
01111

62
10000
10000
10000
10110
11001
10001
11110

63
00000
00000
01110
10000
10000
10001
01110

64
00001
00001
00001
01101
10011
10001
01111

65
00000
00000
01110
10001
11111
10000
01110

66
00110
01001
01000
11100
01000
01000
01000

67
00000
01111
10001
10001
01111
00001
01110

68
10000
10000
10110
11001
10001
10001
10001

69
00000
00100
00000
01100
00100
00100
01110

6a
00010
00000
00110
00010
00010
10010
01100

6b
01000
01000
01001
01010
01100
01010
01001

6c
01100
00100
00100
00100
00100
00100
01110

6d
00000
00000
11010
10101
10101
10001
10001

6e
00000
00000
10110
11001
10001
10001
10001

6f
00000
00000
01110
10001
10001
10001
01110

70
00000
00000
11110
10001
11110
10000
10000

71
00000
00000
01101
10011
01111
00001
00001

72
00000
00000
10110
11001
10000
10000
10000

73
00000
00000
01110
10000
01110
00001
11110

74
01000
01000
11100
01000
01000
01001
00110

75
00000
00000
10001
10001
10001
10011
01101

76
00000
00000
10001
10001
10001
01010
00100

77
00000
00000
10001
10001
10001
10101
01010

78
00000
00000
10001
01010
00100
01010
10001

79
00000
00000
10001
10001
01111
00001
01110

7a
00000
00000
11111
00010
00100
01000
11111

7b
00010
00100
00100
10000
00100
00100
00010

7c
00100
00100
00100
00100
00100
00100
00100

7d
01000
00100
00100
00010
00100
00100
01000

7e
00000
00100
00010
11111
00010
00100
00000

7f
00000
00100
01000
11111
01000
00100
00000

80
01010
00000
00100
01010
10001
11111
10001

81
00100
00000
00100
01010
10001
11111
10001

82
00100
01010
00100
01010
10001
11111
10001

83
00010
00100
01110
00001
01111
10001
01111

84
00100
00000
01110
00001
01111
10001
01111

85
11111
11000
11000
11111
11000
11000
11111

86
10001
01110
10001
10001
10001
10001
01110

87
00000
01010
00000
01110
10001
10001
01110

88
00001
01110
10011
10101
11001
01110
10000

89
00000
00010
01110
10101
10101
01110
01000

8a
10001
00000
10001
10001
10001
10001
01110

8b
00000
01010
00000
10001
10001
10011
01101

8c
00000
10000
01000
00100
00010
00001
00000

8d
00001
00010
11111
00100
11111
01000
10000

8e
00000
01000
10101
10101
00010
00000
00000

8f
01111
10000
01110
10001
01110
00001
11110

90
01110
10100
10100
11111
10100
10100
10111

91
00000
00000
11010
00101
11111
10100
01011

92
00110
01001
01000
11110
01000
01000
11111

93
11100
10010
11100
10010
10111
10010
10011

94
00000
01110
11111
11111
11111
01110
00000

95
00000
01110
10001
10001
10001
01110
00000

96
00000
00100
01110
11111
01110
00100
00000

97
00000
00100
01010
10001
01010
00100
00000

98
00100
00100
00100
00000
00100
00100
00100

99
01111
10000
10000
10000
01111
00100
01000

9a
00000
00001
00011
00101
01001
10001
11111

9b
00010
00100
01000
00100
00010
00000
11111

9c
01000
00100
00010
00100
01000
00000
11111

9d
00001
00001
00101
01001
11111
01000
00100

9e
00100
01110
10101
00100
00100
00100
00100

9f
00100
00100
00100
00100
10101
01110
00100

a0
00000
00000
00000
00000
00000
00000
00000

a1
00000
00000
00000
00000
11100
10100
11100

a2
00111
00100
00100
00100
00000
00000
00000

a3
00000
00000
00000
00100
00100
00100
11100

a4
00000
00000
00000
00000
10000
01000
00100

a5
00000
00000
00000
01100
01100
00000
00000

a6
00000
11111
00001
11111
00001
00010
00100

a7
00000
00000
11111
00001
00110
00100
01000

a8
00000
00000
00010
00100
01100
10100
00100

a9
00000
00000
00100
11111
10001
00001
00110

aa
00000
00000
00000
11111
00100
00100
11111

ab
00000
00000
00010
11111
00110
01010
10010

ac
00000
00000
01000
11111
01001
01010
01000

ad
00000
00000
00000
01110
00010
00010
11111

ae
00000
00000
11110
00010
11110
00010
11110

af
00000
00000
00000
10101
101010
00001
00110

b0
00000
00000
00000
11111
00000
00000
00000

b1
11111
00001
00101
00110
00100
00100
01000

b2
00001
00010
00100
01100
10100
00100
00100

b3
00100
11111
10001
10001
00001
00010
00100

b4
00000
11111
00100
00100
00100
00100
11111

b5
00010
11111
00010
00110
01010
10010
00010

b6
01000
11111
01001
01001
01001
01001
10010

b7
00100
11111
00100
11111
00100
00100
00100

b8
00000
01111
01001
10001
00001
00010
01100

b9
01000
01111
10010
00010
00010
00010
00100

ba
00000
11111
00001
00001
00001
00001
11111

bb
01010
11111
01010
01010
00010
00100
01000

bc
00000
11000
00001
11001
00001
00010
11100

bd
00000
11111
00001
00010
00100
01010
10001

be
01000
11111
01001
01010
01000
01000
00111

bf
00000
10001
10001
01001
00001
00010
01100

c0
00000
01111
01001
10101
00011
00010
11000

c1
00010
11100
00100
11111
00100
00100
01000

c2
00000
10101
10101
10101
00001
00010
00100

c3
01110
00000
11111
00100
00100
00100
01000

c4
01000
01000
01000
01100
01010
01000
01000

c5
00100
00100
11111
00100
00100
01000
10000

c6
00000
01110
00000
00000
00000
00000
11111

c7
00000
11111
00001
01010
00100
01010
10000

c8
00100
11111
00010
00100
01110
10101
00100

c9
00010
00010
00010
00010
00010
00100
01000

ca
00000
00100
00010
10001
10001
10001
10001

cb
10000
10000
11111
10000
10000
10000
01111

cc
00000
11111
00001
00001
00001
00010
01100

cd
00000
01000
10100
00010
00001
00001
00000

ce
00100
11111
00100
00100
10101
10101
00100

cf
00000
11111
00001
00001
01010
00100
00010

d0
00000
01110
00000
01110
00000
01110
00000

d1
00000
00100
01000
10000
10001
11111
00001

d2
00000
00001
00001
01010
00100
01010
10000

d3
00000
11111
01000
11111
01000
01000
00111

d4
01000
01000
11111
01001
01010
01000
01000

d5
00000
01110
00010
00010
00010
00010
11111

d6
00000
11111
00001
11111
00001
00001
11111

d7
01110
00000
11111
00001
00001
00010
00100

d8
10010
10010
10010
10010
00010
00100
01000

d9
00000
00100
10100
10100
10101
10101
10110

da
00000
10000
10000
10001
10010
10100
11000

db
00000
11111
10001
10001
10001
10001
11111

dc
00000
11111
10001
10001
00001
00010
00100

dd
00000
11000
00000
00001
00001
00010
11100

de
00100
10010
01000
00000
00000
00000
00000

df
11100
10100
11100
00000
00000
00000
00000

e0
00000
00000
01001
10101
10010
10010
01101

e1
01010
00000
01110
00001
01111
10001
01111

e2
00000
01110
10001
11110
10001
11110
10000

e3
00000
00000
01110
10000
01100
10001
01110

e4
00000
10001
10001
10011
11101
10000
10000

e5
00000
00000
01111
10100
10010
10001
01110

e6
00000
00110
01001
10001
11110
10000
10000

e7
00000
00000
01111
10001
01111
00001
01110

e8
00000
00000
00111
00100
00100
10100
01000

e9
00010
11010
00010
00000
00000
00000
00000

ea
00000
00010
00000
00010
00010
10010
01100

eb
10100
01000
10100
00000
00000
00000
00000

ec
00000
00100
01110
10100
10101
01110
00100

ed
01000
01000
11100
01000
11100
01000
01111

ee
01110
00000
10110
11001
10001
10001
10001

ef
00000
01010
00000
01110
10001
10001
01110

f0
00000
10110
11001
10001
11110
10000
10000

f1
00000
01101
10011
10001
01111
00001
00001

f2
00000
01110
10001
11111
10001
10001
01110

f3
00000
00000
00000
01011
10101
11010
00000

f4
00000
00000
01110
10001
10001
01010
11011

f5
01010
00000
10001
10001
10001
10011
01101

f6
11111
10000
01000
00100
01000
10000
11111

f7
00000
00000
11111
01010
01010
01010
10011

f8
11111
00000
10001
01010
00100
01010
10001

f9
00000
00000
10001
10001
01111
00001
01110

fa
00000
00001
11110
00100
11111
00100
00100

fb
00000
00000
11111
01000
01111
01001
10001

fc
00000
00000
11111
10101
11111
10001
10001

fd
00000
00100
00000
11111
00000
00100
00000

fe
00000
00000
00000
00000
00000
00000
00000

ff
11111
11111
11111
11111
11111
11111
11111
#!/usr/bin/python
# -*- coding: latin1 -*-
#
# Copyright (C) 2005 Gerome Fournier <jefke(at)free.fr>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

"SLIMP3 player emulator written in python"

import gtk
import gtk.glade
import sys
import signal
import struct
import socket
import random

_CHARS_FILENAME = "lcd_chars.txt"
_GLADE_FILENAME = "gslimp3.glade"

_KEY_MAPPING = {
	"0": '0',
	"1": '1',
	"2": '2',
	"3": '3',
	"4": '4',
	"5": '5',
	"6": '6',
	"7": '7',
	"8": '8',
	"9": '9',
	"KP_0": '0',
	"KP_1": '1',
	"KP_2": '2',
	"KP_3": '3',
	"KP_4": '4',
	"KP_5": '5',
	"KP_6": '6',
	"KP_7": '7',
	"KP_8": '8',
	"KP_9": '9',
	"UP": 'UP',
	"RIGHT": 'RIGHT',
	"LEFT": 'LEFT',
	"DOWN": 'DOWN',
	"PAGE_UP": 'VOLUP',
	"PAGE_DOWN": 'VOLDOWN',
	"HOME": 'NOW_PLAYING',
	"RETURN": 'PLAY',
	"KP_ENTER": 'PLAY',
	"SPACE": 'PAUSE',
	"BRACKETLEFT": 'REW',
	"BRACKETRIGHT": 'FWD',
	"PLUS": 'ADD',
	"KP_ADD": 'ADD',
	"SLASH": 'SEARCH',
	"KP_DIVIDE": 'SEARCH',
	"A": 'SLEEP',
	"B": 'BRIGHTNESS',
	"F": 'SIZE',
	"R": 'REPEAT',
	"S": 'SHUFFLE',
}

class LCDWidget:
	"GTK+ LCD Widget"

	def __init__(self, widget, rows, cols):
		"Instantiate a LCD widget"
		self.rows = rows
		self.cols = cols
		self._area = widget
		self._pix = None
		self._table = {}
		self._area.connect("configure-event", self._configure_cb)
		self._area.connect("expose-event", self._expose_cb)

	def set_zoom_factor(self, factor):
		"Set the zoom factor"
		self._factor = factor
		self._border = 5
		self._cborder = 3*factor
		self._cwidth = 9*factor
		self._cheight = 13*factor
		self._width = 2*self._border + \
				(self._cwidth+self._cborder)*self.cols + self._cborder
		self._height = 2*self._border + \
				(self._cheight+self._cborder)*self.rows + self._cborder
		self._area.set_size_request(self._width, self._height)
		
	def get_zoom_factor(self):
		return self._factor

	def refresh(self):
		"Refresh the LCD widget"
		self._area.queue_draw_area(0, 0, self._width, self._height)

	def draw_char(self, row, col, charindex):
		"""Draw the character stored at position 'charindex' in the internal
		   character definition table, on the LCD widget
		"""
		if not self._pix:
			return
		x = col * (self._cwidth+self._cborder) + self._border + self._cborder
		y = row * (self._cheight+self._cborder) + self._border + self._cborder
		self._pix.draw_drawable(self._back, self._table[charindex], \
				0, 0, x, y, self._cwidth, self._cheight)

	def set_brightness_percentage(self, percentage):
		fg_colors = {
			100: "#00ff96",
			75: "#00d980",
			50: "#00b269",
			25: "#008c53",
			0: "#303030"
		}
		if percentage not in fg_colors.keys():
			return
		if hasattr(self, "_brightness_percentage") \
			and self._brightness_percentage == percentage:
			return
		self._brightness_percentage = percentage
		self._set_colors(["#000000", "#303030", fg_colors[percentage]])
		self._load_font_definition()
		
	def get_brightness_percentage(self):
		return self._brightness_percentage

	def clear(self):
		"Clear the LCD display"
		for row in range(self.rows):
			for col in range(self.cols):
				self.draw_char(row, col, 32)
		self.refresh()

	def set_button_press_event_cb(self, cb):
		"Setup a callback when a mouse button is pressed on the LCD display"
		self._area.add_events(gtk.gdk.BUTTON_PRESS_MASK)
		self._area.connect("button_press_event", cb)

	def set_scroll_event_cb(self, cb):
		"Setup a callback when wheel mouse is used on the LCD display"
		self._area.connect("scroll_event", cb)

	def create_char(self, charindex, shape):
		"""Insert a new char in the character table definition,
		   at position 'charindex', based on 'shape'
		"""
		pix = gtk.gdk.Pixmap(self._area.window, self._cwidth, self._cheight)
		pix.draw_rectangle(self._back, True, 0, 0, self._cwidth, self._cheight)
		for x in range(5):
			for y in range(7):
				pix.draw_rectangle(self._charbg, True, \
					x*2*self._factor, y*2*self._factor, \
					self._factor, self._factor)
		for index in range(35):
			if shape[index] == "1":
				row = index / 5
				col = index - row*5
				pix.draw_rectangle(self._charfg, True, \
					col*2*self._factor, row*2*self._factor, \
					self._factor, self._factor)
		self._table[charindex] = pix

	def print_line(self, string):
		"Print a single line on the LCD display"
		self.clear()
		for i in range(len(string[:self.cols])):
			self.draw_char(0, i, ord(string[i]))
		self.refresh()

	def _configure_cb(self, widget, event):
		x, y, width, height = widget.get_allocation()
		self._pix = gtk.gdk.Pixmap(widget.window, width, height)
		self.set_brightness_percentage(100)
		self._pix.draw_rectangle(self._back, True, 0, 0, width, height)
		self._load_font_definition()
		self.clear()
		return True

	def _expose_cb(self, widget, event):
		if self._pix:
			widget.window.draw_drawable(self._back, self._pix, 0, 0, 0, 0, \
					self._width, self._height)
		return False

	def _set_colors(self, colors):
		for widget, color in zip(["_back", "_charbg", "_charfg"], colors):
			exec "self.%s = gtk.gdk.GC(self._pix)" % widget
			exec "self.%s.set_rgb_fg_color(gtk.gdk.color_parse('%s'))" \
				% (widget, color)

	def _load_font_definition(self):
		try:
			file = open(_CHARS_FILENAME)
		except IOError:
			print >>sys.stderr, "Unable to open font characters definition '%s'" \
					% _CHARS_FILENAME
			sys.exit(1)
		index = 1
		shape = ""
		for line in file.readlines():
			line = line.rstrip()
			if not line or line[0] == "#":
				continue
			if index == 1:
				char_index = int(line, 16)
			else:
				shape = ''.join([shape, line])
			index += 1
			if index == 9:
				self.create_char(char_index, shape)
				index = 1
				shape = ""

class Slimp3LCD(LCDWidget):
	"An LCD display abble to parse Slimp3 LCD display packets"
	_CODE_DELAY = 0
	_CODE_CMD = 2
	_CODE_DATA = 3

	_CMD_CLEAR = 0
	_CMD_HOME = 1
	_CMD_MODE = 2
	_CMD_DISPLAY = 3
	_CMD_SHIFT = 4
	_CMD_FUNC_SET = 5
	_CMD_CG_ADDR = 6
	_CMD_DD_ADDR = 7
	
	def parse_lcd_packet(self, lcd_packet):
		"Parse a SLIMP3 LCD packet"
		self.addr = 0
		self.shift = 1
		i = 0
		while i < len(lcd_packet)/2:
			chunk = socket.ntohs(struct.unpack("H", lcd_packet[i*2:i*2+2])[0])
			code = (chunk & 0xFF00) >> 8
			cmd = chunk & 0x00FF
			if code == self._CODE_DELAY:
				pass
			elif code == self._CODE_CMD:
				i += self._handle_command(cmd, lcd_packet[i*2:])
			elif code == self._CODE_DATA:
				row = self.addr / self.cols
				col = self.addr - self.cols*row
				self.draw_char(row, col, cmd)
				self._move_cursor(self.shift)
			i += 1
		self.refresh()

	def _handle_command(self, cmd, string):
		"Handle LCD commands"
		if cmd >> self._CMD_CLEAR == 1:
			self.clear()
			self.addr = 0
			self.shift = 1
		elif cmd >> self._CMD_HOME == 1:
			self.addr = 0
		elif cmd >> self._CMD_MODE == 1:
			if cmd & 2 != 0:
				self.shift = 1
			else:
				self.shift = -1
		elif cmd >> self._CMD_DISPLAY == 1:
			pass
		elif cmd >> self._CMD_SHIFT == 1:
			if cmd & 0x04:
				self.move_cursor(-1)
			else:
				self.move_cursor(1)
		elif cmd >> self._CMD_FUNC_SET == 1:
			return self._handle_function_set(cmd, string[2:4])
		elif cmd >> self._CMD_CG_ADDR == 1:
			return self._handle_char_definition(cmd, string[2:16])
		elif cmd >> self._CMD_DD_ADDR == 1:
			pass
		return 0

	def _handle_function_set(self, cmd, string):
		"Handle Brightness stuff"
		if ord(string[0]) == 3:
			self.set_brightness_percentage(100 - 25 * ord(string[1]))
			return 1
		else:
			return 0
		
	def _handle_char_definition(self, char, string):
		"Create a char as defined by 'string'"
		if len(string) != 14:
			print >>sys.stderr, "Character definition has a wrong size!"
			return 0
		shape = [' '] * 35
		index = (0x3f & char) >> 3;
		for i in range(7):
			line = ord(string[2*i + 1])
			for j in range(5):
				if 1 & (line >> (4 - j)):
					shape[i*5+j] = "1"
		self.create_char(index, shape)
		# defining a new char consume 7 extra command codes
		return 7

	def _move_cursor(self, shift):
		self.addr += shift
		if self.addr < 0:
			self.addr = 0
		elif self.addr > self.rows * self.cols - 1:
			self.addr = self.rows * self.cols - 1


class Slimp3Gui:
	"Main GUI"

	def __init__(self):
		"Instantiate the application"
		self._setup_widgets()
		self._set_zoom_factor(1)

	def run(self):
		"Start the application"
		try:
			signal.signal(signal.SIGINT, self._quit)
			signal.signal(signal.SIGTERM, self._quit)
			self._window.show_all()
			self.print_bollocks()
			gtk.main()
		except KeyboardInterrupt:
			self._quit()
		except:
			raise

	def _quit(self, *args):
		gtk.main_quit()

	def _setup_widgets(self):
		self._window = gtk.Window()
		self._window.hide()
		self._window.connect("destroy", self._quit)
		widget = gtk.DrawingArea()
		self._window.add(widget)
		self.lcd_display = Slimp3LCD(widget, 2, 40)
		self.lcd_display.set_button_press_event_cb(self.button_press_cb)
		self.lcd_display.set_scroll_event_cb(self.scroll_event_cb)
		
	def button_press_cb(self, widget, event):
		self.print_bollocks(start=random.randint(16,30))
		return True

	def scroll_event_cb(self, widget, event):
		change = 0
		
		if (event.state & gtk.gdk.CONTROL_MASK) == gtk.gdk.CONTROL_MASK:
			if event.direction == gtk.gdk.SCROLL_UP:
				change = 25
			elif event.direction == gtk.gdk.SCROLL_DOWN:
				change = -25

			p = self.lcd_display.get_brightness_percentage()
			self._set_brightness_percentage(p+change)
				

		else:
			if event.direction == gtk.gdk.SCROLL_UP:
				change = 1
			elif event.direction == gtk.gdk.SCROLL_DOWN:
				change = -1
			
			z = self.lcd_display.get_zoom_factor()
			self._set_zoom_factor(z+change)

		self.print_bollocks()
		return True

	def _set_zoom_factor(self, factor):
		if factor < 1:
			factor = 1
		if factor > 2:
			factor = 2
		self.lcd_display.set_zoom_factor(factor)
		
	def _set_brightness_percentage(self, percent):
		if percent < 0:
			percent = 0
		if percent > 100:
			percent = 100
		self.lcd_display.set_brightness_percentage(percent)
		
	def print_bollocks(self, start=16):
		self.lcd_display.clear()
		self.lcd_display.print_line("ABCDEFGHIJKLMNOPabcdefghij")
		for i in range(0,40):
			self.lcd_display.draw_char(1,i,start+i)
		self.lcd_display.refresh()
		
if __name__ == "__main__":
	if len(sys.argv) > 1:
		print >>sys.stderr, "Usage: %s\nSlimp3 client written in python." \
				% sys.argv[0]
		sys.exit(1)
	app = Slimp3Gui()
	app.run()

# vim: ts=4 sw=4 noet
_______________________________________________
pygtk mailing list   pygtk@daa.com.au
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/

Reply via email to