예제 #1
0
 def __init__(self, *args, **kwargs):
     super().__init__(RectangleAsset(1, 1), *args, **kwargs)
     self._val = self._nposinputs.initial()
     self._steps = kwargs.get('steps', 50)
     self._step = (self._nposinputs.maxval() -
                   self._nposinputs.minval()) / self._steps
     self._leftctrl = kwargs.get('leftkey', None)
     self._rightctrl = kwargs.get('rightkey', None)
     self._centerctrl = kwargs.get('centerkey', None)
     self.selectable = True  # must be after super init!
     self.strokable = True  # this enables grabbing/slideing the thumb
     self.thumbcaptured = False
     self._thumbwidth = max(self._stdinputs.width() / 40, 1)
     self._thumb = Sprite(
         RectangleAsset(self._thumbwidth,
                        self._stdinputs.size() - 2,
                        LineStyle(1, self._stdinputs.color()),
                        self._stdinputs.color()), self._thumbXY())
     self._touchAsset()
     if self._leftctrl:
         MathApp.listenKeyEvent("keydown", self._leftctrl, self.moveLeft)
     if self._rightctrl:
         MathApp.listenKeyEvent("keydown", self._rightctrl, self.moveRight)
     if self._centerctrl:
         MathApp.listenKeyEvent("keydown", self._centerctrl,
                                self.moveCenter)
예제 #2
0
    def __init__(self, asset, *args, **kwargs):
        """
        Required inputs
        
        * **asset** a ggame asset
        * **args** the list of required positional and nonpositional arguments,
          as named in the posinputsdef and nonposinputsdef lists
        * **kwargs** all other optional keyword arguments:
          positioning - logical (default) or physical, size, width, color, style
          movable
        
        """

        MathApp._addVisual(self)
        #Sprite.__init__(self, asset, args[0])
        _MathDynamic.__init__(self)
        self._movable = False
        self._selectable = False
        self._strokable = False
        self.selected = False
        self.mouseisdown = False
        #
        self.positioning = kwargs.get('positioning', 'logical')
        # positional inputs
        self.PI = namedtuple('PI', self.posinputsdef)
        # nonpositional inputs
        self.NPI = namedtuple('NPI', self.nonposinputsdef)
        # standard inputs (not positional)
        standardargs = ['size', 'width', 'color', 'style']
        self.SI = namedtuple('SI', standardargs)
        # correct number of args?
        if len(args) != len(self.posinputsdef) + len(self.nonposinputsdef):
            raise TypeError("Incorrect number of parameters provided")
        self.args = args
        # generated named tuple of functions from positional inputs
        self.posinputs = self.PI(*[self.Eval(p)
                                   for p in args][:len(self.posinputsdef)])
        self._getPhysicalInputs()
        # first positional argument must be a sprite position!
        Sprite.__init__(self, asset, self.pposinputs[0])
        # generated named tuple of functions from nonpositional inputs
        if len(self.nonposinputsdef) > 0:
            self.nposinputs = self.NPI(
                *[self.Eval(p)
                  for p in args][(-1 * len(self.nonposinputsdef)):])
        else:
            self.nposinputs = []
        self.stdinputs = self.SI(
            self.Eval(kwargs.get('size', self.defaultsize)),
            self.Eval(kwargs.get('width', self.defaultwidth)),
            self.Eval(kwargs.get('color', self.defaultcolor)),
            self.Eval(kwargs.get('style', self.defaultstyle)))
        self.sposinputs = self.PI(*[0] * len(self.posinputs))
        self.spposinputs = self.PI(*self.pposinputs)
        self.snposinputs = self.NPI(*[0] * len(self.nposinputs))
        self.sstdinputs = self.SI(*[0] * len(self.stdinputs))
