class Car(Widget): angle = BoundedNumericProperty(0.0) #angle = float(0.0) #angle = ObjectProperty('float') rotation = BoundedNumericProperty(0.0) #rotation = ObjectProperty('float') #rotation = float(0.0) velocity_x = BoundedNumericProperty(0) velocity_y = BoundedNumericProperty(0) velocity = ReferenceListProperty(velocity_x, velocity_y) event1 = None queue1_1 = None queue1_2 = None event2 = None queue2 = None event3 = None queue3 = None def move(self, rotation): #self.pos = Vector(*self.velocity) + self.pos self.x = int(self.velocity_x + self.x) self.y = int(self.velocity_y + self.y) self.pos = Vector(self.x, self.y) #self.pos = Vector(self.x, self.y) self.rotation = rotation self.angle = self.angle + self.rotation
class Debris(FloatLayout): velocity_x = NumericProperty(0) velocity_y = NumericProperty(0) red = BoundedNumericProperty(1.0, min=0.0, max=1.0) green = BoundedNumericProperty(0.5, min=0.0, max=1.0) DURATION = 25. def __init__(self, **kwargs): super(Debris, self).__init__(**kwargs) def launch(self): a = Animation( center_x=self.center_x + self.DURATION * FPS * self.velocity_x, center_y=self.center_y + self.DURATION * FPS * self.velocity_y, height=7.5, red=0.5 * self.red, green=0.0, d=self.DURATION * FPS, s=FPS, ) a.bind(on_complete=self.on_stop) a.start(self) def on_stop(self, animation, widget): if self.parent is not None: self.parent.remove_widget(self)
class MDCard(ThemableBehavior, ElevationBehaviour, BoxLayout): r = BoundedNumericProperty(1., min=0., max=1.) g = BoundedNumericProperty(1., min=0., max=1.) b = BoundedNumericProperty(1., min=0., max=1.) a = BoundedNumericProperty(0., min=0., max=1.) background_color = ReferenceListProperty(r, g, b, a)
class BackgroundColorBehavior(Widget): r = BoundedNumericProperty(1.0, min=0.0, max=1.0) """The value of ``red`` in the ``rgba`` palette. :attr:`r` is an :class:`~kivy.properties.BoundedNumericProperty` and defaults to `1.0`. """ g = BoundedNumericProperty(1.0, min=0.0, max=1.0) """The value of ``green`` in the ``rgba`` palette. :attr:`g` is an :class:`~kivy.properties.BoundedNumericProperty` and defaults to `1.0`. """ b = BoundedNumericProperty(1.0, min=0.0, max=1.0) """The value of ``blue`` in the ``rgba`` palette. :attr:`b` is an :class:`~kivy.properties.BoundedNumericProperty` and defaults to `1.0`. """ a = BoundedNumericProperty(0.0, min=0.0, max=1.0) """The value of ``alpha channel`` in the ``rgba`` palette. :attr:`a` is an :class:`~kivy.properties.BoundedNumericProperty` and defaults to `0.0`. """ md_bg_color = ReferenceListProperty(r, g, b, a) """The background color of the widget (:class:`~kivy.uix.widget.Widget`)
class PupilImage(Widget): tx = BoundedNumericProperty(0, min=-1, max=1,errorhandler=lambda x: 1 if x > 1 else -1) ty = BoundedNumericProperty(-1, min=-1, max=1,errorhandler=lambda x: 1 if x > 1 else -1) target_pos = ReferenceListProperty(tx,ty) def target_add(self,x_change,y_change): self.target_pos[0] += x_change self.target_pos[1] += y_change def target_set(self,x_target,y_target): self.target_pos[0] = x_target self.target_pos[1] = y_target def on_target_pos(self,instance,value): self.get_abs_pos(self.parent.ids['toplid'].size[1],self.parent.ids['bottomlid'].size[1]) def get_abs_pos(self,disttop,distbot): abs_x = self.parent.x + 0.5*(1+self.target_pos[0])*(self.parent.size[0]-self.size[0]) abs_y = self.parent.y + 0.5*(1+self.target_pos[1])*(self.parent.size[1]-self.size[1]) if(abs_y>self.parent.y+self.parent.size[1]+self.parent.ids['toplid'].size[1]-0.7*self.size[1]): abs_y=self.parent.y+self.parent.size[1]+self.parent.ids['toplid'].size[1]-0.7*self.size[1] elif (abs_y<self.parent.y+self.parent.ids['bottomlid'].size[1]-0.3*self.size[1]): abs_y=self.parent.y+self.parent.ids['bottomlid'].size[1]-0.3*self.size[1] #print(str(abs_x) + "," + str(abs_y)) anim = Animation(x=abs_x,y=abs_y, duration =.1) anim.start(self)
class BackgroundColorBehavior(Widget): r = BoundedNumericProperty(1., min=0., max=1.) g = BoundedNumericProperty(1., min=0., max=1.) b = BoundedNumericProperty(1., min=0., max=1.) a = BoundedNumericProperty(0., min=0., max=1.) md_bg_color = ReferenceListProperty(r, g, b, a)
class MphGauge(Widget): unit = NumericProperty(1.527777778) value = BoundedNumericProperty(0, min=0, max=180, errorvalue=0) path = dirname(abspath(__file__)) file_gauge = StringProperty(join(path, "MPHgauge.png")) file_needle = StringProperty(join(path, "needle.png")) size_gauge = BoundedNumericProperty(128, min=128, max=256, errorvalue=128) size_text = NumericProperty(10) def __init__(self, **kwargs): super(MphGauge, self).__init__(**kwargs) self._gauge = Scatter(size=(self.size_gauge, self.size_gauge), do_rotation=False, do_scale=False, do_translation=False) _img_gauge = Image(source=self.file_gauge, size=(self.size_gauge, self.size_gauge)) self._needle = Scatter(size=(self.size_gauge, self.size_gauge), do_rotation=False, do_scale=False, do_translation=False) _img_needle = Image(source=self.file_needle, size=(self.size_gauge, self.size_gauge)) self._glab = Label(font_size=self.size_text, markup=True) self._gauge.add_widget(_img_gauge) self._needle.add_widget(_img_needle) self.add_widget(self._gauge) self.add_widget(self._needle) self.add_widget(self._glab) self.bind(pos=self._update) self.bind(size=self._update) self.bind(value=self._turn) def _update(self, *args): self._gauge.pos = self.pos self._needle.pos = (self.x, self.y) self._needle.center = self._gauge.center self._glab.center_x = self._gauge.center_x self._glab.center_y = self._gauge.center_y + (self.size_gauge / 4) def _turn(self, *args): self._needle.center_x = self._gauge.center_x self._needle.center_y = self._gauge.center_y self._needle.rotation = (89.999999987 * self.unit) - (self.value * self.unit) self._glab.text = "[b]{0:.0f}[/b]".format(self.value)
class BBRunSoccerProp(EventDispatcher): team_one_score = BoundedNumericProperty(0, min=0, max=1000, errorvalue=0) team_two_score = BoundedNumericProperty(0, min=0, max=1000, errorvalue=0) def on_team_one_score(self, instance, value): pass def on_team_two_score(self, instance, value): pass
class RoundsStats(Label): won_states = BoundedNumericProperty(0, min=0) won_districts = BoundedNumericProperty(0, min=0) def __init__(self, **kwargs): super(RoundsStats, self).__init__(**kwargs) def late_init(self, store, won_states): self.property('won_districts').set(self, len(set(store.keys()))) self.property('won_states').set(self, len(set(won_states)))
class OppBenchBenchPokemonIndividualBoxLayout(DragBehavior, HoverBehavior, BoxLayout): name = StringProperty("") is_on_hover = BooleanProperty(False) origin_pos_x = BoundedNumericProperty(0) origin_pos_y = BoundedNumericProperty(0) def __init__(self, **args): super(OppBenchBenchPokemonIndividualBoxLayout, self).__init__() self.is_on_hover = False def on_enter(self): global opp_bench_bench_on_hover opp_bench_bench_on_hover = self.name print(opp_bench_bench_on_hover) self.is_on_hover = True with self.canvas.after: BorderImage(source="Transparent_shadow32.png", pos=(self.x - self.width * 0.2, self.y - self.height * 0.2), size=(self.width * 1.35, self.height * 1.35), index=1000) def on_leave(self): # ids_on_hover.remove(self.name) global opp_bench_bench_on_hover opp_bench_bench_on_hover = "" self.is_on_hover = False # print(self.name) self.canvas.after.clear() def on_touch_down(self, touch): super(OppBenchBenchPokemonIndividualBoxLayout, self).on_touch_down(touch) self.canvas.after.clear() self.origin_pos_x = self.x self.origin_pos_y = self.y if self.is_on_hover: ''' ChildrenList = [] for i in range(len(self.parent.children)): ChildrenList.append(self.parent.children[i].name) print(ChildrenList) ''' # print(root_board.ids[self.name].name) # idへのアクセスは、最上位のウィジェットから行う def on_touch_up(self, touch): super(OppBenchBenchPokemonIndividualBoxLayout, self).on_touch_up(touch) if self.origin_pos_x == 0 and self.origin_pos_y == 0: pass else: self.x = self.origin_pos_x self.y = self.origin_pos_y if self.is_on_hover: pass
class MDCard(ThemableBehavior, RectangularElevationBehavior, BoxLayout): r = BoundedNumericProperty(1.0, min=0.0, max=1.0) g = BoundedNumericProperty(1.0, min=0.0, max=1.0) b = BoundedNumericProperty(1.0, min=0.0, max=1.0) a = BoundedNumericProperty(0.0, min=0.0, max=1.0) border_radius = NumericProperty("3dp") border_color_a = BoundedNumericProperty(0, min=0.0, max=1.0) md_bg_color = ReferenceListProperty(r, g, b, a) background = StringProperty() """Background image path."""
class Car(Widget): angle = BoundedNumericProperty(0) rotation = BoundedNumericProperty(0) velocity_x = NumericProperty(0) velocity_y = NumericProperty(0) velocity = ReferenceListProperty(velocity_x, velocity_y) def move(self, rotation): self.pos = Vector(*self.velocity) + self.pos self.rotation = rotation self.angle = self.angle + self.rotation
def test_bounded_numeric_property(self): from kivy.properties import BoundedNumericProperty bnp = BoundedNumericProperty(0.0, min=0.0, max=3.5) bnp.link(wid, 'bnp') bnp.set(wid, 1) bnp.set(wid, 0.0) bnp.set(wid, 3.1) bnp.set(wid, 3.5) self.assertRaises(ValueError, partial(bnp.set, wid, 3.6)) self.assertRaises(ValueError, partial(bnp.set, wid, -3))
class TestCar(Widget): angle = BoundedNumericProperty(0.) rotation = BoundedNumericProperty(0.) velocity_x = BoundedNumericProperty(0.) velocity_y = BoundedNumericProperty(0.) deceleration_x = BoundedNumericProperty(0.) deceleration_y = BoundedNumericProperty(0.) acceleration_x = BoundedNumericProperty(0.) acceleration_y = BoundedNumericProperty(0.) velocity = ReferenceListProperty(velocity_x, velocity_y) deceleration = ReferenceListProperty(deceleration_x, deceleration_y) acceleration = ReferenceListProperty(acceleration_x, acceleration_y) def rotate(self, rotation): # print ("Entered rotate method") self.velocity = Vector(*self.velocity).rotate(self.angle) self.pos = Vector(*self.velocity) + self.pos self.rotation = rotation self.angle = self.angle + self.rotation def accelerate(self, acceleration_x): # print ("Entered method: ", inspect.stack()[0][3]) acceleration_x = float(acceleration_x) self.velocity = Vector(*self.velocity) + Vector(acceleration_x, 0) if self.velocity_x > 2: # Speed Governer self.velocity_x = 2 elif (self.velocity_x < -1): self.velocity_x = -1 if (self.velocity_y > 1): # To avoid car drifting moving upwards self.velocity_y = 1 elif (self.velocity_y < -0.5): # To avoid car drifting downwards self.velocity_y = -0.5 self.pos = Vector(*self.velocity) + self.pos # change property type
class Car(Widget): angle = BoundedNumericProperty(0.0) rotation = BoundedNumericProperty(0.0) speed_x = BoundedNumericProperty(0) speed_y = BoundedNumericProperty(0) velocity = ReferenceListProperty(speed_x, speed_y) def roll(self, rotation): self.x = int(self.speed_x + self.x) self.y = int(self.speed_y + self.y) self.pos = Vector(self.x, self.y) self.rotation = rotation self.angle = self.angle + self.rotation
class PositionGUI(EventDispatcher, PositionBase): """ Position manager for fish, hooks, boat, etc. Enables a wrapped X axis and a bounded Y axis. """ pos_x = BoundedNumericProperty(0, min=0, max=1) pos_y = BoundedNumericProperty(0, min=0, max=1) def __init__(self, parent, space_subdivisions): super().__init__() self.parent = parent self.space_subdivisions = space_subdivisions self.unit = 0.5 / self.space_subdivisions self.bind(pos_x=parent.on_state) self.bind(pos_y=parent.on_state)
class ColorClippingWidget(EffectWidget): # the user properties are in the range 0-255 black = BoundedNumericProperty(0, min=0, max=255, errorvalue=0) white = BoundedNumericProperty(255, min=0, max=255, errorvalue=255) def __init__(self, *args, **kwargs): super(ColorClippingWidget, self).__init__(*args, **kwargs) self.clip_effect = ColorClippingEffect() self.effects = [self.clip_effect] def on_black(self, *args): self.clip_effect.uniforms['black'] = self.black / 255.0 def on_white(self, *args): self.clip_effect.uniforms['white'] = self.white / 255.0
class HexCanvas(FloatLayout): last_node = ObjectProperty(None, allownone=True) grid = ObjectProperty([]) row_count = BoundedNumericProperty(11, min=0, max=11) column_count = BoundedNumericProperty(22, min=0, max=22) vvhelix_id = NumericProperty(0) scaffold_path = ListProperty([]) """docstring for NanoCanvas""" def __init__(self, **kwargs): #super(HexCanvas, self).__init__(**kwargs) super().__init__(**kwargs) self.__construct() def __construct(self): x_start, y_start = 30, 30 a = 60 x_offset = a / 2 y_offset = a * sqrt(3) / 2 y = y_start for j in range(self.row_count): row = [] if j % 2 != 0: offset = x_offset else: offset = 0 x = x_start + offset for i in range(self.column_count): node = Node(pos=(x, y), grid_id=(j, i)) row.append(node) self.add_widget(node) x += a y += y_offset self.grid.append(row) def clean(self): # TODO remove vhelixes and other stuff !!! self.last_node = None # for row in self.grid: # for node in row: # del node self.grid = [] self.vvhelix_id = 0 self.scaffold_path = [] self.__construct()
class wip007(App): # class vars: title = "NNV - wip007" grid = gridWidget() gridSize = BoundedNumericProperty( grid._gridSize + 1, min=2, max=20, errorvalue=2) # class Methods: def updateGrid(self, operation): if operation and self.gridSize <= 20: self.gridSize += 1 elif self.gridSize >= 0: self.gridSize -= 1 self.grid.draw(_gridSize=self.gridSize - 1) # The Big enchilada : def build(self): root = BoxLayout() sideBar = BoxLayout( padding=4, orientation='vertical', size_hint=(None, 0.60), width=200, spacing=2, pos_hint={'top': 1}) UI_1 = Builder.load_file( os.path.join( os.path.dirname(os.path.abspath(__file__)), 'UI_1.kv')) sideBar.add_widget(UI_1) sideBar.add_widget(Widget()) root.add_widget(self.grid) root.add_widget(sideBar) return root
class Ball(Widget): velocity_error_handler = lambda x: 10 if x > 10 else -10 velocity_x = NumericProperty(0) velocity_y = BoundedNumericProperty(0, min=-10, max=10, errorhandler=velocity_error_handler) #Revise this bit some more, not fully understood velocity = ReferenceListProperty(velocity_x, velocity_y) #Function for bounce behaviour def bounce(self, target): speedup = 1.00 #on top of target angle if target.x <= self.last[0] <= target.width: self.velocity_x *= -1 #from side else: self.velocity_y *= -1 self.velocity = Vector(*self.velocity) * speedup def move(self): self.last = self.center self.pos = Vector(*self.velocity) + self.pos self.next = Vector(*self.velocity) + self.pos #Note the difference from __init__(), this is for restarting game def init(self, screen): #start_pos should be set once in __init__, but I don't know how to call it in .kv self.start_pos = (screen.center_x, 200) self.center = self.start_pos self.velocity_y = -3 y = abs(self.velocity_y) self.velocity_x = randint(-y, y)
class BaseRectangularButton(RectangularRippleBehavior, BaseButton): """ Abstract base class for all rectangular buttons, bringing in the appropriate on-touch behavior. Also maintains the correct minimum width as stated in guidelines. """ width = BoundedNumericProperty( 88, min=88, max=None, errorhandler=lambda x: 88 ) text = StringProperty("") """Button text. :attr:`text` is an :class:`~kivy.properties.StringProperty` and defaults to `''`. """ button_label = BooleanProperty(True) """ If ``False`` the text on the button will not be displayed. :attr:`button_label` is an :class:`~kivy.properties.BooleanProperty` and defaults to `True`. """ _radius = NumericProperty("2dp") _height = NumericProperty(0)
class Laptime(SingleChannelGauge): Builder.load_string(""" <Laptime>: anchor_x: 'center' anchor_y: 'center' value_size: self.height AutoShrinkFieldLabel: text: root.NULL_LAP_TIME id: value font_size: root.font_size """) NULL_LAP_TIME = '--:--.--' value = BoundedNumericProperty(0, min=MIN_LAP_TIME, max=MAX_LAP_TIME, errorhandler=lambda x: MAX_LAP_TIME if x > MAX_LAP_TIME else MIN_LAP_TIME) font_size = NumericProperty() def __init__(self, **kwargs): super(Laptime, self).__init__(**kwargs) def on_value(self, instance, value): view = self.valueView if view: view.text = format_laptime(value) self.update_colors() def on_normal_color(self, instance, value): self.valueView.color = value
class Brake_Bias(FloatLayout): """A widget """ percentage = BoundedNumericProperty(50, min=0, max=100, errorvalue=50) def __init__(self, **kwargs): super(Brake_Bias, self).__init__(**kwargs)
class Laptime(SingleChannelGauge): NULL_LAP_TIME = '--:--.---' value = BoundedNumericProperty(0, min=MIN_LAP_TIME, max=MAX_LAP_TIME, errorhandler=lambda x: MAX_LAP_TIME if x > MAX_LAP_TIME else MIN_LAP_TIME) def __init__(self, **kwargs): super(Laptime, self).__init__(**kwargs) def on_value(self, instance, value): view = self.valueView if view: if value == None: view.text = self.NULL_LAP_TIME else: intMinuteValue = int(value) fractionMinuteValue = 60.0 * (value - float(intMinuteValue)) if value == MIN_LAP_TIME: view.text = self.NULL_LAP_TIME else: view.text = '{}:{}'.format( intMinuteValue, '{0:06.3f}'.format(fractionMinuteValue)) def on_normal_color(self, instance, value): self.valueView.color = value
class Card(Widget): index = BoundedNumericProperty(0, min=0, max=18) theme = StringProperty(None) texture = ObjectProperty(None) endpoints = ListProperty( []) # list of points used to draw the card borders in .kv def __init__(self, index, theme='guns', **kwargs): super().__init__(**kwargs) self.index = index # index of the image to be rendered, or 0 (card back) self.theme = theme self.texture = images[self.theme][ self.index] # load card image from memory, render as texture self.endpoints = [ self.pos[0] - card_padding, self.pos[1] - card_padding, # the start point self.pos[0] - card_padding, self.pos[1] + card_padding + self.size[1], self.pos[0] + card_padding + self.size[0], self.pos[1] + card_padding + self.size[1], self.pos[0] + card_padding + self.size[0], self.pos[1] - card_padding, self.pos[0] - card_padding, self.pos[1] - card_padding # return to the start point ]
class MDFlatButton(ThemableBehavior, RectangularRippleBehavior, ButtonBehavior, BackgroundColorBehavior, AnchorLayout): width = BoundedNumericProperty(dp(64), min=dp(64), max=None, errorhandler=lambda x: dp(64)) text_color = ListProperty() text = StringProperty('') theme_text_color = OptionProperty( None, allownone=True, options=['Primary', 'Secondary', 'Hint', 'Error', 'Custom']) text_color = ListProperty(None, allownone=True) _text = StringProperty('') _bg_color_down = ListProperty([0, 0, 0, 0]) def __init__(self, **kwargs): super(MDFlatButton, self).__init__(**kwargs) self._bg_color_down = get_color_from_hex( colors[self.theme_cls.theme_style]['FlatButtonDown']) Clock.schedule_once(lambda x: self.ids._label.bind( texture_size=self.update_width_on_label_texture)) def update_width_on_label_texture(self, instance, value): self.ids._label.width = value[0] def on_text(self, instance, value): self._text = value.upper()
class MDTabs(ThemableBehavior, AnchorLayout): """The MDTabs class. You can use it to create your own custom tabbed panel. """ default_tab = NumericProperty(0) """Index of the default tab. Default to 0.""" tab_bar_height = NumericProperty("48dp") """Height of the tab bar.""" tab_indicator_anim = BooleanProperty(False) """Tab indicator animation. Default to True. If you do not want animation set it to False. """ tab_indicator_height = NumericProperty("2dp") """Height of the tab indicator.""" anim_duration = NumericProperty(0.2) """Duration of the slide animation. Default to 0.2.""" anim_threshold = BoundedNumericProperty(0.8, min=0.0, max=1.0, errorhandler=lambda x: 0.0 if x < 0.0 else 1.0) """Animation threshold allow you to change the tab indicator animation effect. Default to 0.8. """ def on_carousel_index(self, carousel, index): # when the index of the carousel change, update # tab indicator, select the current tab and reset threshold data. current_tab_label = carousel.current_slide.tab_label if current_tab_label.state == "normal": current_tab_label._do_press() self.tab_bar.update_indicator(current_tab_label.x, current_tab_label.width) def add_widget(self, widget): # You can add only subclass of MDTabsBase. if len(self.children) >= 2: if not issubclass(widget.__class__, MDTabsBase): raise MDTabsException( "MDTabs accept only subclass of MDTabsBase") widget.tab_label.tab_bar = self.tab_bar self.tab_bar.layout.add_widget(widget.tab_label) self.carousel.add_widget(widget) return return super().add_widget(widget) def remove_widget(self, widget): # You can remove only subclass of MDTabsBase. if not issubclass(widget.__class__, MDTabsBase): raise MDTabsException( "MDTabs can remove only subclass of MDTabBase") if widget.parent.parent == self.carousel: self.tab_bar.layout.remove_widget(widget.tab_label) self.carousel.remove_widget(widget)
class MirrorCannon(Entity): id = 'mirror_cannon' state = BoundedNumericProperty(4, min=0, max=5, errorhandler=lambda x: 0 if x < 0 else 5) def turn(self, direction: int): self.state += direction # Class Property to return the current angle. @property def angle(self): return MIRROR_ANGLES[self.state] # Class property to return end point & mid-point vectors of the mirror axis @property def mirror_axis(self): p0 = MIRROR_CANNON_POS + MIRROR_OFFSET p1 = p0 + Vector( round(0.5 * MIRROR_DIAMETER * math.cos(math.radians(self.angle))), round(0.5 * MIRROR_DIAMETER * math.sin(math.radians(self.angle)))) p2 = -(p1 - p0) + p0 p3 = (p2 - p0).rotate(90 - self.angle) p4 = -p3 return p0, p1, p2, p3, p4
class Control(Widget): # Properties Definitions control_id = StringProperty(None) value = BoundedNumericProperty(0, min=0, max=1) # Syncronization Events in_construction = Event() in_construction.set() # Control Constructor def __init__(self, **kwargs): # send initialization event Control.in_construction.clear() # Widget constructor super(Control, self).__init__(**kwargs) # run init in a new thread, with some delay to get widget resources Clock.schedule_once(self.launch_deferred__init__, 0) def launch_deferred__init__(self, *largs): Thread(target=self.deferred__init__).start() # Creation Conditions def deferred__init__(self, *largs): # instance variables self.values = {} # Send termination event Control.in_construction.set() # Event Listener Methods Definition def on_value(self, instance, value): self.parent.send(self.control_id, self.value)
class MDTabHeader(MDFlatButton): """ Internal widget for headers based on MDFlatButton""" width = BoundedNumericProperty(dp(0), min=dp(72), max=dp(264), errorhandler=lambda x: dp(72)) tab = ObjectProperty(None) panel = ObjectProperty(None)
def test_bounded_numeric_property_error_value(self): from kivy.properties import BoundedNumericProperty bnp = BoundedNumericProperty(0, min=-5, max=5, errorvalue=1) bnp.link(wid, 'bnp') bnp.set(wid, 1) self.assertEqual(bnp.get(wid), 1) bnp.set(wid, 5) self.assertEqual(bnp.get(wid), 5) bnp.set(wid, 6) self.assertEqual(bnp.get(wid), 1) bnp.set(wid, -5) self.assertEqual(bnp.get(wid), -5) bnp.set(wid, -6) self.assertEqual(bnp.get(wid), 1)
def test_bounded_numeric_property_error_handler(self): from kivy.properties import BoundedNumericProperty bnp = BoundedNumericProperty( 0, min=-5, max=5, errorhandler=lambda x: 5 if x > 5 else -5) bnp.link(wid, 'bnp') bnp.set(wid, 1) self.assertEqual(bnp.get(wid), 1) bnp.set(wid, 5) self.assertEqual(bnp.get(wid), 5) bnp.set(wid, 10) self.assertEqual(bnp.get(wid), 5) bnp.set(wid, -5) self.assertEqual(bnp.get(wid), -5) bnp.set(wid, -10) self.assertEqual(bnp.get(wid), -5)