def test_fancycontrols(self): self.imgbutton = InputImageButton("ggimages/button-round.png", self.pressbutton, (0, 0), frame=Frame(0, 0, 100, 100), qty=2) self.imgbutton.scale = 0.5 self.ii = ImageIndicator("ggimages/red-led-off-on.png", (300, 500), self.imgbutton, positioning="physical", frame=Frame(0, 0, 600, 600), qty=2) self.ii.scale = 0.1 self.glassbutton = GlassButton(None, (0, -0.5)) self.toggle = MetalToggle(0, (0, -1)) self.Li = LEDIndicator((300, 450), self.glassbutton, positioning="physical") self.Lit = LEDIndicator((300, 480), self.toggle, positioning="physical") ma = MathApp() ma.run() self.imgbutton.destroy() self.ii.destroy() self.glassbutton.destroy() self.toggle.destroy() self.Li.destroy() self.Lit.destroy()
def select(self): super().select() self._savedval = self._val self._val = 0 self._updateText(True) self.touchAsset() MathApp.listenKeyEvent("keypress", "*", self.processEvent)
def test_SRGate(self): IC1 = BoolSRFF(gateclass=BoolNAND) Inv1 = BoolNOT() Inv2 = BoolNOT() b1 = GlassButton(None, (0, 0)) b2 = GlassButton(None, (0, -0.5)) Inv1.inp = b1 Inv2.inp = b2 IC1.setinput("R", Inv1) IC1.setinput("S", Inv2) d1 = LEDIndicator((0.5, 0), IC1) d2 = LEDIndicator((0.5, -0.5), IC1.q_) ma = MathApp() ma.run() for i in range(10): time.sleep(1 / 60) ma.step() for o in [IC1, Inv1, Inv2, b1, b2, d1, d2]: o.destroy()
def test_controls(self): self.imgbutton = InputImageButton("ggimages/button-round.png", self.pressbutton, (0, 0), frame=Frame(0, 0, 100, 100), qty=2) self.imgbutton.scale = 0.5 self.vslider1 = Slider((100, 150), 0, 250, 125, positioning='physical', steps=10) self.label = Label(self.labelcoords, self.buttonstatus, size=15, positioning="physical", color=self.labelcolor) self.button = InputButton(self.pressbutton, self.buttoncoords, "Press Me", size=15, positioning="physical") self.numinput = InputNumeric((300, 275), 3.14, positioning="physical") ma = MathApp() ma.run() self.vslider1.destroy() self.label.destroy() self.button.destroy() self.numinput.destroy() self.imgbutton.destroy()
def __init__(self): super().__init__() self._once = [] self._callbacks = {} self._time = 0 self.reset() MathApp.addDynamic(self) # always dynamically defined
def test_geometry(self): self.ip = ImagePoint("bunny.png", (0, 0)) self.ip.movable = True self.p1 = Point((0, 0), color=Color(0x008000, 1)) self.p1.movable = True self.p2 = Point((0, -1)) self.p3 = Point((1.2, 0)) self.l1 = LineSegment(self.p2, self.p3, style=LineStyle(3, Color(0, 1))) self.l2 = LineSegment(self.p2, self.p1, style=LineStyle(3, Color(0, 1))) self.c2 = Circle((-1, -1), self.p1) ma = MathApp() ma.run() self.ip.destroy() self.p1.destroy() self.p2.destroy() self.p3.destroy() self.c2.destroy() self.l1.destroy() self.l2.destroy()
def movable(self, val): if not self._dynamic: self._movable = val if val: MathApp._addMovable(self) else: MathApp._removeMovable(self)
def test_fancycontrols(self): self.imgbutton = InputImageButton( "ggame/images/button-round.png", self.pressbutton, (0, 0), frame=Frame(0, 0, 100, 100), qty=2, ) self.imgbutton.scale = 0.5 self.ii = ImageIndicator( "ggame/images/red-led-off-on.png", (300, 500), self.imgbutton, positioning="physical", frame=Frame(0, 0, 600, 600), qty=2, ) self.ii.scale = 0.1 self.glassbutton = GlassButton(None, (0, -0.5)) self.toggle = MetalToggle(0, (0, -1)) self.Li = LEDIndicator((300, 450), self.glassbutton, positioning="physical") self.Lit = LEDIndicator((300, 480), self.toggle, positioning="physical") ma = MathApp() ma.run() self.imgbutton.destroy() self.ii.destroy() self.glassbutton.destroy() self.toggle.destroy() self.Li.destroy() self.Lit.destroy()
def __init__(self): super().__init__() self.once = [] self.callbacks = {} self.reset() self.step() self.next = None MathApp._addDynamic(self) # always dynamically defined
def unselect(self): super().unselect() self._val = self._savedval self._updateText() self.touchAsset() try: MathApp.unlistenKeyEvent("keypress", "*", self.processEvent) except ValueError: pass
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))
def test_timer(self): self.callbackcomplete = False self.timer = Timer() self.timer.callAfter(0.1, self.timercallback) ma = MathApp() ma.run() for i in range(10): time.sleep(1 / 60) ma._animate(1) self.assertEquals(self.callbackcomplete, True) self.timer.destroy()
def _buildAsset(self): pcenter = self._spposinputs.pos try: pradius = ( MathApp.distance(self._posinputs.pos(), self._nposinputs.radius()) * MathApp.scale ) except (AttributeError, TypeError): # pylint: disable=no-member pradius = self._nposinputs.radius() * MathApp.scale # pylint: enable=no-member style = self._stdinputs.style() fill = self._stdinputs.color() ymax = pcenter[1] + pradius ymin = pcenter[1] - pradius xmax = pcenter[0] + pradius xmin = pcenter[0] - pradius try: if ymin > MathApp.height or ymax < 0 or xmax < 0 or xmin > MathApp.width: return CircleAsset(pradius, style, fill) if pradius > 2 * MathApp.width: # here begins unpleasant hack to overcome crappy circles poly = self._buildPolygon(pcenter, pradius) if poly: passet = PolygonAsset(poly, style, fill) return passet except AttributeError: return CircleAsset(pradius, style, fill) return CircleAsset(pradius, style, fill)
def physicalPointTouching(self, ppos): r = MathApp.distance(self._spposinputs.pos(), ppos) # pylint: disable=no-member pradius = self._nposinputs.radius() * MathApp.scale # pylint: enable=no-member style = self._stdinputs.style() inner = pradius - style.width / 2 outer = pradius + style.width / 2 return inner <= r <= outer
def physicalPointTouching(self, ppos): """ Determine if a physical point is considered to be touching this point. :param tuple(int,int) ppos: Physical screen coordinates. :rtype: boolean :returns: True if touching, False otherwise. """ return MathApp.distance(ppos, self._pposinputs.pos) < self._sstdinputs.size
def distanceTo(self, otherpoint): """ Compute the distance to another :class:`_Point` object. :param _Point otherpoint: A reference to the other :class:`_Point` :rtype: float :returns: The distance (in logical units) to the other point """ try: return MathApp.distance(self(), otherpoint()) except AttributeError: return otherpoint # presumably a scalar - use this distance
def translate(self, pdisp): """ Perform necessary processing in response to being moved by the mouse/UI. :param tuple(int,int) pdisp: Translation vector (x,y) in physical screen units. :returns: None """ ldisp = MathApp.translatePhysicalToLogical(pdisp) pos = self._posinputs.pos() self._posinputs = self._posinputs._replace(pos=self.Eval((pos[0] + ldisp[0], pos[1] + ldisp[1]))) self._touchAsset()
def physicalPointTouching(self, ppos): """ Determine if a physical point is considered to be touching this point. :param tuple(int,int) ppos: Physical screen coordinates. :rtype: boolean :returns: True if touching, False otherwise. """ return ( MathApp.distance(ppos, self._pposinputs.pos) # pylint: disable=no-member < self._sstdinputs.size )
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 __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 test_SRGate(self): IC1 = BoolSRFF(gateclass=BoolNAND) Inv1 = BoolNOT() Inv2 = BoolNOT() b1 = GlassButton(None, (0, 0)) b2 = GlassButton(None, (0, -0.5)) Inv1.In = b1 Inv2.In = b2 IC1.SetInput('R', Inv1) IC1.SetInput('S', Inv2) d1 = LEDIndicator((0.5, 0), IC1) d2 = LEDIndicator((0.5, -0.5), IC1.Q_) ma = MathApp() ma.run() for i in range(10): time.sleep(1 / 60) ma.step() for o in [IC1, Inv1, Inv2, b1, b2, d1, d2]: o.destroy()
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 translate(self, pdisp): """ Perform necessary processing in response to being moved by the mouse/UI. :param tuple(int,int) pdisp: Translation vector (x,y) in physical screen units. :returns: None """ ldisp = MathApp.translatePhysicalToLogical(pdisp) pos = self._posinputs.pos() self._posinputs = self._posinputs._replace( pos=self.eval((pos[0] + ldisp[0], pos[1] + ldisp[1])) ) self.touchAsset()
def test_gates(self): IC1 = BoolNOT() IC2 = BoolAND() b1 = MetalToggle(1, (1, 0)) b2 = MetalToggle(1, (1, 0.3)) db1 = LEDIndicator((1.3, 0), b1) db2 = LEDIndicator((1.3, 0.3), b2) b3 = MetalToggle(1, (1, 0.6)) b4 = MetalToggle(1, (1, 0.9)) db1 = LEDIndicator((1.3, 0.6), b3) db2 = LEDIndicator((1.3, 0.9), b4) d2 = LEDIndicator((1.5, 0.45), IC2) IC2.inp = b1, b2 IC2.inp = IC2.inp + [b3, b4] button = GlassButton(None, (0, 0)) LED = LEDIndicator((0, -1), IC1) IC1.inp = button t1 = MetalToggle(1, (1, -1)) t2 = MetalToggle(1, (1, -1.3)) dt1 = LEDIndicator((1.3, -1), t1) dt2 = LEDIndicator((1.3, -1.3), t2) ma = MathApp() ma.run() for i in range(10): time.sleep(1 / 60) ma.step() for o in [b1, b2, db1, db2, b3, b4, IC1, IC2, button, LED, t1, t2, dt1, dt2]: o.destroy()
def test_controls(self): self.imgbutton = InputImageButton( "ggame/images/button-round.png", self.pressbutton, (0, 0), frame=Frame(0, 0, 100, 100), qty=2, ) self.imgbutton.scale = 0.5 self.vslider1 = Slider( (100, 150), 0, 250, 125, positioning="physical", steps=10 ) self.label = Label( self.labelcoords, self.buttonstatus, size=15, positioning="physical", color=self.labelcolor, ) self.button = InputButton( self.pressbutton, self.buttoncoords, "Press Me", size=15, positioning="physical", ) self.numinput = InputNumeric((300, 275), 3.14, positioning="physical") ma = MathApp() ma.run() self.vslider1.destroy() self.label.destroy() self.button.destroy() self.numinput.destroy() self.imgbutton.destroy()
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 _getPhysicalInputs(self): """ Translate all positional inputs to physical """ pplist = [] if self.positioning == 'logical': for p in self.posinputs: pval = p() try: pp = MathApp.logicalToPhysical(pval) except AttributeError: pp = MathApp._scale * pval pplist.append(pp) else: # already physical pplist = [p() for p in self.posinputs] self.pposinputs = self.PI(*pplist)
def test_gates(self): IC1 = BoolNOT() IC2 = BoolAND() b1 = MetalToggle(1, (1, 0)) b2 = MetalToggle(1, (1, 0.3)) db1 = LEDIndicator((1.3, 0), b1) db2 = LEDIndicator((1.3, 0.3), b2) b3 = MetalToggle(1, (1, 0.6)) b4 = MetalToggle(1, (1, 0.9)) db1 = LEDIndicator((1.3, 0.6), b3) db2 = LEDIndicator((1.3, 0.9), b4) d2 = LEDIndicator((1.5, 0.45), IC2) IC2.In = b1, b2 IC2.In = IC2.In + [b3, b4] button = GlassButton(None, (0, 0)) LED = LEDIndicator((0, -1), IC1) IC1.In = button t1 = MetalToggle(1, (1, -1)) t2 = MetalToggle(1, (1, -1.3)) dt1 = LEDIndicator((1.3, -1), t1) dt2 = LEDIndicator((1.3, -1.3), t2) ma = MathApp() ma.run() for i in range(10): time.sleep(1 / 60) ma.step() for o in [ b1, b2, db1, db2, b3, b4, IC1, IC2, button, LED, t1, t2, dt1, dt2 ]: o.destroy()
def destroy(self): MathApp._removeDynamic(self)
def _setDynamic(self): MathApp._addDynamic(self) self._dynamic = True
def physicalPointTouching(self, ppos): r = MathApp.distance(self._pcenter, ppos) inner = self._pradius - self.style.width / 2 outer = self._pradius + self.style.width / 2 return r <= outer and r >= inner
""" Example of using MathApp InputButton class. """ from ggame.input import InputButton from ggame.mathapp import MathApp def pressbutton(_button): """ Callback function executed when button is pressed. """ print("InputButton pressed!") InputButton( pressbutton, # reference to handler (20, 80), # physical location on screen "Press Me", # text to display size=15, # text size (pixels) positioning="physical", ) # use physical coordinates MathApp().run()
def destroy(self): MathApp._removeVisual(self) MathApp._removeMovable(self) MathApp._removeStrokable(self) _MathDynamic.destroy(self) Sprite.destroy(self)
def selectable(self, val): self._selectable = val if val: MathApp._addSelectable(self) else: MathApp._removeSelectable(self)
def strokable(self, val): self._strokable = val if val: MathApp._addStrokable(self) else: MathApp._removeStrokable(self)