9bd064da6147e4c3788bce88047905a7990419bd
[minwii.git] / src / pgu / gui / surface.py
1 """
2 """
3 import pygame
4
5 def subsurface(s,r):
6 """Return the subsurface of a surface, with some help, checks.
7
8 <pre>subsurface(s,r): return surface</pre>
9 """
10 r = pygame.Rect(r)
11 if r.x < 0 or r.y < 0:
12 raise "gui.subsurface: %d %d %s"%(s.get_width(),s.get_height(),r)
13 w,h = s.get_width(),s.get_height()
14 if r.right > w:
15 r.w -= r.right-w
16 if r.bottom > h:
17 r.h -= r.bottom-h
18 assert(r.w >= 0 and r.h >= 0)
19 return s.subsurface(r)
20
21 class ProxySurface:
22 """
23 A surface-like object which smartly handle out-of-area blitting.
24
25 <pre>ProxySurface(parent, rect, real_surface=None, offset=(0, 0))</pre>
26
27 <p>only one of parent and real_surface should be supplied (non None)</p>
28 <dl>
29 <dt>parent<dd>a ProxySurface object
30 <dt>real_surface<dd>a pygame Surface object
31 </dl>
32
33 <strong>Variables</strong>
34
35 <dl>
36 <dt>mysubsurface<dd>a real and valid pygame.Surface object to be used
37 for blitting.
38 <dt>x, y<dd>if the proxy surface is lefter or higher than the parent,
39 x, y hold the diffs.
40 <dt>offset<dd>an optional feature which let you scroll the whole blitted
41 content.
42 </dl>
43 """
44 def __init__(self, parent, rect, real_surface, offset=(0, 0)):
45 self.offset = offset
46 self.x = self.y = 0
47 if rect.x < 0: self.x = rect.x
48 if rect.y < 0: self.y = rect.y
49 self.real_surface = real_surface
50 if real_surface == None:
51 self.mysubsurface = parent.mysubsurface.subsurface(
52 parent.mysubsurface.get_rect().clip(rect))
53 else:
54 self.mysubsurface = real_surface.subsurface(
55 real_surface.get_rect().clip(rect))
56 rect.topleft = (0, 0)
57 self.rect = rect
58
59 def blit(self, s, pos, rect=None):
60 if rect == None: rect = s.get_rect()
61 pos = (pos[0] + self.offset[0] + self.x, pos[1] + self.offset[1] + self.y)
62 self.mysubsurface.blit(s, pos, rect)
63
64 def subsurface(self, rect):
65 r = pygame.Rect(rect).move(self.offset[0] + self.x,
66 self.offset[1] + self.y)
67 return ProxySurface(self, r, self.real_surface)
68
69 def fill(self, color, rect=None):
70 if rect != None: self.mysubsurface.fill(color, rect)
71 else: self.mysubsurface.fill(color)
72 def get_rect(self): return self.rect
73 def get_width(self): return self.rect[2]
74 def get_height(self): return self.rect[3]
75 def get_abs_offset(): return self.rect[:2]
76 def get_abs_parent(): return self.mysubsurface.get_abs_parent()
77 def set_clip(self, rect=None):
78 if rect == None: self.mysubsurface.set_clip()
79 else:
80 rect = [rect[0] + self.offset[0] + self.x, rect[1] + self.offset[0] + self.y, rect[2], rect[3]]
81 self.mysubsurface.set_clip(rect)
82
83
84
85
86
87
88 class xProxySurface:
89 """
90 A surface-like object which smartly handle out-of-area blitting.
91
92 <pre>ProxySurface(parent, rect, real_surface=None, offset=(0, 0))</pre>
93
94 <p>only one of parent and real_surface should be supplied (non None)</p>
95 <dl>
96 <dt>parent<dd>a ProxySurface object
97 <dt>real_surface<dd>a pygame Surface object
98 </dl>
99
100 <strong>Variables</strong>
101
102 <dl>
103 <dt>mysubsurface<dd>a real and valid pygame.Surface object to be used
104 for blitting.
105 <dt>x, y<dd>if the proxy surface is lefter or higher than the parent,
106 x, y hold the diffs.
107 <dt>offset<dd>an optional feature which let you scroll the whole blitted
108 content.
109 </dl>
110 """
111 def __init__(self, parent, rect, real_surface, offset=(0, 0)):
112 self.offset = offset
113 self.x = self.y = 0
114 if rect[0] < 0: self.x = rect[0]
115 if rect[1] < 0: self.y = rect[1]
116 self.real_surface = real_surface
117 if real_surface == None:
118 self.mysubsurface = parent.mysubsurface.subsurface(parent.mysubsurface.get_rect().clip(rect))
119 else:
120 self.mysubsurface = real_surface.subsurface(real_surface.get_rect().clip(rect))
121 rect[0], rect[1] = 0, 0
122 self.rect = rect
123
124 def blit(self, s, pos, rect=None):
125 if rect == None: rect = s.get_rect()
126 pos = (pos[0] + self.offset[0] + self.x, pos[1] + self.offset[1] + self.y)
127 self.mysubsurface.blit(s, pos, rect)
128
129 def subsurface(self, rect): return ProxySurface(self, pygame.Rect(rect).move(self.offset[0] + self.x, self.offset[1] + self.y),self.real_surface)
130 def fill(self, color, rect=None):
131 if rect != None: self.mysubsurface.fill(color, rect)
132 else: self.mysubsurface.fill(color)
133 def get_rect(self): return self.rect
134 def get_width(self): return self.rect[2]
135 def get_height(self): return self.rect[3]
136 def get_abs_offset(): return self.rect[:2]
137 def get_abs_parent(): return self.mysubsurface.get_abs_parent()
138 def set_clip(self, rect=None):
139 if rect == None: self.mysubsurface.set_clip()
140 else:
141 rect = [rect[0] + self.offset[0] + self.x, rect[1] + self.offset[0] + self.y, rect[2], rect[3]]
142 self.mysubsurface.set_clip(rect)
143