Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

About this user

Korakot Chaovavanich http://korakot.stumbleupon.com

« Newer Snippets
Older Snippets »
Showing 1-8 of 8 total  RSS 

Using <font> (font tag) within pys60 Text widget

The Text widget allow rich text. However, it's quite
difficult to use. You need to set each attribute
(font, style, highlight, color) of the widget
before adding more text with differert style.

So, I make a function that make it a bit easier.
The font tag (<font></font>) is used (borrowed from HTML).
Attributes allowed are
- color ( #RRGGBB or 0xRRGGBB or color name)
- face ( both font and size eg. albi17b )
- style ( bold, italic, underline or strikethrough )
(styles can be combined using comma)
- highlight ( standard, rounded, shadow)
- hcolor ( highlight color )
   1  
   2  from appuifw import *
   3  
   4  def process_color(color):
   5      color_name = {
   6          'red': 0xff0000, 'green': 0x008000, 'blue':0x0000ff,       
   7          'black': 0,      'white':0xffffff,      'yellow': 0xffff00
   8          }
   9      if color.startswith('#'):   # HTML format #000000
  10          return int(color[1:], 16)
  11      if color.startswith('0x'):  # pys60 format 0x000000
  12          return int(color, 16)
  13      return color_name[color]
  14  
  15  def set_ml(t, s):
  16      stack = []
  17      t.clear()
  18      t.font = 'normal'
  19      i = 0
  20      while i < len(s):
  21          if s.startswith('<', i):  # tag end or tag begin
  22              j = s.find('>', i) + 1
  23              if s[i:i+7] == '</font>' or s[i:i+3] == '</>':
  24                  t.color, t.font, t.style, t.highlight_color = stack.pop()
  25              else:
  26                  stack.append([t.color, t.font, t.style, t.highlight_color])
  27                  to_style = 0
  28                  for attr_val in s[i:j-1].split(' '):
  29                      if '=' in attr_val:
  30                          attr, val = attr_val.split('=')
  31                          if attr == 'color':
  32                              t.color = process_color(val)
  33                          elif attr == 'face':
  34                              t.font = unicode(val)
  35                          elif attr == 'hcolor':
  36                              t.highlight_color = process_color(val)
  37                          elif attr == 'style':   # style and highlight go together
  38                              to_style |= eval('|'.join(['STYLE_' + st.upper() for st in val.split(',')]))
  39                          elif attr == 'highlight':
  40                              to_style |= eval("HIGHLIGHT_" + val.upper())
  41                  if to_style:
  42                      t.style = to_style
  43          else:    # normal text
  44              j = s.find('<', i)
  45              if j == -1: j = len(s)
  46              text = u'' + s[i:j].replace('&lt;', '<')
  47              t.add(text)
  48          i = j      # go next chunk
  49  

Now you can use it easily
   1  
   2  >>> t = app.body   # use the default Text widget that start pys60
   3  >>> set_ml(t, '<font color=red>Hello</font> <font style=bold>World</font>.')
   4  >>>  # a stylish 'Hello World' is displayed

Notice:
- Quotation marks are not used to specify attribute values.
- A </> shorthand can be used for </font>
- <font> can be nested.

HTML 4.0 color names

There are 16 of them
   1  
   2  Black  	#000000
   3  Silver 	#C0C0C0
   4  Gray 	#808080
   5  White 	#FFFFFF
   6  Maroon 	#800000
   7  Red 	#FF0000
   8  Purple 	#800080
   9  Fuchsia #FF00FF
  10  Green 	#008000
  11  Lime 	#00FF00
  12  Olive 	#808000
  13  Yellow 	#FFFF00
  14  Navy 	#000080
  15  Blue 	#0000FF
  16  Teal 	#008080
  17  Aqua 	#00FFFF

From this page.

Color picker

I saw someone write a fileselect dialog a few days ago.
I think we should have more dialog type to use in our apps.
So, I write a color picker code below.
It can be converted easily into a dialog component.

   1  
   2  // Usual code as always
   3  import e32
   4  from appuifw import *
   5  from key_codes import *
   6  
   7  class Keyboard(object):
   8      def __init__(self):
   9          self.state = {}  # is this key pressing ?
  10          self.buffer= {}  # is it waiting to be processed ?
  11      def handle_event(self, event): # for event_callback
  12          code = event['scancode']
  13          if event['type'] == EEventKeyDown:
  14              self.buffer[code]= 1   # put into queue
  15              self.state[code] = 1
  16          elif event['type'] == EEventKeyUp:
  17              self.state[code] = 0
  18      def pressing(self, code):      # just check
  19          return self.state.get(code,0)
  20      def pressed(self, code):       # check and process the event
  21          if self.buffer.get(code,0):
  22              self.buffer[code] = 0  # take out of queue
  23              return 1
  24          return 0
  25  
  26  key = Keyboard()
  27  app.body = canvas = Canvas(event_callback=key.handle_event)
  28  
  29  def quit():
  30      global running
  31      running = 0
  32  
  33  app.exit_key_handler = quit
  34  running = 1

At first, I wanted to use the standard palette of s60.
But later decide to just use 216 web-safe colors.
The code is simpler, so the concept is easier to understand.
   1  
   2  ff00 = range(0xff, -1, -0x33)
   3  pal = [(r,g,b) for r in ff00 for g in ff00 for b in ff00]  # web-safe
   4  map_j = range(0,12,2)+range(11,0,-2)  # make better grouping
   5  for j in range(12):
   6      for i in range(18):
   7          k = 18*map_j[j] + i
   8          canvas.rectangle([(9*i+1, 9*j+1), (9*i+9, 9*j+9)], None, pal[k])
   9  
  10  def clear_box(color=0xffffff):
  11      global x,y
  12      canvas.rectangle([(9*x, 9*y), (9*x+10, 9*y+10)], color)  # cursor
  13  
  14  x, y = 0, 0
  15  black_white = 0
  16  while running:
  17      if key.pressed(EScancodeLeftArrow):
  18          clear_box()
  19          if x > 0: x -= 1
  20      if key.pressed(EScancodeRightArrow):
  21          clear_box()
  22          if x < 17: x += 1
  23      if key.pressed(EScancodeUpArrow):
  24          clear_box()
  25          if y > 0: y -= 1
  26      if key.pressed(EScancodeDownArrow):
  27          clear_box()
  28          if y < 11: y += 1
  29      if key.pressed(EScancodeSelect):
  30          color = pal[18*map_j[y] + x]
  31          canvas.rectangle([(1,109), (17*9+9,130)], None, color)  # show color
  32      black_white ^= 0xffffff  # toggle
  33      clear_box(black_white)
  34      e32.ao_sleep(0.2)

See Screenshot.

Reading a 24-bit icon in an mbm file

Here's an example how I read the icon and display it on canvas
It's a continued part of my previous mbm hack.
   1  
   2  >>> from appuifw import *
   3  >>> from struct import unpack
   4  >>> def readL(f, pos=None):     # helping function
   5  ...     if pos is not None:
   6  ...         f.seek(pos)
   7  ...     return unpack('L', f.read(4))[0]
   8  ...
   9  >>> fxmbm = 'E:\\system\\apps\\FExplorer\\FExplorer.mbm'
  10  >>> f = open(fxmbm, 'rb')
  11  >>> trailer = readL(f, 16)
  12  >>> num = readL(f, trailer)   # 19 icons
  13  >>> offset = []
  14  >>> for i in range(num):
  15  ...   offset.append(readL(f))
  16  ...
  17  >>> offset
  18  [20L, 68L, 116L, 474L, 588L, 1038L, 1228L, 1636L, 1864L, 2277L, 2430L, 3735L, 41
  19  69L, 4569L, 4697L, 5197L, 5370L, 5897L, 6062L]
  20  >>> start = offset[2]  # folder icon
  21  >>> f.seek(start)
  22  >>> length = readL(f) - readL(f)    # length of data section
  23  >>> width, height = readL(f), readL(f)  # 16 x 13
  24  >>> f.seek(start+0x28)  # start of data section
  25  >>> data_enc = f.read(length)   # got the data
  26  >>> def rle24_decode(bytes):
  27  ...     out = []
  28  ...     i = 0
  29  ...     while i < len(bytes):
  30  ...         n = ord(bytes[i])
  31  ...         i += 1
  32  ...         if n < 0x80:
  33  ...             out.append( bytes[i:i+3] * (n+1) )
  34  ...             i += 3
  35  ...         else:
  36  ...             n = 0x100 - n
  37  ...             out.append( bytes[i:i+3*n] )
  38  ...             i += 3*n
  39  ...     return ''.join(out)
  40  ...
  41  >>> data = rel24_decode(data_enc)
  42  >>> app.body = canvas = Canvas()
  43  >>> for j in range(height):
  44  ...     for i in range(width):
  45  ...         p = 3*(j*width+i)
  46  ...         color = [ord(data[p+k]) for k in (2,1,0)]  # It's BGR
  47  ...         canvas.point((i,j), tuple(color))
  48  ...
  49  >>>  # folder icon is drawn on screen

Getting symbian's default palette table

After a night hacking what is the 8-bit color for mbm format.
I finally found this thead about standard palette.

So, I make this pallete mapping table to use with 8-bit icons.
   1  
   2  palette_string = '''0x00000000
   3  0x00CCFFFF
   4  0x0099FFFF
   5  0x0066FFFF
   6  0x0033FFFF
   7  0x0000FFFF
   8  0x00FFCCFF
   9  0x00CCCCFF
  10  0x0099CCFF
  11  0x0066CCFF
  12  0x0033CCFF
  13  0x0000CCFF
  14  0x00FF99FF
  15  0x00CC99FF
  16  0x009999FF
  17  0x006699FF
  18  0x003399FF
  19  0x000099FF
  20  0x00FF66FF
  21  0x00CC66FF
  22  0x009966FF
  23  0x006666FF
  24  0x003366FF
  25  0x000066FF
  26  0x00FF33FF
  27  0x00CC33FF
  28  0x009933FF
  29  0x006633FF
  30  0x003333FF
  31  0x000033FF
  32  0x00FF00FF
  33  0x00CC00FF
  34  0x009900FF
  35  0x006600FF
  36  0x003300FF
  37  0x000000FF
  38  0x00FFFFCC
  39  0x00CCFFCC
  40  0x0099FFCC
  41  0x0066FFCC
  42  0x0033FFCC
  43  0x0000FFCC
  44  0x00FFCCCC
  45  0x00CCCCCC
  46  0x0099CCCC
  47  0x0066CCCC
  48  0x0033CCCC
  49  0x0000CCCC
  50  0x00FF99CC
  51  0x00CC99CC
  52  0x009999CC
  53  0x006699CC
  54  0x003399CC
  55  0x000099CC
  56  0x00FF66CC
  57  0x00CC66CC
  58  0x009966CC
  59  0x006666CC
  60  0x003366CC
  61  0x000066CC
  62  0x00FF33CC
  63  0x00CC33CC
  64  0x009933CC
  65  0x006633CC
  66  0x003333CC
  67  0x000033CC
  68  0x00FF00CC
  69  0x00CC00CC
  70  0x009900CC
  71  0x006600CC
  72  0x003300CC
  73  0x000000CC
  74  0x00FFFF99
  75  0x00CCFF99
  76  0x0099FF99
  77  0x0066FF99
  78  0x0033FF99
  79  0x0000FF99
  80  0x00FFCC99
  81  0x00CCCC99
  82  0x0099CC99
  83  0x0066CC99
  84  0x0033CC99
  85  0x0000CC99
  86  0x00FF9999
  87  0x00CC9999
  88  0x00999999
  89  0x00669999
  90  0x00339999
  91  0x00009999
  92  0x00FF6699
  93  0x00CC6699
  94  0x00996699
  95  0x00666699
  96  0x00336699
  97  0x00006699
  98  0x00FF3399
  99  0x00CC3399
 100  0x00993399
 101  0x00663399
 102  0x00333399
 103  0x00003399
 104  0x00FF0099
 105  0x00CC0099
 106  0x00990099
 107  0x00660099
 108  0x00330099
 109  0x00000099
 110  0x00FFFF66
 111  0x00CCFF66
 112  0x0099FF66
 113  0x0066FF66
 114  0x0033FF66
 115  0x0000FF66
 116  0x00FFCC66
 117  0x00CCCC66
 118  0x0099CC66
 119  0x0066CC66
 120  0x0033CC66
 121  0x0000CC66
 122  0x00FF9966
 123  0x00CC9966
 124  0x00999966
 125  0x00669966
 126  0x00339966
 127  0x00009966
 128  0x00FF6666
 129  0x00CC6666
 130  0x00996666
 131  0x00666666
 132  0x00336666
 133  0x00006666
 134  0x00FF3366
 135  0x00CC3366
 136  0x00993366
 137  0x00663366
 138  0x00333366
 139  0x00003366
 140  0x00FF0066
 141  0x00CC0066
 142  0x00990066
 143  0x00660066
 144  0x00330066
 145  0x00000066
 146  0x00FFFF33
 147  0x00CCFF33
 148  0x0099FF33
 149  0x0066FF33
 150  0x0033FF33
 151  0x0000FF33
 152  0x00FFCC33
 153  0x00CCCC33
 154  0x0099CC33
 155  0x0066CC33
 156  0x0033CC33
 157  0x0000CC33
 158  0x00FF9933
 159  0x00CC9933
 160  0x00999933
 161  0x00669933
 162  0x00339933
 163  0x00009933
 164  0x00FF6633
 165  0x00CC6633
 166  0x00996633
 167  0x00666633
 168  0x00336633
 169  0x00006633
 170  0x00FF3333
 171  0x00CC3333
 172  0x00993333
 173  0x00663333
 174  0x00333333
 175  0x00003333
 176  0x00FF0033
 177  0x00CC0033
 178  0x00990033
 179  0x00660033
 180  0x00330033
 181  0x00000033
 182  0x00FFFF00
 183  0x00CCFF00
 184  0x0099FF00
 185  0x0066FF00
 186  0x0033FF00
 187  0x0000FF00
 188  0x00FFCC00
 189  0x00CCCC00
 190  0x0099CC00
 191  0x0066CC00
 192  0x0033CC00
 193  0x0000CC00
 194  0x00FF9900
 195  0x00CC9900
 196  0x00999900
 197  0x00669900
 198  0x00339900
 199  0x00009900
 200  0x00FF6600
 201  0x00CC6600
 202  0x00996600
 203  0x00666600
 204  0x00336600
 205  0x00006600
 206  0x00FF3300
 207  0x00CC3300
 208  0x00993300
 209  0x00663300
 210  0x00333300
 211  0x00003300
 212  0x00FF0000
 213  0x00CC0000
 214  0x00990000
 215  0x00660000
 216  0x00330000
 217  0x00000000
 218  0x00EEEEEE
 219  0x00DDDDDD
 220  0x00BBBBBB
 221  0x00AAAAAA
 222  0x00888888
 223  0x00777777
 224  0x00555555
 225  0x00444444
 226  0x00222222
 227  0x00111111
 228  0x00000000
 229  0x00000000
 230  0x00000000
 231  0x00000000
 232  0x00000000
 233  0x00000000
 234  0x00000000
 235  0x00000000
 236  0x00000000
 237  0x00000000
 238  0x00000000
 239  0x00000000
 240  0x00000000
 241  0x00000000
 242  0x00000000
 243  0x00000000
 244  0x00000000
 245  0x00000000
 246  0x00000000
 247  0x00000000
 248  0x00000000
 249  0x00000000
 250  0x00000000
 251  0x00000000
 252  0x00000000
 253  0x00000000
 254  0x00000000
 255  0x00000000
 256  0x00000000
 257  0x00FFFFFF'''

Split and map them into (RR, GG, BB) array
   1  
   2  palette = [tuple([int(col[i:i+2], 16) for i in range(8,2,-2)]) for col in palette_string.split('\n')]

Last night, I lost 3-4 hours figuring if 8-bit is a 8-bit true color.
I should have thought about standard palette and google them eariler.

updated
=======
I just notice the sequence pattern which should make the code shorter.
   1  
   2  ff00 = range(0xff, -1, -0x33)
   3  palette = [(r,g,b) for r in ff00 for g in ff00 for b in ff00] #0x336699
   4  palette[0] = (0,0,0)
   5  palette += [(17*i,17*i,17*i) for i in (14,13, 11,10, 8,7, 5,4, 2,1)] # grey
   6  palette += [(0,0,0) for i in range(30)]  # empty
   7  palette[-1] = (255,255,255)

get pixel colors of an image

I wrote a hack to get the color of a pixel.
Now pys60 1.2 has support for getpixel (though undocumented).
Cyke64 has shown me in an example.
   1  
   2  >>> from graphics import Image
   3  >>> im = Image.new((10,10))   # create a new 10x10 image
   4  >>> im.clear(0xff0000)        # make it all red
   5  >>> im.getpixel((0,0))   # top-left is red
   6  [(255, 0, 0)]
   7  >>> im.getpixel([(0,0), (10,10)])  # you can get multiple points
   8  [(255, 0, 0), (255, 0, 0)]
   9  >>> 

Get pixel colors of an image

Pys60 now has a decent Canvas and Image class.
We can draw many shapes and color them.
However, one important feature is missing, ie. getpixel().
So, you can only 'write' but not 'read' from graphics.

To get around this problem, I write a small library that
add 'getpixel' to the Image class.
Now, you can call im.getpixel(x,y) and get an (R,G,B) tuple.
   1  
   2  # some setup
   3  from graphics import *
   4  im = screenshot()  # sample image
   5  
   6  # http://larndham.net/service/pys60/getpixel.py
   7  import getpixel
   8  getpixel.enable(im)  # magically give Image.getpixel()
   9  r, g, b = im.getpixel(0,0)  # top left corner
  10  print 'Red: %s, Green:%s, Blue:%s' % (r,g,b)

Now you can do some easy image processing with getpixel.

Implementation note
===================
- This is a pure python module
- It saves an image as an uncompressed PNG file
- It reads pixel data from the file and attach it to the image.
- You need to call enable() every time you change the image.

Python syntax coloring for series60

The new Text() control allows rich text which can be
used for syntax coloring
(screenshot)
http://photos22.flickr.com/30187174_8598b800ec_o.jpg
   1  
   2  from appuifw import *
   3  from pyfontify import fontify
   4  import os, e32
   5  
   6  src = ur"""
   7  __version__ = "0.4"
   8  import string, re, keyword  
   9  commentPat = "#.*"  
  10  # Build up a regular expression
  11  pat = "q[^\q\n]*(\\\\[\000-\377][^\q\n]*)*q"
  12  """
  13  
  14  color = { 'keyword': 0x0000ff,
  15            'string': 0xff00ff,
  16            'comment': 0x008000,
  17            'function': 0x008080,
  18            'class': 0x008080 }
  19  
  20  t = Text()
  21  pos = 0
  22  for tag, start, end, sl in fontify(src):
  23      t.color = 0
  24      t.add(src[pos:start])
  25      t.color = color[tag]
  26      t.add(src[start:end])
  27      pos = end
  28  t.color = 0
  29  t.add(src[pos:])
  30  
  31  app.body = t
  32  e32.ao_sleep(10)

You first need to install the pyfontify module from here
http://linux.duke.edu/~mstenner/free-docs/diveintopython-3.9-1/py/pyfontify.py
« Newer Snippets
Older Snippets »
Showing 1-8 of 8 total  RSS