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