예제 #1
0
class Scaled(Widget):
    def __init__(self, **kwargs):
        super(Scaled, self).__init__(**kwargs)

        self.elements = []
        self.pointsize = 5  # this multiplies by two according to kivy docs

        with self.canvas:
            self._fbo = Fbo(size=self.size)
            self._rect = Rectangle(texture=self._fbo.texture)

        with self._fbo:
            Color(1, 1, 1)
            self._fborect = Rectangle(size=self._fbo.size)
            Color(0, 0, 1)
            self._points = Point(pointsize=self.pointsize)

        self._fbo.add_reload_observer(self._clear_fbo)
        self.bind(pos=self._update_rect, size=self._update_rect)

    def drawpoint(self, x, y):
        self.elements.append([x, y])
        self._points.add_point(x, y)

    def draw(self, matrix):
        self._points.points = []
        self._clear_fbo()

        for point in matrix:
            x = int(point[0] * (self.pointsize * 2) + self.pointsize)
            y = int(point[1] * (self.pointsize * 2) + self.pointsize)
            self.drawpoint(x, y)

    # RELOADING THE BUFFER AT ANY CHANGE
    def _clear_fbo(self, fbo=None):
        ''' This will reload the framebufferer either by the call of the
        observer or by the deletion of a point'''
        if fbo is None:
            fbo = self._fbo

        fbo.bind()
        fbo.clear_buffer()
        fbo.add(Color(1, 1, 1))
        fbo.add(self._fborect)
        fbo.add(Color(0, 0, 1))
        fbo.add(self._points)
        fbo.release()

    def _update_rect(self, instance, value):
        self._fbo.size = instance.size
        self._fborect.size = instance.size
        self._rect.size = instance.size
        self._rect.pos = instance.pos
        self._rect.texture = self._fbo.texture
예제 #2
0
class Scaled(Widget):
    def __init__(self, **kwargs):
        super(Scaled, self).__init__(**kwargs)

        self.elements = []
        self.pointsize = 5  # this multiplies by two according to kivy docs

        with self.canvas:
            self._fbo = Fbo(size=self.size)
            self._rect = Rectangle(texture=self._fbo.texture)

        with self._fbo:
            Color(1, 1, 1)
            self._fborect = Rectangle(size=self._fbo.size)
            Color(0, 0, 1)
            self._points = Point(pointsize=self.pointsize)

        self._fbo.add_reload_observer(self._clear_fbo)
        self.bind(pos=self._update_rect, size=self._update_rect)

    def drawpoint(self, x, y):
        self.elements.append([x, y])
        self._points.add_point(x, y)

    def draw(self, matrix):
        self._points.points = []
        self._clear_fbo()

        for point in matrix:
            x = int(point[0] * (self.pointsize * 2) + self.pointsize)
            y = int(point[1] * (self.pointsize * 2) + self.pointsize)
            self.drawpoint(x, y)

    # RELOADING THE BUFFER AT ANY CHANGE
    def _clear_fbo(self, fbo=None):
        """ This will reload the framebufferer either by the call of the
        observer or by the deletion of a point"""
        if fbo is None:
            fbo = self._fbo

        fbo.bind()
        fbo.clear_buffer()
        fbo.add(Color(1, 1, 1))
        fbo.add(self._fborect)
        fbo.add(Color(0, 0, 1))
        fbo.add(self._points)
        fbo.release()

    def _update_rect(self, instance, value):
        self._fbo.size = instance.size
        self._fborect.size = instance.size
        self._rect.size = instance.size
        self._rect.pos = instance.pos
        self._rect.texture = self._fbo.texture
예제 #3
0
    def test_point_add(self):
        from kivy.uix.widget import Widget
        from kivy.graphics import Point, Color
        r = self.render

        wid = Widget()
        with wid.canvas:
            Color(1, 1, 1)
            p = Point(pointsize=10)

        p.add_point(10, 10)
        p.add_point(90, 10)
        p.add_point(10, 90)
        p.add_point(50, 50)
        p.add_point(10, 50)
        p.add_point(50, 10)

        r(wid)
예제 #4
0
    def test_point_add(self):
        from kivy.uix.widget import Widget
        from kivy.graphics import Point, Color
        r = self.render

        wid = Widget()
        with wid.canvas:
            Color(1, 1, 1)
            p = Point(pointsize=10)

        p.add_point(10, 10)
        p.add_point(90, 10)
        p.add_point(10, 90)
        p.add_point(50, 50)
        p.add_point(10, 50)
        p.add_point(50, 10)

        r(wid)
