Beispiel #1
0
 def drawTextInput(self,touch):
     start, pos = self.touch_time[touch.id]
     start = start if start else time.time() 
     elaspsed_time = time.time() -  start
     idu = self.touch_keys[touch.id]
     Log.debug('Elapsed time:%s' % elaspsed_time)
     if elaspsed_time >= 1:
         distance = Vector.distance( Vector(pos.sx, pos.sy),
                                     Vector(touch.osxpos, touch.osypos))
         Log.debug('Screen coordinate Distance:%f vs %f' % (distance,self.press_and_hold_distance))
         _l = len(self.touch_positions[idu]['Cdata'])
         Log.debug('Num points:%d' % _l)
         _vd = Vector.distance(\
                         Vector(*self.touch_positions[idu]['Cdata'][0]),\
                         Vector(*self.touch_positions[idu]['Cdata'][_l-1]))
         Log.debug('touch distance :%f and %d' % (_vd, int(_vd)))
         if distance <= self.press_and_hold_distance and\
                     (_l < self.travel_limit or int(_vd) < self.travel_limit):                                            
             
             txt = ScribbleTextWidget(pos=touch.pos, group=self.session,
                                                keyboard=self.keyboard,
                                                cls='scribbleKeyboardcss')
             txt.push_handlers(on_transform=curry(self.on_transform,txt))
             self.add_widget(txt) 
             self.disable_all()
             txt.enable()
             d = txt.to_dic()
             self.dispatch_event('on_text_change', d)
             return True
Beispiel #2
0
 def on_popup_draw(self):
     self._xml.root.center = self.get_parent_window().center
     popup = self._xml.getById('popup')
     set_color(*self.style.get('bg-color-full'))
     drawCSSRectangle(pos=Vector(popup.pos) - (10, 10),
                      size=Vector(popup.size) + (20, 20),
                      style=self.style)
Beispiel #3
0
    def transform_with_touch(self, touch):
        # just do a simple one finger drag
        if len(self._touches) == 1:
            return self._apply_drag(touch)

        # we have more than one touch...
        points = [Vector(*self._last_touch_pos[t]) for t in self._touches] 

        # we only want to transform if the touch is part of the two touches
        # furthest apart! So first we find anchor, the point to transform
        # around as the touch farthest away from touch
        anchor  = max(points, key=lambda p: p.distance(touch.pos))

        # now we find the touch farthest away from anchor, if its not the
        # same as touch. Touch is not one of the two touches used to transform
        farthest = max(points, key=anchor.distance)
        if points.index(farthest) != self._touches.index(touch):
            return

        # ok, so we have touch, and anchor, so we can actually compute the
        # transformation        
        old_line = Vector(*touch.dpos) - anchor
        new_line = Vector(*touch.pos) - anchor

        angle = radians( new_line.angle(old_line) ) * self._do_rotation
        scale = new_line.length() / old_line.length()
        new_scale = scale * self.scale
        if new_scale < self.scale_min or new_scale > self.scale_max:
            scale = 1.0

        self.apply_transform(rotation_matrix(angle, (0, 0, 1)), anchor=anchor)
        self.apply_transform(scale_matrix(scale), anchor=anchor)

        #dispatch on_transform with th touch that caused it
        self.dispatch_event('on_transform', touch)
Beispiel #4
0
 def collide_point(self, x, y):
     #A algorithm to find the whether a touch is within a semi ring
     cx, cy = self.center
     point_dist = Vector(self.center).distance((x, y))
     point_angle = Vector(self._radius_line).angle((x - cx, y - cy))
     if point_angle < 0:
         point_angle = 360. + point_angle
     if 0 < point_angle > self.sweep_angle:
         return False
     return self.radius - self.thickness < point_dist <= self.radius
Beispiel #5
0
 def get_rigid_rotation(self, dstpts):
     '''
     Extract the rotation to apply to a group of points to minimize the
     distance to a second group of points. The two groups of points are
     assumed to be centered. This is a simple version that just pick
     an angle based on the first point of the gesture.
     '''
     if len(self.strokes) < 1 or len(self.strokes[0].points) < 1:
         return 0
     if len(dstpts.strokes) < 1 or len(dstpts.strokes[0].points) < 1:
         return 0
     target = Vector( [dstpts.strokes[0].points[0].x, dstpts.strokes[0].points[0].y]  )
     source = Vector( [self.strokes[0].points[0].x, self.strokes[0].points[0].y] )
     return source.angle(target)
