Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/pgu/gui/surface.py
blob: 82d92d1320b73efd063e2f7e085f0ff248191d17 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
"""
"""
import pygame

def subsurface(s,r):
    """Return the subsurface of a surface, with some help, checks.
    
    <pre>subsurface(s,r): return surface</pre>
    """
    r = pygame.Rect(r)
    if r.x < 0 or r.y < 0:
        raise "gui.subsurface: %d %d %s"%(s.get_width(),s.get_height(),r)
    w,h = s.get_width(),s.get_height()
    if r.right > w:
        r.w -= r.right-w
    if r.bottom > h:
        r.h -= r.bottom-h
    assert(r.w >= 0 and r.h >= 0)
    return s.subsurface(r)

class ProxySurface:
    """
    A surface-like object which smartly handle out-of-area blitting.
    
    <pre>ProxySurface(parent, rect, real_surface=None, offset=(0, 0))</pre>
    
    <p>only one of parent and real_surface should be supplied (non None)</p>
    <dl>
    <dt>parent<dd>a ProxySurface object
    <dt>real_surface<dd>a pygame Surface object
    </dl>
  
    <strong>Variables</strong>  
    
    <dl>
    <dt>mysubsurface<dd>a real and valid pygame.Surface object to be used
                       for blitting.
    <dt>x, y<dd>if the proxy surface is lefter or higher than the parent,
                x, y hold the diffs.
    <dt>offset<dd>an optional feature which let you scroll the whole blitted
                  content.
    </dl>
    """
    def __init__(self, parent, rect, real_surface, offset=(0, 0)):
        self.offset = offset
        self.x = self.y = 0
        if rect.x < 0: self.x = rect.x
        if rect.y < 0: self.y = rect.y
        self.real_surface = real_surface
        if real_surface == None:
            self.mysubsurface = parent.mysubsurface.subsurface(
                parent.mysubsurface.get_rect().clip(rect))
        else:
            self.mysubsurface = real_surface.subsurface(
                real_surface.get_rect().clip(rect))
        rect.topleft = (0, 0)
        self.rect = rect
        
    def blit(self, s, pos, rect=None):
        if rect == None: rect = s.get_rect()
        pos = (pos[0] + self.offset[0] + self.x, pos[1] + self.offset[1] + self.y)
        self.mysubsurface.blit(s, pos, rect)
        
    def subsurface(self, rect): 
        r = pygame.Rect(rect).move(self.offset[0] + self.x, 
                                   self.offset[1] + self.y)
        return ProxySurface(self, r, self.real_surface)

    def fill(self, color, rect=None): 
        if rect != None: self.mysubsurface.fill(color, rect)
        else: self.mysubsurface.fill(color)
    def get_rect(self): return self.rect
    def get_width(self): return self.rect[2]
    def get_height(self): return self.rect[3]
    def get_abs_offset(): return self.rect[:2]
    def get_abs_parent(): return self.mysubsurface.get_abs_parent()
    def set_clip(self, rect=None): 
        if rect == None: self.mysubsurface.set_clip()
        else: 
            rect = [rect[0] + self.offset[0] + self.x, rect[1] + self.offset[0] + self.y, rect[2], rect[3]]
            self.mysubsurface.set_clip(rect)






class xProxySurface:
    """
    A surface-like object which smartly handle out-of-area blitting.
    
    <pre>ProxySurface(parent, rect, real_surface=None, offset=(0, 0))</pre>
    
    <p>only one of parent and real_surface should be supplied (non None)</p>
    <dl>
    <dt>parent<dd>a ProxySurface object
    <dt>real_surface<dd>a pygame Surface object
    </dl>
  
    <strong>Variables</strong>  
    
    <dl>
    <dt>mysubsurface<dd>a real and valid pygame.Surface object to be used
                       for blitting.
    <dt>x, y<dd>if the proxy surface is lefter or higher than the parent,
                x, y hold the diffs.
    <dt>offset<dd>an optional feature which let you scroll the whole blitted
                  content.
    </dl>
    """
    def __init__(self, parent, rect, real_surface, offset=(0, 0)):
        self.offset = offset
        self.x = self.y = 0
        if rect[0] < 0: self.x = rect[0]
        if rect[1] < 0: self.y = rect[1]
        self.real_surface = real_surface
        if real_surface == None:
            self.mysubsurface = parent.mysubsurface.subsurface(parent.mysubsurface.get_rect().clip(rect))
        else:
            self.mysubsurface = real_surface.subsurface(real_surface.get_rect().clip(rect))
        rect[0], rect[1] = 0, 0
        self.rect = rect
        
    def blit(self, s, pos, rect=None):
        if rect == None: rect = s.get_rect()
        pos = (pos[0] + self.offset[0] + self.x, pos[1] + self.offset[1] + self.y)
        self.mysubsurface.blit(s, pos, rect)
        
    def subsurface(self, rect): return ProxySurface(self, pygame.Rect(rect).move(self.offset[0] + self.x, self.offset[1] + self.y),self.real_surface)
    def fill(self, color, rect=None): 
        if rect != None: self.mysubsurface.fill(color, rect)
        else: self.mysubsurface.fill(color)
    def get_rect(self): return self.rect
    def get_width(self): return self.rect[2]
    def get_height(self): return self.rect[3]
    def get_abs_offset(): return self.rect[:2]
    def get_abs_parent(): return self.mysubsurface.get_abs_parent()
    def set_clip(self, rect=None): 
        if rect == None: self.mysubsurface.set_clip()
        else: 
            rect = [rect[0] + self.offset[0] + self.x, rect[1] + self.offset[0] + self.y, rect[2], rect[3]]
            self.mysubsurface.set_clip(rect)