예제 #3
0
 def __init__(self, asset, *args, **kwargs):
     MathApp.addVisual(self)
     # Sprite.__init__(self, asset, args[0])
     _MathDynamic.__init__(self)
     self._movable = False
     self._selectable = False
     self._strokable = False
     self.selected = False
     """
     True if object is currently selected by the UI.
     """
     self.mouseisdown = False
     """
     True if object is tracking UI mouse button as down.
     """
     self._positioning = kwargs.get("positioning", "logical")
     # positional inputs
     self._pi = namedtuple("PI", self._posinputsdef)
     # nonpositional inputs
     self._npi = namedtuple("NPI", self._nonposinputsdef)
     # standard inputs (not positional)
     standardargs = ["size", "width", "color", "style"]
     self._si = namedtuple("SI", standardargs)
     # correct number of args?
     if len(args) != len(self._posinputsdef) + len(self._nonposinputsdef):
         raise TypeError("Incorrect number of parameters provided")
     self._args = args
     # generated named tuple of functions from positional inputs
     self._posinputs = self._pi(
         *[self.eval(p) for p in args][: len(self._posinputsdef)]
     )
     self._getPhysicalInputs()
     # first positional argument must be a sprite position!
     Sprite.__init__(self, asset, self._pposinputs[0])
     # generated named tuple of functions from nonpositional inputs
     if self._nonposinputsdef:
         self._nposinputs = self._npi(
             *[self.eval(p) for p in args][(-1 * len(self._nonposinputsdef)) :]
         )
     else:
         self._nposinputs = []
     self._stdinputs = self._si(
         self.eval(kwargs.get("size", self._defaultsize)),
         self.eval(kwargs.get("width", self._defaultwidth)),
         self.eval(kwargs.get("color", self._defaultcolor)),
         self.eval(kwargs.get("style", self._defaultstyle)),
     )
     self._sposinputs = self._pi(*[0] * len(self._posinputs))
     self._spposinputs = self._pi(*self._pposinputs)
     self._snposinputs = self._npi(*[0] * len(self._nposinputs))
     self._sstdinputs = self._si(*[0] * len(self._stdinputs))
예제 #4
0
 def __init__(self, asset, *args, **kwargs):
     MathApp.addVisual(self)
     # Sprite.__init__(self, asset, args[0])
     _MathDynamic.__init__(self)
     self._movable = False
     self._selectable = False
     self._strokable = False
     self.selected = False
     """
     True if object is currently selected by the UI.
     """
     self.mouseisdown = False
     """
     True if object is tracking UI mouse button as down.
     """
     self._positioning = kwargs.get("positioning", "logical")
     # positional inputs
     self._pi = namedtuple("PI", self._posinputsdef)
     # nonpositional inputs
     self._npi = namedtuple("NPI", self._nonposinputsdef)
     # standard inputs (not positional)
     standardargs = ["size", "width", "color", "style"]
     self._si = namedtuple("SI", standardargs)
     # correct number of args?
     if len(args) != len(self._posinputsdef) + len(self._nonposinputsdef):
         raise TypeError("Incorrect number of parameters provided")
     self._args = args
     # generated named tuple of functions from positional inputs
     self._posinputs = self._pi(*[self.eval(p)
                                  for p in args][:len(self._posinputsdef)])
     self._getPhysicalInputs()
     # first positional argument must be a sprite position!
     Sprite.__init__(self, asset, self._pposinputs[0])
     # generated named tuple of functions from nonpositional inputs
     if self._nonposinputsdef:
         self._nposinputs = self._npi(
             *[self.eval(p)
               for p in args][(-1 * len(self._nonposinputsdef)):])
     else:
         self._nposinputs = []
     self._stdinputs = self._si(
         self.eval(kwargs.get("size", self._defaultsize)),
         self.eval(kwargs.get("width", self._defaultwidth)),
         self.eval(kwargs.get("color", self._defaultcolor)),
         self.eval(kwargs.get("style", self._defaultstyle)),
     )
     self._sposinputs = self._pi(*[0] * len(self._posinputs))
     self._spposinputs = self._pi(*self._pposinputs)
     self._snposinputs = self._npi(*[0] * len(self._nposinputs))
     self._sstdinputs = self._si(*[0] * len(self._stdinputs))