Beispiel #6
0
    def transform_with_touch(self, touch):
        # just do a simple one finger drag
        if len(self._touches) == 1:
            return self._apply_drag(touch)

        # we have more than one touch...
        points = [Vector(*self._last_touch_pos[t]) for t in self._touches]

        # we only want to transform if the touch is part of the two touches
        # furthest apart! So first we find anchor, the point to transform
        # around as the touch farthest away from touch
        anchor = max(points, key=lambda p: p.distance(touch.pos))

        # now we find the touch farthest away from anchor, if its not the
        # same as touch. Touch is not one of the two touches used to transform
        farthest = max(points, key=anchor.distance)
        if points.index(farthest) != self._touches.index(touch):
            return

        # ok, so we have touch, and anchor, so we can actually compute the
        # transformation
        old_line = Vector(*touch.dpos) - anchor
        new_line = Vector(*touch.pos) - anchor

        angle = radians(new_line.angle(old_line)) * self._do_rotation
        scale = new_line.length() / old_line.length()
        new_scale = scale * self.scale
        if new_scale < self.scale_min or new_scale > self.scale_max:
            scale = 1.0

        self.apply_transform(rotation_matrix(angle, (0, 0, 1)), anchor=anchor)
        self.apply_transform(scale_matrix(scale), anchor=anchor)

        #dispatch on_transform with th touch that caused it
        self.dispatch_event('on_transform', touch)
Beispiel #7
0
    def __init__(self, **kwargs):
        kwargs.setdefault('radius', 200)

        super(MTVectorSlider, self).__init__(**kwargs)

        self.radius = kwargs.get('radius')

        self.vector = Vector(self.x + self.radius, self.y)
        self.amplitude = 0
        self.angle = 0

        self.register_event_type('on_amplitude_change')
        self.register_event_type('on_angle_change')
        self.register_event_type('on_vector_change')
Beispiel #8
0
 def _set_pos(self, pos):
     _pos = self.bbox[0]
     if pos == _pos:
         return
     t = Vector(*pos) - _pos
     trans = translation_matrix((t.x, t.y, 0))
     self.apply_transform(trans)
Beispiel #9
0
    def apply_angle_scale_trans(self, angle, scale, trans, point=Vector(0, 0)):
        '''Update matrix transformation by adding new angle, scale and translate.

        :Parameters:
            `angle` : float
                Rotation angle to add
            `scale` : float
                Scaling value to add
            `trans` : Vector
                Vector translation to add
            `point` : Vector, default to (0, 0)
                Point to apply transformation
        '''
        old_scale = self.scale
        new_scale = old_scale * scale
        if new_scale < self.scale_min or old_scale > self.scale_max:
            scale = 1

        t = translation_matrix((trans[0] * self._do_translation_x,
                                trans[1] * self._do_translation_y, 0))
        t = matrix_multiply(t, translation_matrix((point[0], point[1], 0)))
        t = matrix_multiply(t, rotation_matrix(angle, (0, 0, 1)))
        t = matrix_multiply(t, scale_matrix(scale))
        t = matrix_multiply(t, translation_matrix((-point[0], -point[1], 0)))
        self.apply_transform(t)

        self.dispatch_event('on_transform', None)
Beispiel #10
0
 def get_rigid_rotation(self, dstpts):
     '''
     Extract the rotation to apply to a group of points to minimize the
     distance to a second group of points. The two groups of points are
     assumed to be centered. This is a simple version that just pick
     an angle based on the first point of the gesture.
     '''
     if len(self.strokes) < 1 or len(self.strokes[0].points) < 1:
         return 0
     if len(dstpts.strokes) < 1 or len(dstpts.strokes[0].points) < 1:
         return 0
     target = Vector(
         [dstpts.strokes[0].points[0].x, dstpts.strokes[0].points[0].y])
     source = Vector(
         [self.strokes[0].points[0].x, self.strokes[0].points[0].y])
     return source.angle(target)
Beispiel #11
0
 def on_touch_down(self, touch):
     if self.state == 'dragging':
         return False
     if self.collide_point(touch.x, touch.y):
         self.state = 'dragging'
         touch.grab(self)
         touch.userdata['touch_offset'] = Vector(self.pos) - touch.pos
         return True
