def draw(self, renderer, rect): super().draw(renderer, rect) if self.axis in (Axis.HORIZONTAL, None): w = rect.width - (0 if self.axis == Axis.HORIZONTAL else self.track_size) track_rect = Rect(origin=(rect.left, rect.bottom - self.track_size), size=(w, self.track_size)) self.env.draw(renderer, "scroll.horizontal.track", track_rect) knob_rect = self.knob_rect(Axis.HORIZONTAL) if knob_rect.width: self.env.draw(renderer, "scroll.knob", knob_rect) if self.axis in (Axis.VERTICAL, None): h = rect.height - (0 if self.axis == Axis.VERTICAL else self.track_size) track_rect = Rect(origin=(rect.right - self.track_size, rect.top), size=(self.track_size, h)) self.env.draw(renderer, "scroll.vertical.track", track_rect) knob_rect = self.knob_rect(Axis.VERTICAL) if knob_rect.height: self.env.draw(renderer, "scroll.knob", knob_rect) if self.axis is None: corner_rect = Rect( origin=(rect.right - self.track_size, rect.bottom - self.track_size), size=(self.track_size, self.track_size), ) self.env.draw(renderer, "scroll.corner", corner_rect)
def draw(self, renderer, rect): offset = int((self.current.value - self.minimum) * (rect.width - self.env.scaled(20)) / (self.span - 1)) slider_rect = Rect(origin=(rect.left, rect.top + self.env.scaled(7)), size=(rect.width, self.env.scaled(6))) knob_rect = Rect(origin=(rect.left + offset, rect.top), size=(self.env.scaled(20), self.env.scaled(20))) self.env.draw(renderer, "slider.track", slider_rect) self.env.draw(renderer, "slider.knob", knob_rect)
def draw(self, renderer, rect): width = int((self.current.value - self.minimum) * rect.width / (self.maximum - self.minimum)) track_rect = Rect(origin=(rect.left, rect.top), size=(rect.width, self.env.scaled(6))) bar_rect = Rect(origin=(rect.left, rect.top), size=(width, self.env.scaled(6))) self.env.draw(renderer, "progress.track", track_rect) if width > 0: self.env.draw(renderer, "progress.bar", bar_rect)
def knob_rect(self, axis): size = self.knob_size() pos = self.knob_position() inner = self.frame - self.env.padding - self.env.border if axis == Axis.VERTICAL: return Rect( origin=(inner.right - self.env.scaled(13), inner.top + pos.y), size=(self.env.scaled(11), size.h) ) else: return Rect( origin=(inner.left + pos.x, inner.bottom - self.env.scaled(13)), size=(size.w, self.env.scaled(11)) )
def test_rect_insets(self): r1 = Rect(origin=(100, 100), size=(150, 50)) r2 = r1 + Insets(10) self.assertEqual(r2.origin, Point(90, 90)) self.assertEqual(r2.size, Size(170, 70)) r3 = r1 - Insets(10) self.assertEqual(r3.origin, Point(110, 110)) self.assertEqual(r3.size, Size(130, 30))
def __init__(self, *contents, **options): super().__init__() # Overall frame of the View, including padding and border. self.frame = Rect() # How this View is represented in navigation views such as TabView. self.item_view = None # Convenience for stashing stuff. Should probably clean this up. for name, value in options.items(): setattr(self, name, value) # The raw (un-built) View instances under this one. self.contents = contents # Resolved and built list of subviews, after evaluating e.g. ForEach constructs. # This will be empty until rebuild is called, which happens on first layout and state changes. self._subviews = []
def reposition(self, inside: Rect): self.position_inside(inside) current = (self.frame.origin[self.axis] + self.env.padding.leading(self.axis) + self.env.border.leading(self.axis)) # Align based on the content size without the padding and borders. inner = self.frame - self.env.padding - self.env.border for idx, view in enumerate(self.subviews): if idx > 0: current += self.env.spacing cross = inner.origin[self.cross] + int( self.env.alignment.value * (inner.size[self.cross] - view.frame.size[self.cross])) view.reposition( Rect(origin=self.axis.point(current, cross), size=view.frame.size)) current += view.frame.size[self.axis]
def reposition(self, inside: Rect): self.position_inside(inside) main = self.frame.origin[self.axis] + self.env.padding.leading( self.axis) + self.env.border.leading(self.axis) for views in chunked(self.subviews, self.count): max_main = 0 cross = (self.frame.origin[self.cross] + self.env.padding.leading(self.cross) + self.env.border.leading(self.cross)) for idx, view in enumerate(views): if idx > 0: cross += self.spacing[self.cross] view.reposition( Rect( origin=self.axis.point(main, cross), size=view.frame.size, )) cross += view.frame.size[self.cross] max_main = max(max_main, view.frame.size[self.axis]) main += max_main + self.spacing[self.axis]