예제 #5
0
 def __init__(self, *args, **kwargs):
     super().__init__(RectangleAsset(1, 1), *args, **kwargs)
     self._val = self._nposinputs.initial()  # pylint: disable=no-member
     self._steps = kwargs.get("steps", 50)
     self._step = (
         self._nposinputs.maxval()  # pylint: disable=no-member
         - self._nposinputs.minval()  # pylint: disable=no-member
     ) / self._steps
     self._leftctrl = kwargs.get("leftkey", None)
     self._rightctrl = kwargs.get("rightkey", None)
     self._centerctrl = kwargs.get("centerkey", None)
     self.selectable = True  # must be after super init!
     self.strokable = True  # this enables grabbing/slideing the thumb
     self.thumbcaptured = False
     self._thumbwidth = max(self._stdinputs.width() / 40, 1)
     self._thumb = Sprite(
         RectangleAsset(
             self._thumbwidth,
             self._stdinputs.size() - 2,
             LineStyle(1, self._stdinputs.color()),
             self._stdinputs.color(),
         ),
         self._thumbXY(),
     )
     self.touchAsset()
     if self._leftctrl:
         MathApp.listenKeyEvent("keydown", self._leftctrl, self._moveLeft)
     if self._rightctrl:
         MathApp.listenKeyEvent("keydown", self._rightctrl, self._moveRight)
     if self._centerctrl:
         MathApp.listenKeyEvent("keydown", self._centerctrl, self._moveCenter)
예제 #6
0
 def destroy(self):
     MathApp.removeVisual(self)
     MathApp.removeMovable(self)
     MathApp.removeStrokable(self)
     _MathDynamic.destroy(self)
     Sprite.destroy(self)