Beispiel #12
0
    def process(self, events):
        # check if module is disabled
        if self.timeout == 0:
            return events

        d = time.time()
        for type, touch in events[:]:
            if type == 'up':
                events.remove((type, touch))
                if touch.uid in self._links:
                    selection = self._links[touch.uid]
                    selection.userdata['__retain_time'] = d
                    self._available.append(selection)
                    del self._links[touch.uid]
                else:
                    touch.userdata['__retain_time'] = d
                    self._available.append(touch)
            elif type == 'move':
                if touch.uid in self._links:
                    selection = self._links[touch.uid]
                    selection.x = touch.x
                    selection.y = touch.y
                    selection.sx = touch.sx
                    selection.sy = touch.sy
                    events.remove((type, touch))
                    events.append((type, selection))
                else:
                    pass
            elif type == 'down':
                # new touch, found the nearest one
                selection = None
                selection_distance = 99999
                for touch2 in self._available:
                    touch_distance = Vector(touch2.spos).distance(touch.spos)
                    if touch_distance > self.distance:
                        continue
                    if touch2.__class__ != touch.__class__:
                        continue
                    if touch_distance < selection_distance:
                        # eligible for continuation
                        selection_distance = touch_distance
                        selection = touch2
                if selection is None:
                    continue

                self._links[touch.uid] = selection
                self._available.remove(selection)
                events.remove((type, touch))

        for touch in self._available[:]:
            t = touch.userdata['__retain_time']
            if d - t > self.timeout:
                self._available.remove(touch)
                events.append(('up', touch))

        return events
Beispiel #13
0
 def rotate(self, angle):
     g = Gesture()
     for stroke in self.strokes:
         tmp = []
         for j in stroke.points:
             v = Vector([j.x, j.y]).rotate(angle)
             tmp.append(v)
         g.add_stroke(tmp)
     g.gesture_product = g.dot_product(g)
     return g
Beispiel #14
0
 def find_double_tap(self, ref):
     '''Find a double tap touch within self.touches.
     The touch must be not a previous double tap, and the distance must be
     ok'''
     for touchid in self.touches:
         if ref.uid == touchid:
             continue
         type, touch = self.touches[touchid]
         if type != 'up':
             continue
         if touch.is_double_tap:
             continue
         distance = Vector.distance(Vector(ref.sx, ref.sy),
                                    Vector(touch.osxpos, touch.osypos))
         if distance > self.double_tap_distance:
             continue
         touch.double_tap_distance = distance
         return touch
     return None
Beispiel #15
0
    def on_touch_up(self, touch):
        # accept only the touch we've got first.
        if touch.grab_current != self:
            return
        touch.ungrab(self)
        self._touch = None

        # animate the transition to back to 0
        # cover will back to position in nicer way
        self._animation = True

        # launch on_select ?
        if not touch.userdata['coverflow.noclick']:
            distance = Vector(touch.userdata['coverflow.firstpos']).distance(
                Vector(touch.pos))
            if distance <= self.trigger_distance:
                self.dispatch_event('on_select',
                                    self.children[self._selection])
        return True
Beispiel #16
0
    def draw(self):

        # extract relative position
        rx, ry = self.relpos

        # calculate triangle
        mx = self.x + rx + self.width * 0.5 + self.trirelpos[0]
        my = self.y + ry + self.height * 0.5 + self.trirelpos[1]
        angle = Vector(1, 0).angle(Vector(mx - self.x, my - self.y))
        vpos = Vector(mx, my)
        v1 = Vector(self.trisize, 0).rotate(angle) + vpos
        v2 = Vector(-self.trisize, 0).rotate(angle) + vpos

        # draw border
        if self.bordersize > 0:
            drawRoundedRectangle(
                pos=(self.x - self.padding - self.bordersize + rx,
                     self.y - self.padding - self.bordersize + ry),
                size=(self.width + self.padding * 2 + self.bordersize * 2,
                      self.height + self.padding * 2 + self.bordersize * 2),
                radius=self.radius,
                color=self.bordercolor)

            glEnable(GL_LINE_SMOOTH)
            glLineWidth(self.bordersize * 2)
            drawPolygon((self.x, self.y, v1.x, v1.y, v2.x, v2.y),
                        style=GL_LINE_LOOP)

        # draw background
        drawRoundedRectangle(pos=(self.x - self.padding + rx,
                                  self.y - self.padding + ry),
                             size=(self.width + self.padding * 2,
                                   self.height + self.padding * 2),
                             radius=self.radius,
                             color=self.bgcolor)
        drawPolygon((self.x, self.y, v1.x, v1.y, v2.x, v2.y))

        # hack to translate label position
        with gx_matrix:
            glTranslatef(rx, ry, 0)
            super(MTSpeechBubble, self).draw()
Beispiel #17
0
 def _calculate_angle(self, x, y):
     cx, cy = self.center
     self._last_touch = x - cx, y - cy 
     angle = Vector(self._radius_line).angle(self._last_touch)
     if angle < 0:
         angle += 360
     try:
         self.value = angle * (self.max - self.min) / \
                      self.sweep_angle + self.min
         self._slider_angle = angle
     except RangeException:
         pass
     self.dispatch_event('on_value_change', self._value)
