Прикреплённый файл «sqec.py»

Загрузка

   1 #!/usr/bin/env python
   2 # -*- coding: utf8 -*-
   3 # vim: ts=4:expandtab:sw=4
   4 '''
   5 Векторный редактор, версия 5:
   6     * Простые фигуры
   7     * Фокус
   8     * Изменение типа, заливки, цвета (без выбора)
   9     * Перемещение и изменение размера
  10     * Запись и чтение из файла (без выбора)
  11     * Ломаные и многоугольники
  12 '''
  13 import pygame, random, sys
  14 pygame.init()
  15 
  16 color, back, width = (255,25,255), (0,0,0), 2
  17 W,H=800,600
  18 screen = pygame.display.set_mode((W,H))
  19 # Типы фигур
  20 shapes = ['rect','line','circle','ellipse','poly']
  21 
  22 def resize(dots, rect):
  23     '''Превратить относительные (в %) координаты dots
  24     в абсолютные в рамках rect'''
  25     return [(int(x*rect.width/100+rect.left),int(y*rect.height/100+rect.top)) for x,y in dots]
  26 
  27 
  28 def draw_figure(scr, fig):
  29     '''Нарисовать фигуру fig на поверхности scr'''
  30     width=fig['empty'] and fig['width'] or 0
  31     rect,color,args=fig['rect'],fig['color'],fig['args']
  32     if not fig['shape']:
  33         return
  34     elif fig['shape'] == 'rect':
  35         pygame.draw.rect(scr,color,rect,width)
  36     elif fig['shape'] == 'line':
  37         pygame.draw.line(scr,color,rect.topleft,rect.bottomright,fig['width'])
  38     elif fig['shape'] == 'circle':
  39         r = max(min(rect.size)/2,width)
  40         pygame.draw.circle(scr,color,rect.center,r,width)
  41     elif fig['shape'] == 'ellipse':
  42         r = rect.union(pygame.Rect(0,0,width*2,width*2).clamp(rect))
  43         pygame.draw.ellipse(scr,color,r,width)
  44     elif fig['shape'] == 'poly':
  45         if not args:
  46             args=[rect.left,rect.top,rect.right,rect.bottom]
  47         args=[(int(x),int(y)) for x,y in zip(args[0::2],args[1::2])]
  48         if fig['empty']:
  49             pygame.draw.lines(scr,color,False,resize(args,rect),width)
  50         else:
  51             pygame.draw.polygon(scr,color,resize(args,rect),0)
  52     else:
  53         print >> sys.stderr, "'%s' unimplemented"%fig['shape']
  54 
  55 def draw_all(scr, figs):
  56     '''Нарисовать все фигуры figs на поверхности scr'''
  57     scr.fill(back)
  58     for f in figs:
  59         draw_figure(scr,f)
  60 
  61 def draw_2circle(scr, pos):
  62     '''Нарисовать чёрно-белую окружность'''
  63     pygame.draw.circle(scr, (255,255,255), pos, 2)
  64     pygame.draw.circle(scr, (0,0,0), pos, 3, 1)
  65 
  66 def draw_focus(scr, f):
  67     '''Нарисовать на фигуре f пометку о том, что она получила фокус'''
  68     draw_2circle(scr, f['rect'].topleft)
  69     draw_2circle(scr, f['rect'].topright)
  70     draw_2circle(scr, f['rect'].bottomleft)
  71     draw_2circle(scr, f['rect'].bottomright)
  72 
  73 def get_focus(figs, pos):
  74     'Какой из фигур в figs принадлежат координаты pos'
  75     for i in xrange(len(figs)-1, -1, -1):
  76         if figs[i]['rect'].collidepoint(pos):
  77             return i
  78     return 0
  79 
  80 def upfocus(f, figs):
  81     'Поднять фигуру f в figs на 1 слой'
  82     if f < len(figs)-1 and f>0:
  83         figs[f:f+2]=[figs[f+1],figs[f]]
  84         return f+1
  85     return len(figs) - 1
  86 
  87 def downfocus(f, figs):
  88     'Опустить фигуру f в figs на 1 слой (не ниже подложки)'
  89     if f > 1:
  90         figs[f-1:f+1]=[figs[f],figs[f-1]]
  91         return f-1
  92     return 0
  93 
  94 def random_color(grad=16,channel=255,grey=25):
  95     'Случайный цвет в диапазоне grey..channel (grad градаций каждого канала)'
  96     return [random.randint(0,grad-1)*(channel-grey)/(grad-1)+grey for i in xrange(3)]
  97 
  98 def gen_random(shape=shapes[0], size=[], pos=[], color=[], width=width, empty=True, args=[]):
  99     '''Сгенерировать фигуру (если параметр не задан, выбирается случайно)
 100     shape -- тип фигуры (по умолчанию 'rect')
 101     size -- размер
 102     pos -- координаты
 103     color -- цвет
 104     width -- ширина пера
 105     empty -- вид заливки (по умолчанию -- пустая)
 106     args -- дополнительные параметры
 107     '''
 108     col = color or random_color()
 109     x, y = pos or (random.randint(10,W-50), random.randint(10,H-50))
 110     w, h = size or (random.randint(50, W-x), random.randint(50, H-y))
 111     return { 'rect':pygame.Rect(x,y,w,h),
 112              'color':col,
 113              'width':width,
 114              'shape':shape,
 115              'empty':empty,
 116              'args':args,
 117            }
 118 
 119 def read_figure(name):
 120     'Прочитать фигуры из файла name'
 121     f = file(name,"r")
 122     W,H=[int(i) for i in f.readline().split()]
 123     fg=[]
 124     for s in f.readlines():
 125         l=s.split()
 126         if l[0] == 'color':
 127             color=[int(i) for i in l[1:]]
 128         elif l[0] == 'width':
 129             width = int(l[1])
 130         else:
 131             shape, rct, args  = l[0], [int(i) for i in l[1:5]], l[5:]
 132             empty = 'fill' not in args
 133             if not empty: args.pop(args.index('fill'))
 134             fg.append(gen_random(shape, rct[2:4], rct[:2], color, width, empty, args))
 135     f.close()
 136     return fg
 137 
 138 def select_filename():
 139     'TODO: выбор имени файла'
 140     return "figure"
 141 
 142 def write_figure(name):
 143     'Зпаисать фигуру в файл'
 144     f = file(name,"w")
 145     width,col = -1, (-1,-1,-1)
 146     print >> f, W, H    # размер
 147     print >> f, "width %d"%width
 148     for fig in figs[1:]:
 149         rect=fig['rect']
 150         if fig['color']!=col:
 151             print >> f, "color %d %d %d"%tuple(fig['color'])
 152             col=fig['color']
 153         if fig['width']!=width:
 154             width = fig['width']
 155             print >> f, "width %d"%fig['width']
 156         s="%d %d %d %d"%(rect.left,rect.top,rect.w,rect.h)
 157         a="".join([" %s"%c for c in fig['args']])
 158         print >> f, fig['shape'],s + a + (not fig['empty'] and ' fill' or '')
 159     f.close()
 160 
 161 backing = gen_random('rect',(W,H),(0,0),back)   # подложка
 162 figs = [backing.copy()]
 163 focus = 0
 164 debug= False
 165 while True:
 166     event = pygame.event.wait()
 167     if debug: print event
 168     if event.type == pygame.QUIT:
 169         sys.exit()
 170     elif event.type == pygame.MOUSEBUTTONDOWN:
 171         nfocus = get_focus(figs, event.pos)
 172         if event.button == 1:   # смена фокуса
 173             focus = nfocus
 174         elif event.button == 4: # поднять фигуру
 175             focus = upfocus(focus,figs)
 176         elif event.button == 5: # опустить фигуру
 177             focus = downfocus(focus,figs)
 178     elif event.type == pygame.MOUSEMOTION:
 179         if event.buttons[0]:    # переместить
 180             figs[focus]['rect'].move_ip(event.rel)
 181         elif event.buttons[2]:  # изменить размер
 182             figs[focus]['rect'].inflate_ip(event.rel)
 183     elif event.type == pygame.KEYDOWN:
 184         if event.key == 8:      # BackSpace - отладочная выдача
 185             debug = not debug
 186         elif event.key == 32:  # Space - случайный цвет
 187             figs[focus]['color']=random_color()
 188         elif event.key == 275:  # Right - увеличить ширину пера
 189             figs[focus]['width']+=1
 190         elif event.key == 276:  # Left - уменьшить ширину пера (>0)
 191             figs[focus]['width']=max(1,figs[focus]['width']-1)
 192         elif event.key == 274:  # Down - смениь тип заливки
 193             figs[focus]['empty']=not figs[focus]['empty']
 194         elif event.key == 273:  # Up - сменить тип фигуры
 195             if focus>=0:
 196                 newt=(shapes.index(figs[focus]['shape'])+1)%len(shapes)
 197                 figs[focus]['shape']=shapes[newt]
 198         elif event.key == 277:  # Ins - доавить ещё одну фигуру
 199             figs.append(gen_random(figs[focus]['shape'],empty=figs[focus]['empty']))
 200         elif event.key == 127:  # Del - удалить фигуру (кроме подложки)
 201             if len(figs)>1: figs.pop(focus)
 202             if focus>=len(figs):
 203                 focus=len(figs)-1
 204         elif event.key == 270:  # grey + - поднять фигуру
 205             focus = upfocus(focus,figs)
 206         elif event.key == 269:  # grey - - опустить фигуру
 207             focus = downfocus(focus,figs)
 208         elif event.key == 9:    # tab - сменить фокус
 209             focus = (focus + 1)%len(figs)
 210         elif event.key == 279:  # End - записать файл
 211             write_figure(select_filename())
 212         elif event.key == 278:  # Home - прочитать из файла
 213             figs=[backing.copy()]+read_figure(select_filename())
 214             focus=0
 215         elif event.key in range(48,56): # выбрать один из 8 цветов
 216             figs[focus]['color']=(
 217                                     ( event.key-48)   %2*220+30,
 218                                     ((event.key-48)/2)%2*220+30,
 219                                     ( event.key-48)/4   *220+30,
 220                                  )
 221     figs[0]=backing.copy()
 222     draw_all(screen, figs)
 223     if focus > 0:
 224         draw_focus(screen, figs[focus])
 225     pygame.display.flip()

Прикреплённые файлы

Для ссылки на прикреплённый файл в тексте страницы напишите attachment:имяфайла, как показано ниже в списке файлов. Не используйте URL из ссылки «[получить]», так как он чисто внутренний и может измениться.

Вам нельзя прикреплять файлы к этой странице.