예제 #7
0
class Slider(_MathVisual):
    """
    Create a 'slider' style numeric input control on the screen. This is a 
    subclass of :class:`~ggame.sprite.Sprite` and 
    :class:`~ggame.mathapp._MathVisual` but most of the inherited 
    members are of little use and are not shown in the documentation. 


    :param \*args:
        See below
    :param \**kwargs:
        See below

    :Required Arguments:
        * **pos**  (*tuple(float,float)*) Screen position of the slider, which may
            be a literal tuple of floats, or a reference to any object or 
            function that returns or evaluates to a tuple of floats.
        * **minval** (*float*) The minimum value of the slider
        * **maxval** (*float*) The maximum value of the slider
        * **initial** (*float*) The initial value of the slider


    :Optional Keyword Arguments:
        * **steps** (*int*) Number of steps between minval and maxval (default 50)
        * **leftkey** (*str*) Name of a keyboard key that will make the 
            slider control step down (move left) (default None). See 
            :class:`~ggame.event.KeyEvent` for a list of names.
        * **rightkey** (*str*) Name of a keyboard key that will make the slider
            control step up (move right) (default None) 
        * **centerkey** (*str*) Name of a keyboard key that will make the slider
            move to its center position (default None)
        * **positioning** (*str*) One of 'logical' or 'physical'
        * **size** (*int*) Width of the slider (in pixels)
        * **color** (*Color*) Valid :class:`~ggame.asset.Color` object
        * **style** (*LineStyle*) Valid :class:`~ggame.asset.LineStyle` object
        
    Example::
    
    
        from ggame.slider import Slider
        from ggame.mathapp import MathApp
    
        s = Slider(
            (100, 150),     # screen position
            0,              # minimum value
            250,            # maximum value
            125,            # initial value
            positioning='physical', # use physical coordinates for position
            steps=10)       # 10 steps between 125 and 250
            
        MathApp().run()

        
    """
    _posinputsdef = ['pos']
    _nonposinputsdef = ['minval', 'maxval', 'initial']

    def __init__(self, *args, **kwargs):
        super().__init__(RectangleAsset(1, 1), *args, **kwargs)
        self._val = self._nposinputs.initial()
        self._steps = kwargs.get('steps', 50)
        self._step = (self._nposinputs.maxval() -
                      self._nposinputs.minval()) / self._steps
        self._leftctrl = kwargs.get('leftkey', None)
        self._rightctrl = kwargs.get('rightkey', None)
        self._centerctrl = kwargs.get('centerkey', None)
        self.selectable = True  # must be after super init!
        self.strokable = True  # this enables grabbing/slideing the thumb
        self.thumbcaptured = False
        self._thumbwidth = max(self._stdinputs.width() / 40, 1)
        self._thumb = Sprite(
            RectangleAsset(self._thumbwidth,
                           self._stdinputs.size() - 2,
                           LineStyle(1, self._stdinputs.color()),
                           self._stdinputs.color()), self._thumbXY())
        self._touchAsset()
        if self._leftctrl:
            MathApp.listenKeyEvent("keydown", self._leftctrl, self.moveLeft)
        if self._rightctrl:
            MathApp.listenKeyEvent("keydown", self._rightctrl, self.moveRight)
        if self._centerctrl:
            MathApp.listenKeyEvent("keydown", self._centerctrl,
                                   self.moveCenter)

    def _thumbXY(self):
        minval = self._nposinputs.minval()
        maxval = self._nposinputs.maxval()
        return (self._spposinputs.pos[0] + (self._val - minval) *
                (self._sstdinputs.width - self._thumbwidth) /
                (maxval - minval), self._spposinputs.pos[1] + 1)

    def __call__(self):
        return self._val

    @property
    def value(self):
        return self._val

    @value.setter
    def value(self, val):
        self._setval(val)

    def _buildAsset(self):
        self._setThumb()
        return RectangleAsset(self._stdinputs.width(),
                              self._stdinputs.size(),
                              line=self._stdinputs.style(),
                              fill=Color(0, 0))

    def _setThumb(self):
        self._thumb.position = self._thumbXY()

    def step(self):
        pass

    def _setval(self, val):
        minval = self._nposinputs.minval()
        maxval = self._nposinputs.maxval()
        if val <= minval:
            self._val = minval
        elif val >= maxval:
            self._val = maxval
        else:
            self._val = round((val - minval) * self._steps /
                              (maxval - minval)) * self._step + minval
        self._setThumb()

    def increment(self, step):
        self._setval(self._val + step)

    def select(self):
        super().select()
        if not self._leftctrl:
            MathApp.listenKeyEvent("keydown", "left arrow", self._moveLeft)
        if not self._rightctrl:
            MathApp.listenKeyEvent("keydown", "right arrow", self._moveRight)
        MathApp.listenMouseEvent("click", self._mouseClick)

    def unselect(self):
        super().unselect()
        try:
            if not self._leftctrl:
                MathApp.unlistenKeyEvent("keydown", "left arrow",
                                         self._moveLeft)
            if not self._rightctrl:
                MathApp.unlistenKeyEvent("keydown", "right arrow",
                                         self._moveRight)
            MathApp.unlistenMouseEvent("click", self._mouseClick)
        except ValueError:
            pass

    def _mouseClick(self, event):
        if self.physicalPointTouching((event.x, event.y)):
            if event.x > self.thumb.x + self._thumbwidth:
                self._moveRight(event)
            elif event.x < self.thumb.x:
                self._moveLeft(event)

    def _moveLeft(self, event):
        self.increment(-self._step)

    def _moveRight(self, event):
        self.increment(self._step)

    def _moveCenter(self, event):
        self._val = (self._snposinputs.minval + self._snposinputs.maxval) / 2
        self._setThumb()

    def canstroke(self, ppos):
        return self.physicalPointTouchingThumb(ppos)

    def stroke(self, ppos, pdisp):
        _ppos = self._spposinputs.pos
        minval = self._snposinputs.minval
        maxval = self._snposinputs.maxval
        xpos = ppos[0] + pdisp[0]
        self.value = (xpos - _ppos[0]) * (
            maxval - minval) / self._sstdinputs.width + minval

    def physicalPointTouching(self, ppos):
        _ppos = self._spposinputs.pos
        return (ppos[0] >= _ppos[0]
                and ppos[0] <= _ppos[0] + self._sstdinputs.width
                and ppos[1] >= _ppos[1]
                and ppos[1] <= _ppos[1] + self._sstdinputs.size)

    def physicalPointTouchingThumb(self, ppos):
        thumbpos = self._thumbXY()
        return (ppos[0] >= thumbpos[0]
                and ppos[0] <= thumbpos[0] + self._thumbwidth + 2
                and ppos[1] >= thumbpos[1]
                and ppos[1] <= thumbpos[1] + self._sstdinputs.size - 2)

    def translate(self, pdisp):
        pass

    def destroy(self):
        self._thumb.destroy()
        super().destroy()