Beispiel #18
0
    def __init__(self, **kwargs):
        kwargs.setdefault('radius', 200)

        super(MTVectorSlider, self).__init__(**kwargs)

        self.radius = kwargs.get('radius')

        self.vector = Vector(self.x+self.radius, self.y)
        self.amplitude = 0
        self.angle = 0

        self.register_event_type('on_amplitude_change')
        self.register_event_type('on_angle_change')
        self.register_event_type('on_vector_change')
Beispiel #19
0
def circumcircle(a, b, c):
    '''
    Computes the circumcircle of a triangel defined by a,b,c
    see: http://en.wikipedia.org/wiki/Circumscribed_circle#Circumscribed_circles_of_triangles
    
    :Parameters:
        `a` : iterable
            the 1. point of the triangle
        `b` : iterable
            the 2. point of the triangle
        `c` : iterable
            the 3. point of the triangle
        
    :Return:
        A Circle that defined the tuple :
            * The first element in the returned touple is the center (tuple x,y)
            * The second the radius (float)
    '''
    P = Vector(a[0], a[1])
    Q = Vector(b[0], b[1])
    R = Vector(c[0], c[1])

    mPQ = (P + Q) * .5
    mQR = (Q + R) * .5

    numer = -(-mPQ.y*R.y + mPQ.y*Q.y + mQR.y*R.y - mQR.y*Q.y \
              -mPQ.x*R.x + mPQ.x*Q.x + mQR.x*R.x - mQR.x*Q.x)
    denom = (-Q.x * R.y + P.x * R.y - P.x * Q.y + Q.y * R.x - P.y * R.x +
             P.y * Q.x)

    t = numer / denom

    cx = -t * (Q.y - P.y) + mPQ.x
    cy = t * (Q.x - P.x) + mPQ.y

    return ((cx, cy), (P - (cx, cy)).length())
Beispiel #20
0
 def find_double_tap(self, ref):
     """Find a double tap touch within self.touches.
     The touch must be not a previous double tap, and the distance must be
     ok"""
     for touchid in self.touches:
         if ref.id == touchid:
             continue
         type, touch = self.touches[touchid]
         if type != "up":
             continue
         if touch.is_double_tap:
             continue
         distance = Vector.distance(Vector(ref.sx, ref.sy), Vector(touch.osxpos, touch.osypos))
         if distance > self.double_tap_distance:
             continue
         touch.double_tap_distance = distance
         return touch
     return None
Beispiel #21
0
 def get_key_at_pos(self, x, y):
     '''Return the key + size info on the current layout, at the coordinate (x, y)'''
     mtop, mright, mbottom, mleft = self.style['margin']
     w, h = self.width - mleft - mright, self.height - mtop - mbottom
     kx, ky = self.layout.SIZE
     keysize = Vector(w / kx, h / ky)
     if x < mleft or x > self.width - mright or \
        y < mbottom or y > self.height - mtop:
         return None
     index = ky-int((y - mbottom) /
             (self.height - mtop - mbottom)
             * ky)
     line = self.layout.__getattribute__('%s_%d' % (self.mode, index))
     x -= mleft
     kx = 0
     for key in line:
         kw = keysize.x * key[3]
         if x >= kx and x < kx + kw:
             h = (self.height - mtop - mbottom) / ky
             return (key, (kx, h * (ky-index), kw, h))
         kx += kw
     return None
Beispiel #22
0
 def should_delete(self,touch_p, line_p):    
     distance = Vector.distance( Vector(*line_p), #IGNORE:W0142
                                 Vector(*touch_p)) #IGNORE:W0142
     if distance <= self.delete_distance:
         return True
Beispiel #23
0
 def _get_rotation(self):
     # v1 = vetor from (0,0) to (0,10)
     # v2 = vector from center to center + (0,10) (in widget space)
     v1 = Vector(0,10)
     v2 = Vector(*self.to_parent(*self.pos)) - self.to_parent(self.x, self.y+10)
     return -1.0 *(v1.angle(v2) + 180) % 360
Beispiel #24
0
 def on_press(self, touch):
     self.orig = Vector(self.to_window(*touch.pos))