예제 #5
0
class Grid( Widget ):
    point_size = NumericProperty(10)
    
    def __init__(self, **kwargs):
        super(Grid, self).__init__(**kwargs)
        # Which elements exist in the grid in the normalized coordinates
        self.elements = []
        # If active, it can't be modified
        self.active = False
        
        # To the canvas, we add the FrameBufferObject and the rect to show it
        with self.canvas:
            self.fbo = Fbo(size=self.size)
            self.rect = Rectangle(texture=self.fbo.texture)
            # Color(1,0,0)
            # self.rect = Rectangle(size = self.size, pos = self.pos)

        # To the FrameBufferObject I set the color and add the point list
        with self.fbo:
            Color(1,1,1)
            self.points = Point( pointsize=self.point_size )

        # add some observers to the fbo, changes for the point_size (grid 
        # resizing) and widget resizing
        self.fbo.add_reload_observer(self._populate_fbo)
        self.bind( point_size = self._reshape )
        self.bind( size = self._update_rect, pos = self._update_rect )

    def on_touch_down(self, touch):
        ''' Handle adding/removing points when the grid is not active'''
        if not self.active and self.collide_point(*touch.pos):
            # Move to a 0,0 from where the widget starts
            x = touch.x - self.x
            y = touch.y - self.y
            self.add_point( [x,y] )

            return True

        return super(Grid, self).on_touch_down(touch)

    def normalize(self, coords):
        ''' normalization of coordinates, it will transform any given point in 
        the widget to its corresponding normalized coords '''
        # TODO: Create a picture to describe what are the normalized coordinates
        if type(coords) is tuple:
            coords = list(coords)

        if type(coords) is list:
            for ind in range(len(coords)):
                coords[ind] = int( coords[ind] // ( self.points.pointsize * 2 ) )
            return coords
        else:
            return int( coords // ( self.points.pointsize * 2 ) )

    def adjust(self, coords):
        ''' adjustment of a normalized coordinate to the real coordinate using
        the current point size as a guide '''
        if type(coords) is tuple:
            coords = list(coords)

        if type(coords) is list:
            for ind in range(len(coords)):
                coords[ind] = int( coords[ind] * ( self.points.pointsize * 2 ) + self.points.pointsize )
            return coords
        else:
            return int( coords * ( self.points.pointsize * 2 ) + self.points.pointsize )

    def add_point(self, point, redraw=True):
        ''' method to add a point to the grid if it doesn't exist
        if it's there, remove it'''
        point = self.normalize(point)
        
        if point in self.elements:
            where = self.elements.index( point )

            # Steal the reference to the vector of points
            points = self.points.points
            self.points.points = []
            # Clean the desired point
            del(points[where*2])
            del(points[where*2])

            # Reassign the property for the context to know (kivy weird things)
            self.points.points = points

            # Remove from the historical
            del(self.elements[where])

            # Redraw if asked for
            if redraw:
                self._populate_fbo(self.fbo)
        else:
            # add the normalized coords to the element list
            # it has to be copied because the adjust method will modify
            # the elements in points
            self.elements.append(point[:])
            # add the point to the visible points using the adjusted coordinates
            # the * leading self.adjust is to unpack the resulting array
            self.points.add_point( *self.adjust(point) )

        # print(self.elements)

    def next(self, instance):
        if len(self.elements) == 0: return
        
        # calculate the survivors
        nextgen = automaton.survivors(self.elements)
        # print(nextgen)
        # calculate any possible newborns
        nextgen += automaton.births(self.elements)
        # print(nextgen)

        # replace the current elements
        self.elements = nextgen
        # The vector comes with minivectors within, which is fine for the 
        # list of elements but doesn't work for the adjustment of points in
        # the screen
        nextgen = [ i for cell in nextgen for i in cell ]
        # adjust the elements to the actual coordinates
        nextgen = self.adjust( nextgen )
        # assign the vector back
        self.points.points = nextgen
        # redraw
        self._populate_fbo()

    def clear(self, instance):
        self.elements = []
        self.points.points = []
        self._populate_fbo()

    # RELOADING THE BUFFER AT ANY CHANGE
    def _populate_fbo(self, fbo = None):
        ''' This will reload the framebufferer either by the call of the 
        observer or by the deletion of a point'''
        if fbo is None:
            fbo = self.fbo

        fbo.bind()
        fbo.clear_buffer()
        fbo.add(self.points)
        fbo.release()

    def _reshape(self, instance, value):
        # There are no elements
        if len(self.elements) == 0:
            # We just update the points to be drawn
            self.points.pointsize = self.point_size
        # If we do have elements
        else:
            # steal the reference to the vector
            points = self.points.points
            self.points.points = []

            # normalize using current value
            points = self.normalize( points )
            # reassing the value
            self.points.pointsize = self.point_size
            # adjust using new value
            points = self.adjust( points )

            # assign the vector back
            self.points.points = points
            # redraw
            self._populate_fbo()

    # REDRAWING THE FBO AND THE
    def _update_rect( self, instance, value ):
        self.fbo.size = instance.size
        self.rect.size = instance.size
        self.rect.pos = instance.pos
        self.rect.texture = self.fbo.texture
예제 #6
0
    def update_canvas(self, *args):

        for i, value in enumerate(self.values):
            self._previous_values.append(None)
            if self.needles_props:
                props = self.needles_props[i]
                color = Color(* props.get('color') or \
                                ((i%3)*.5, ((i+1)%3)*.5, ((i+2)%3*.5)))
                length = props.get('length') or 1.0
                width = props.get('width') or 1.0
            else:
                color = Color((i % 3) * .5, ((i + 1) % 3) * .5,
                              ((i + 2) % 3 * .5))
                length = 1.0
                width = 2.0
            self._needles_props.append({
                'color': color,
                'width': width,
                'length': length
            })
            self._needles.append(InstructionGroup())

        self.canvas.clear()
        x0, y0 = self.pos
        with self.canvas:

            e_width = self.width / 2
            e_height = self.height / 2

            # Default color
            Color(1, 1, 1)

            # Labels
            if self.labels:
                for value, text in self.labels:
                    angle = self.begin - \
                            ((self.begin-self.end) / (self.maxi - self.mini) * value)
                    pos = ellipse(x0 + e_width, y0 + e_height, e_width - 30,
                                  e_height - 30, angle)
                    self._labels.append(
                        Label(
                            text=text,
                            color=(1, 1, 1, .5),
                            pos=pos,
                            size=('1dp', '1dp'),  #self.texture_size,
                            font_size='20sp',
                            bold=True))
                    x1, y1 = ellipse(x0 + e_width, y0 + e_height, e_width,
                                     e_height, angle)
                    x2, y2 = ellipse(x0 + e_width, y0 + e_height, e_width - 10,
                                     e_height - 10, angle)
                    Line(
                        points=[x1, y1, x2, y2],
                        width=2,
                        #cap = 'round',
                        close=False)

            else:
                # Default : label on dizains
                for i in range(0, -self.mini + self.maxi + 1, 10):
                    angle = self.begin - \
                            ((self.begin-self.end) / (self.maxi - self.mini) * i)
                    pos = ellipse(x0 + e_width, y0 + e_height, e_width - 30,
                                  e_height - 30, angle)
                    self._labels.append(
                        Label(
                            text='%d' % (i + self.mini),
                            color=(1, 1, 1, .5),
                            pos=pos,
                            size=('1dp', '1dp'),  #self.texture_size,
                            font_size='20sp',
                            bold=True))
                    x1, y1 = ellipse(x0 + e_width, y0 + e_height, e_width,
                                     e_height, angle)
                    x2, y2 = ellipse(x0 + e_width, y0 + e_height, e_width - 10,
                                     e_height - 10, angle)
                    Line(
                        points=[x1, y1, x2, y2],
                        width=2,
                        #cap = 'round',
                        close=False)

            # Graduations
            p = Point()

            if self.graduations:
                pass  # XXX TODO

            else:
                # Default : point on units
                for i in range(0, -self.mini + self.maxi + 1):
                    angle = self.begin - \
                            ((self.begin-self.end) / (self.maxi - self.mini) * i)
                    if i % 10 == 0:
                        # Label, no graduation
                        continue
                    x, y = ellipse(x0 + e_width, y0 + e_height, e_width - 5,
                                   e_height - 5, angle)
                    p.add_point(x, y)

        # Save values used in update_values to display needle(s)
        self._e_width = e_width
        self._e_height = e_height
        self._scale = (self.begin - self.end) / (self.maxi - self.mini)
        self._x0, self._y0 = self.pos[0] + e_width, self.pos[1] + e_height
        self._ready = True

        # Display needle(s)
        self.update_values()