~glitter-team/glitter/trunk

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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# !/usr/bin/python
# -*- coding: utf-8 -*-

# Glitter Toolkit

__authors__ = ["Jan Jokela <janjokela@gmail.com>"]
__licenses__ = ["LICENSE.LGPL"]
__description__ = "Image widget" 

import os
import sys

import clutter

from theme import Theme
from container import Container
from svg_image import SVGImage

class Image(Container):
    """ Glitter image widget 
    
    The Glitter Image widget derives from Container and represents an image.
    Images can be bitmaps, cairo textures or scalable vector graphics. If the 
    source_scalable flag is enabled, the source will be handled as scalable, 
    this means that every time it changes size through the Container API, the 
    image will be recomputed to fit the new size.
    
    * The source_scalable flag doesn't affect bitmaps or operations through the
    clutter.Actor API (ex: scale, rotate, etc..) as to enable fast transforms 
    for things like transitions and effects.
    """

    def __init__(self, source=None, source_scalable=True):
        """ Initialize image widget """
                
        super(Image, self).__init__()
        
        # Set property values
        self._source = source
        self._source_scalable = source_scalable
        
        self.texture = None
        
        self._update_style(self.style)
    
    def _update_style(self, props=None):
        """ Update style """
        
        super(Image, self)._update_style(props)
        
        if not props:
            return
            
        
    def get_source(self):
        """ Retrieves image source file uri 
        
        return (str) -- image source uri in standard uri format
        """
        
        return self._source
        
    def set_source(self, value):
        """ Sets image source uri 
        
        value (str) -- image source uri in standard uri format
        """
        
        self._source = value
        if self._source:
            if self.texture:
                self.remove(self.texture)
                del(self.texture)
                self.texture = None
            self._set_source()   
            self._update_layout()    
    
    source = property(get_source, set_source)
         
    def get_source_scalable(self):
        """ Retrieve whether image source file should be handled as a scalable 
        graphic (only applicable to SVGs and Cairo textures) 
        
        return (bool)
        """
        
        return self._source_scalable
        
    def set_source_scalable(self, value):
        """ Sets wether image source file should be handled as a scalable 
        graphic (only applicable to SVGs and Cairo textures) 
        
        value (bool)
        """
    
        self._source_scalable = value
        self._set_source()
        
    source_scalable = property(get_source_scalable, set_source_scalable)
        
    # Global

    def _update_layout(self):
        """ Update widget """
        
        super(Image, self)._update_layout()

        if not self.texture or self.source_scalable:
            self._set_source()
        else:
            width = self.get_width()
            height = self.get_height()
            self.texture.set_width(width)
            self.texture.set_height(height)
    
    # Private
     
    def _set_source(self):
        """ Set texture based on given source
        
        - current support for PNG, SVG and Cairo
        """
        
        width = self.get_width() 
        height = self.get_height()
        
        # Account for 0 width or height
        if width == 0 or height == 0:
            return
       
        # Account for no change in size
        if self.texture and \
           width == self.texture.get_width() and \
           height == self.texture.get_height():
            return    
        
        # Source filename and extension
        source_name = os.path.splitext(self.source)[0]
        source_ext = os.path.splitext(self.source)[1]
        
        theme = Theme.get_default()
        if source_ext == '.py':
            source_path = os.path.join(theme.get_path(), 'resources')
        elif os.path.exists(self.source):
            source_path = os.path.dirname(self.source)
            source = self.source
        else:
            source_path = os.path.join(theme.get_path(), 'resources')
            source = os.path.join(source_path, self.source)
        
        if os.path.exists(source_path):
            if source_ext == '.png':
                if not self.texture:
                    self.texture = clutter.Texture(filename=source)
                    self.add(self.texture)
                    self.texture.show()
                self.texture.set_width(width)
                self.texture.set_height(height)
            elif source_ext == '.svg':
                if self.texture:
                    self.remove(self.texture)
                    del(self.texture)
                self.texture = SVGImage(source, width, height)
                self.add(self.texture)
                self.texture.show()
            elif source_ext == '.py':
                if self.texture:
                    self.remove(self.texture)
                    del(self.texture)
                source_import = os.path.basename(source_name)
                sys.path[1] = source_path
                cairotexture = __import__(source_import)
                self.texture = cairotexture.Texture(width, height)
                self.add(self.texture)
                self.texture.show()
        else: 
            raise AttributeError, "source doesn't exist: %s" % source_path