예제 #8
0
"""
Example of using Sprite class.
"""
from ggame.sprite import Sprite
from ggame.asset import ImageAsset, CircleAsset
from ggame.app import App

PLAYER = Sprite(ImageAsset("bunny.png"), (100, 100), CircleAsset(50))

App().run()
예제 #9
0
 def destroy(self):
     MathApp._removeVisual(self)
     MathApp._removeMovable(self)
     MathApp._removeStrokable(self)
     _MathDynamic.destroy(self)
     Sprite.destroy(self)
예제 #10
0
class Slider(_MathVisual):
    """
    Create a 'slider' style numeric input control on the screen. This is a
    subclass of :class:`~ggame.sprite.Sprite` and
    :class:`~ggame.mathapp._MathVisual` but most of the inherited
    members are of little use and are not shown in the documentation.


    :param \\*args:
        See below
    :param \\**kwargs:
        See below

    :Required Arguments:
        * **pos**  (*tuple(float,float)*) Screen position of the slider, which may
            be a literal tuple of floats, or a reference to any object or
            function that returns or evaluates to a tuple of floats.
        * **minval** (*float*) The minimum value of the slider
        * **maxval** (*float*) The maximum value of the slider
        * **initial** (*float*) The initial value of the slider


    :Optional Keyword Arguments:
        * **steps** (*int*) Number of steps between minval and maxval (default 50)
        * **leftkey** (*str*) Name of a keyboard key that will make the
            slider control step down (move left) (default None). See
            :class:`~ggame.event.KeyEvent` for a list of names.
        * **rightkey** (*str*) Name of a keyboard key that will make the slider
            control step up (move right) (default None)
        * **centerkey** (*str*) Name of a keyboard key that will make the slider
            move to its center position (default None)
        * **positioning** (*str*) One of 'logical' or 'physical'
        * **size** (*int*) Width of the slider (in pixels)
        * **color** (*Color*) Valid :class:`~ggame.asset.Color` object
        * **style** (*LineStyle*) Valid :class:`~ggame.asset.LineStyle` object

    Example:

    .. literalinclude:: ../examples/sliderslider.py

    """

    _posinputsdef = ["pos"]
    _nonposinputsdef = ["minval", "maxval", "initial"]

    def __init__(self, *args, **kwargs):
        super().__init__(RectangleAsset(1, 1), *args, **kwargs)
        self._val = self._nposinputs.initial()  # pylint: disable=no-member
        self._steps = kwargs.get("steps", 50)
        self._step = (
            self._nposinputs.maxval()  # pylint: disable=no-member
            - self._nposinputs.minval()  # pylint: disable=no-member
        ) / self._steps
        self._leftctrl = kwargs.get("leftkey", None)
        self._rightctrl = kwargs.get("rightkey", None)
        self._centerctrl = kwargs.get("centerkey", None)
        self.selectable = True  # must be after super init!
        self.strokable = True  # this enables grabbing/slideing the thumb
        self.thumbcaptured = False
        self._thumbwidth = max(self._stdinputs.width() / 40, 1)
        self._thumb = Sprite(
            RectangleAsset(
                self._thumbwidth,
                self._stdinputs.size() - 2,
                LineStyle(1, self._stdinputs.color()),
                self._stdinputs.color(),
            ),
            self._thumbXY(),
        )
        self.touchAsset()
        if self._leftctrl:
            MathApp.listenKeyEvent("keydown", self._leftctrl, self._moveLeft)
        if self._rightctrl:
            MathApp.listenKeyEvent("keydown", self._rightctrl, self._moveRight)
        if self._centerctrl:
            MathApp.listenKeyEvent("keydown", self._centerctrl, self._moveCenter)

    def _thumbXY(self):
        minval = self._nposinputs.minval()  # pylint: disable=no-member
        maxval = self._nposinputs.maxval()  # pylint: disable=no-member
        return (
            self._spposinputs.pos[0]
            + (self._val - minval)
            * (self._sstdinputs.width - self._thumbwidth)
            / (maxval - minval),
            self._spposinputs.pos[1] + 1,
        )

    def __call__(self):
        return self._val

    @property
    def value(self):
        """
        Report value of the slider. Attribute is get-able and set-able.
        """
        return self._val

    @value.setter
    def value(self, val):
        self._setval(val)

    def _buildAsset(self):
        self._setThumb()
        return RectangleAsset(
            self._stdinputs.width(),
            self._stdinputs.size(),
            line=self._stdinputs.style(),
            fill=Color(0, 0),
        )

    def _setThumb(self):
        self._thumb.position = self._thumbXY()

    def step(self):
        pass

    def _setval(self, val):
        minval = self._nposinputs.minval()  # pylint: disable=no-member
        maxval = self._nposinputs.maxval()  # pylint: disable=no-member
        if val <= minval:
            self._val = minval
        elif val >= maxval:
            self._val = maxval
        else:
            self._val = (
                round((val - minval) * self._steps / (maxval - minval)) * self._step
                + minval
            )
        self._setThumb()

    def increment(self, step):
        """
        Increment the slider value.

        :param float step: The amount by which the slider control should be adjusted.
        :returns: None
        """

        self._setval(self._val + step)

    def select(self):
        super().select()
        if not self._leftctrl:
            MathApp.listenKeyEvent("keydown", "left arrow", self._moveLeft)
        if not self._rightctrl:
            MathApp.listenKeyEvent("keydown", "right arrow", self._moveRight)
        MathApp.listenMouseEvent("click", self._mouseClick)

    def unselect(self):
        super().unselect()
        try:
            if not self._leftctrl:
                MathApp.unlistenKeyEvent("keydown", "left arrow", self._moveLeft)
            if not self._rightctrl:
                MathApp.unlistenKeyEvent("keydown", "right arrow", self._moveRight)
            MathApp.unlistenMouseEvent("click", self._mouseClick)
        except ValueError:
            pass

    def _mouseClick(self, event):
        if self.physicalPointTouching((event.x, event.y)):
            if event.x > self._thumb.x + self._thumbwidth:
                self._moveRight(event)
            elif event.x < self._thumb.x:
                self._moveLeft(event)

    def _moveLeft(self, _event):
        self.increment(-self._step)

    def _moveRight(self, _event):
        self.increment(self._step)

    def _moveCenter(self, _event):
        self._val = (self._snposinputs.minval + self._snposinputs.maxval) / 2
        self._setThumb()

    def canstroke(self, ppos):
        """
        Function returns true if the given physical position corresponds with a part
        of the slider that can be dragged (i.e. the thumb).

        :param (float,float) ppos: Physical screen coordinates.
        :return: True if the position represents a draggable part of the control.
        :rtype: boolean

        """
        return self.physicalPointTouchingThumb(ppos)

    def stroke(self, ppos, pdisp):
        """
        Function performs the action of stroking or click-dragging on the slider
        control (i.e. dragging the thumb).

        :param (float, float) ppos: Physical screen coordinates.
        :param (float, float) pdisp: Physical displacement vector.
        :return: None

        """
        _ppos = self._spposinputs.pos
        minval = self._snposinputs.minval
        maxval = self._snposinputs.maxval
        xpos = ppos[0] + pdisp[0]
        self.value = (xpos - _ppos[0]) * (
            maxval - minval
        ) / self._sstdinputs.width + minval

    def physicalPointTouching(self, ppos):
        _ppos = self._spposinputs.pos
        return (
            ppos[0] >= _ppos[0]
            and ppos[0] <= _ppos[0] + self._sstdinputs.width
            and ppos[1] >= _ppos[1]
            and ppos[1] <= _ppos[1] + self._sstdinputs.size
        )

    def physicalPointTouchingThumb(self, ppos):
        """
        Determine if a physical screen location is touching the slider "thumb".

        :param (float, float) ppos: Physical screen coordinates.
        :returns: True if touching, False otherwise.
        :rtype: boolean
        """

        thumbpos = self._thumbXY()
        return (
            ppos[0] >= thumbpos[0]
            and ppos[0] <= thumbpos[0] + self._thumbwidth + 2
            and ppos[1] >= thumbpos[1]
            and ppos[1] <= thumbpos[1] + self._sstdinputs.size - 2
        )

    def translate(self, pdisp):
        pass

    def destroy(self):
        self._thumb.destroy()
        super().destroy()