Beispiel #25
0
class ScribbleText(MyTextArea):
    def __init__(self, **kwargs):
        kwargs.setdefault('padding_x', 3)
        kwargs.setdefault('autosize', True)
        kwargs.setdefault('cls', 'mytextinput')
        kwargs.setdefault('style',{'font-size': kwargs['font-size']})
        super(ScribbleText, self).__init__(**kwargs)
        self.orig = (0, 0)
        self.label_obj.options['font_size'] = self.style['font-size']
        self.label_obj.refresh()
    def _recalc_size(self):
        # We could do this as .size property I suppose, but then we'd
        # be calculating it all the time when .size is accessed.
        num = len(self.lines)
        if not num:
            return
        # The following two if statements ensure that the textarea remains
        # easily clickable even if there's no content.
        if self.autosize or self.autoheight:
            self.height = num * self.line_height + self.line_spacing * (num - 1)
        if (self.autosize or self.autowidth):
            self.width = max(label.content_width for label in self.line_labels)
            + 20

    def on_press(self, touch):
        self.orig = Vector(self.to_window(*touch.pos))

    def on_release(self, touch):
        final = Vector(self.to_window(*touch.pos))
        if self.orig.distance(final) <= 4:
            if not self.is_active_input:
                self.parent.disable_all() #IGNORE:E1101
                self._can_deactive = True
            super(ScribbleText, self).on_release(touch)
#    def show_keyboard(self):
#        super(MyTextArea,self).show_keyboard()
#        to_root = self.keyboard_to_root
#        if(to_root):
#            w = self.get_root_window() if to_root else self.get_parent_window()
#            w.remove_widget(self.keyboard)
#            #we want to add this keyboard to the innerwindow border
#            #self.parent.parent.parent.parent.show_keyboard(self.keyboard)
#            self.parent.parent.parent.parent.add_widget(self.keyboard)
#            #self.keyboard.pos = self.to_window(self.pos[0], self.pos[1] - self.height  - self.keyboard.height) #position of the text input field
#
#
#                                
#    def hide_keyboard(self):
#        if self._is_active_input:
#            self.parent.parent.parent.parent.set_button_image() 
#        super(ScribbleText, self).hide_keyboard()
#        p = self.parent
#        if(p):
#            pp = p.parent
#            if(pp):
#                ppp = pp.parent
#                if(ppp):
#                    p4 = ppp.parent
#                    if(p4):
#                        #p4.hide_keyboard(self.keyboard)
#                        p4.remove_widget(self.keyboard)

    def on_touch_down(self, touch):
        super(ScribbleText, self).on_touch_down(touch)
        return False
Beispiel #26
0
def minimum_bounding_circle(points):
    '''
    Returns the minimum bounding circle for a set of points
    
    For a description of the problem being solved see http://en.wikipedia.org/wiki/Smallest_circle_problem
    The function uses Applet's Algorithm Algorithm, worst case teh runtime is O(h^3 *n), where h= number of points in teh convex hull of the set of points. But it runs in linear time in almost all real world cases.
    see: http://www.personal.kent.edu/~rmuhamma/Compgeometry/MyCG/CG-Applets/Center/centercli.htm
    
    :Parameters:
        `points` : iterable
            A list of points (2 tuple with x,y coordinates)

    :Return:
        A Circle that defined the tuple :
            * The first element in the returned touple is the center (tuple x,y)
            * The second the radius (float)
    '''
    points = [Vector(p[0], p[1]) for p in points]

    if len(points) == 1:
        return (points[0].x, points[0].y), 0.0

    if len(points) == 2:
        p1, p2 = points
        return (p1 + p2) * .5, ((p1 - p2) * .5).length()

    # determine a point P with the smallest y value
    P = min(points, key=lambda p: p.y)

    # find a point Q such that the angle of the line segment
    # PQ with the x axis is minimal
    def x_axis_angle(q):
        if q == P:
            return 1e10  # max val if teh same, to skip
        return abs((q - P).angle((1, 0)))

    Q = min(points, key=x_axis_angle)

    for p in points:
        # find R such that angle PRQ is minimal
        def angle_pq(r):
            if r in (P, Q):
                return 1e10  # max val if teh same, to skip
            return abs((r - P).angle(r - Q))

        R = min(points, key=angle_pq)

        # check for case 1 (angle PRQ is obtuse), the circle is determined
        # by two points, P and Q. radius = |(P-Q)/2|, center = (P+Q)/2
        if angle_pq(R) > 90.0:
            return (P + Q) * .5, ((P - Q) * .5).length()

        # if angle RPQ is obtuse, make P = R, and try again
        if abs((R - P).angle(Q - P)) > 90:
            P = R
            continue

        # if angle PQR is obtuse, make Q = R, and try again
        if abs((P - Q).angle(R - Q)) > 90:
            Q = R
            continue

        # all angles were acute..we just need teh circle through the
        # two points furthest apart!
        break

    # find teh circumcenter for triangle given by P,Q,R
    return circumcircle(P, Q, R)
Beispiel #27
0
 def _get_scale(self):
     p1 = Vector(*self.to_parent(0, 0))
     p2 = Vector(*self.to_parent(1, 0))
     scale = p1.distance(p2)
     return float(scale)
Beispiel #28
0
 def _get_scale(self):
     p1 = Vector(*self.to_parent(0, 0))
     p2 = Vector(*self.to_parent(1, 0))
     scale = p1.distance(p2)
     return float(scale)
Beispiel #29
0
 def _get_rotation(self):
     v1 = Vector(0, 10)
     v2 = Vector(*self.to_parent(*self.pos)) - self.to_parent(
         self.x, self.y + 10)
     return -1.0 * (v1.angle(v2) + 180) % 360
Beispiel #30
0
    def _do_update(self, mode=None):
        # we absolutly want mode to update displaylist.
        if mode not in ('background', 'keys'):
            return

        # don't update background if it's already compiled
        if mode == 'background' and self._current_cache['background'].is_compiled():
            return

        # calculate margin
        s = self.scale
        w, h = self.container_width, self.container_height
        if mode == 'background':
            s = 1.
            w, h = self.size
        mtop, mright, mbottom, mleft = map(lambda x: x * s, self.style['margin'])
        self.texsize = Vector(w - mleft - mright,
                              h - mtop - mbottom)
        kx, ky = self.layout.SIZE
        self.keysize = Vector(self.texsize.x / kx, self.texsize.y / ky)
        m = 3 * s
        x, y = 0, self.texsize.y - self.keysize.y

        # update display list
        self._current_cache['usedlabel'] = []
        with self._current_cache[mode]:

            # draw lines
            for index in xrange(1, ky + 1):
                line = self.layout.__getattribute__('%s_%d' % (self.mode, index))

                # draw keys
                for key in line:
                    displayed_str, internal_str, internal_action, scale = key
                    kw = self.keysize.x * scale

                    # don't display empty keys
                    if displayed_str is not None:
                        set_color(*self.style['key-color'])
                        if mode == 'background':
                            if internal_action is not None:
                                set_color(*self.style['syskey-color'])
                            drawCSSRectangle(
                                pos=(x+m, y+m),
                                size=(kw-m*2, self.keysize.y-m*2),
                                style=self.style, prefix='key')
                        elif mode == 'keys':
                            font_size = int(14 * s)
                            if font_size < 8:
                                font_size = 8
                            color = self.style['color']
                            if internal_action is not None:
                                color = self.style['color-syskey']
                            drawLabel(label=displayed_str,
                                    pos=(x + kw / 2., y + self.keysize.y / 2.),
                                    font_size=font_size, bold=False,
                                    font_name=self.style.get('font-name'),
                                    color=color)
                            self._current_cache['usedlabel'].append(getLastLabel())
                    # advance X
                    x += kw
                # advance Y
                y -= self.keysize.y
                x = 0

        # update completed
        self._need_update = None
Beispiel #31
0
 def _set_center(self, center):
     if center == self.center:
         return False
     t = Vector(*center) - self.center
     trans = translation_matrix((t.x, t.y, 0))
     self.apply_transform(trans)
Beispiel #32
0
    def process_kinetic(self):
        '''Processing of kinetic, called in draw time.'''
        dt = getFrameDt()
        todelete = []
        acceleration = self.max_acceleration

        for touchID in self.touch:
            ktouch = self.touch[touchID]
            if abs(ktouch.X) < 0.01:
                ktouch.X = 0
            else:
                ktouch.X /= 1 + (self.friction * dt)
                ktouch.X = boundary(ktouch.X, -acceleration, acceleration)
            if abs(ktouch.Y) < 0.01:
                ktouch.Y = 0
            else:
                ktouch.Y /= 1 + (self.friction * dt)
                ktouch.Y = boundary(ktouch.Y, -acceleration, acceleration)

            if ktouch.mode != 'spinning':
                continue

            # process kinetic
            event = ''
            ktouch.dxpos = ktouch.x
            ktouch.dypos = ktouch.y
            ktouch.x += ktouch.X
            ktouch.y += ktouch.Y

            if Vector(ktouch.X, ktouch.Y).length() < self.velstop:
                # simulation finished
                event = 'up'
                getCurrentTouches().remove(ktouch)
                super(MTKinetic, self).on_touch_up(ktouch)
                todelete.append(touchID)
            else:
                # simulation in progress
                event = 'move'
                super(MTKinetic, self).on_touch_move(ktouch)

            # dispatch ktouch also in grab mode
            for _wid in ktouch.grab_list[:]:
                wid = _wid()
                if wid is None:
                    ktouch.grab_list.remove(_wid)
                    continue
                ktouch.push()
                ktouch.x, ktouch.y = self.to_window(*ktouch.pos)
                ktouch.dxpos, ktouch.dypos = self.to_window(*ktouch.dpos)
                if wid.parent:
                    ktouch.x, ktouch.y = wid.parent.to_widget(
                        ktouch.x, ktouch.y)
                    ktouch.dxpos, ktouch.dypos = wid.parent.to_widget(
                        ktouch.dxpos, ktouch.dypos)
                else:
                    ktouch.x, ktouch.y = wid.to_parent(
                        *wid.to_widget(ktouch.x, ktouch.y))
                    ktouch.dxpos, ktouch.dypos = wid.to_parent(
                        *wid.to_widget(ktouch.dxpos, ktouch.dypos))
                ktouch.grab_current = wid
                ktouch.grab_state = True
                if event == 'move':
                    wid.dispatch_event('on_touch_move', ktouch)
                else:
                    # if the widget is not visible, the on_touch_up may have
                    # disabled
                    wid.register_event_type('on_touch_up')
                    wid.dispatch_event('on_touch_up', ktouch)
                ktouch.grab_state = False
                ktouch.grab_current = None
                ktouch.pop()

        # remove finished event
        for touchID in todelete:
            del self.touch[touchID]
Beispiel #33
0
class MTVectorSlider(MTWidget):
    '''
    This is a slider that provides an arrow, and allows you to manipulate
    it just like any other vector, adjusting its angle and amplitude.

    :Parameters:
        `radius` : int, default to 200
            The radius of the whole widget

    :Events:
        `on_amplitude_change`: (amplitude)
            Fired when amplitude is changed
        `on_angle_change`: (angle)
            Fired when angle is changed
        `on_vector_change`: (amplitude, angle)
            Fired when vector is changed

    :Styles:
        `vector-color` : color
            Color of the vector
        `slider-color` : color
            Color of the triangle
        `bg-color` : color
            Background color of the slider
    '''

    def __init__(self, **kwargs):
        kwargs.setdefault('radius', 200)

        super(MTVectorSlider, self).__init__(**kwargs)

        self.radius = kwargs.get('radius')

        self.vector = Vector(self.x+self.radius, self.y)
        self.amplitude = 0
        self.angle = 0

        self.register_event_type('on_amplitude_change')
        self.register_event_type('on_angle_change')
        self.register_event_type('on_vector_change')

    def on_amplitude_change(self, *largs):
        pass

    def on_angle_change(self, *largs):
        pass

    def on_vector_change(self, *largs):
        pass

    def collide_point(self, x, y):
        '''Because this widget is a circle, and this method as
        defined in MTWidget is for a square, we have to override
        it.'''
        return _get_distance(self.pos, (x, y)) <= self.radius

    def _calc_stuff(self):
        '''Recalculated the args for the callbacks'''
        self.amplitude = self.vector.distance(self.pos)
        # Make a new vector relative to the origin
        tvec = [self.vector[0], self.vector[1]]
        tvec[0] -= self.pos[0]
        tvec[1] -= self.pos[1]

        # Incase python throws float div or div by zero exception,
        # ignore them, we will be close enough
        try:
            self.angle = degrees(atan((int(tvec[1])/int(tvec[0]))))
        except Exception:
            pass

        # Ajdust quadrants so we have 0-360 degrees
        if tvec[0] < 0 and tvec[1] > 0:
            self.angle = 90 + (90 + self.angle)
        elif tvec[0] < 0 and tvec[1] < 0:
            self.angle += 180
        elif tvec[0] > 0 and tvec[1] < 0:
            self.angle = 270 + (self.angle + 90)
        elif tvec[0] > 0 and tvec[1] > 0:
            pass

    def on_touch_down(self, touch):
        if self.collide_point(touch.x, touch.y):
            self.vector[0], self.vector[1] = touch.x, touch.y
            self._calc_stuff()

            self.dispatch_event('on_aplitude_change', self.amplitude)
            self.dispatch_event('on_angle_change', self.angle)
            self.dispatch_event('on_vector_change', self.amplitude, self.angle)

            return True
    def on_touch_move(self, touch):
        if self.collide_point(touch.x, touch.y):
            self.vector[0], self.vector[1] = touch.x, touch.y
            self._calc_stuff()

            self.dispatch_event('on_aplitude_change', self.amplitude)
            self.dispatch_event('on_angle_change', self.angle)
            self.dispatch_event('on_vector_change', self.amplitude, self.angle)

            return True

    def draw(self):
        # Background
        set_color(*self.style.get('bg-color'))
        drawCircle(self.pos, self.radius)

        # A good size for the hand, proportional to the size of the widget
        hd = self.radius / 10
        # Draw center of the hand
        set_color(*self.style.get('vector-color'))
        drawCircle(self.pos, hd)
        # Rotate the triangle so its not skewed
        l = prot((self.pos[0] - hd, self.pos[1]), self.angle-90, self.pos)
        h = prot((self.pos[0] + hd, self.pos[1]), self.angle-90, self.pos)
        # Draw triable of the hand
        with gx_begin(GL_POLYGON):
            glVertex2f(*l)
            glVertex2f(*h)
            glVertex2f(self.vector[0], self.vector[1])
Beispiel #34
0
class MTVectorSlider(MTWidget):
    '''
    This is a slider that provides an arrow, and allows you to manipulate
    it just like any other vector, adjusting its angle and amplitude.

    :Parameters:
        `radius` : int, default to 200
            The radius of the whole widget

    :Events:
        `on_amplitude_change`: (amplitude)
            Fired when amplitude is changed
        `on_angle_change`: (angle)
            Fired when angle is changed
        `on_vector_change`: (amplitude, angle)
            Fired when vector is changed

    :Styles:
        `vector-color` : color
            Color of the vector
        `slider-color` : color
            Color of the triangle
        `bg-color` : color
            Background color of the slider
    '''
    def __init__(self, **kwargs):
        kwargs.setdefault('radius', 200)

        super(MTVectorSlider, self).__init__(**kwargs)

        self.radius = kwargs.get('radius')

        self.vector = Vector(self.x + self.radius, self.y)
        self.amplitude = 0
        self.angle = 0

        self.register_event_type('on_amplitude_change')
        self.register_event_type('on_angle_change')
        self.register_event_type('on_vector_change')

    def on_amplitude_change(self, *largs):
        pass

    def on_angle_change(self, *largs):
        pass

    def on_vector_change(self, *largs):
        pass

    def collide_point(self, x, y):
        '''Because this widget is a circle, and this method as
        defined in MTWidget is for a square, we have to override
        it.'''
        return _get_distance(self.pos, (x, y)) <= self.radius

    def _calc_stuff(self):
        '''Recalculated the args for the callbacks'''
        self.amplitude = self.vector.distance(self.pos)
        # Make a new vector relative to the origin
        tvec = [self.vector[0], self.vector[1]]
        tvec[0] -= self.pos[0]
        tvec[1] -= self.pos[1]

        # Incase python throws float div or div by zero exception,
        # ignore them, we will be close enough
        try:
            self.angle = degrees(atan((int(tvec[1]) / int(tvec[0]))))
        except Exception:
            pass

        # Ajdust quadrants so we have 0-360 degrees
        if tvec[0] < 0 and tvec[1] > 0:
            self.angle = 90 + (90 + self.angle)
        elif tvec[0] < 0 and tvec[1] < 0:
            self.angle += 180
        elif tvec[0] > 0 and tvec[1] < 0:
            self.angle = 270 + (self.angle + 90)
        elif tvec[0] > 0 and tvec[1] > 0:
            pass

    def on_touch_down(self, touch):
        if self.collide_point(touch.x, touch.y):
            self.vector[0], self.vector[1] = touch.x, touch.y
            self._calc_stuff()

            self.dispatch_event('on_aplitude_change', self.amplitude)
            self.dispatch_event('on_angle_change', self.angle)
            self.dispatch_event('on_vector_change', self.amplitude, self.angle)

            return True

    def on_touch_move(self, touch):
        if self.collide_point(touch.x, touch.y):
            self.vector[0], self.vector[1] = touch.x, touch.y
            self._calc_stuff()

            self.dispatch_event('on_aplitude_change', self.amplitude)
            self.dispatch_event('on_angle_change', self.angle)
            self.dispatch_event('on_vector_change', self.amplitude, self.angle)

            return True

    def draw(self):
        # Background
        set_color(*self.style.get('bg-color'))
        drawCircle(self.pos, self.radius)

        # A good size for the hand, proportional to the size of the widget
        hd = self.radius / 10
        # Draw center of the hand
        set_color(*self.style.get('vector-color'))
        drawCircle(self.pos, hd)
        # Rotate the triangle so its not skewed
        l = prot((self.pos[0] - hd, self.pos[1]), self.angle - 90, self.pos)
        h = prot((self.pos[0] + hd, self.pos[1]), self.angle - 90, self.pos)
        # Draw triable of the hand
        with gx_begin(GL_POLYGON):
            glVertex2f(*l)
            glVertex2f(*h)
            glVertex2f(self.vector[0], self.vector[1])
Beispiel #35
0
 def _get_rotation(self):
     v1 = Vector(0, 10)
     v2 = Vector(*self.to_parent(*self.pos)) - self.to_parent(self.x, self.y + 10)
     return -1.0 *(v1.angle(v2) + 180) % 360