def __init__(self, image_composition, service, previous_service, scroll_delay, synchroniser, device, position, controller): self.speed = Args.Speed self.position = position self.Controller = controller self.image_composition = image_composition self.rectangle = ComposableImage(RectangleCover(device).image, position=(0, 16 * position + 16)) self.CurrentService = service self.generateCard(service) self.IStaticOld = ComposableImage(StaticTextImage( device, service, previous_service).image, position=(0, (16 * position))) self.image_composition.add_image(self.IStaticOld) self.image_composition.add_image(self.rectangle) self.max_pos = self.IDestination.width self.image_y_posA = 0 self.image_x_pos = 0 self.device = device self.partner = None self.delay = scroll_delay self.ticks = 0 self.state = self.OPENING_SCROLL if service.ID != 0 else self.STUD self.synchroniser = synchroniser self.render() self.synchroniser.ready(self)
def generateCard(self,service): displayTimeTemp = TextImage(device, service.DisplayTime) IDestinationTemp = TextImageComplex(device, service.Destination,service.Via, displayTimeTemp.width) self.IDestination = ComposableImage(IDestinationTemp.image.crop((0,0,IDestinationTemp.width + 10,16)), position=(45 if Args.ShowIndex or Args.LargeLineName else 30, 16 * self.position)) self.IServiceNumber = ComposableImage(TextImageServiceNumber(device, service.ServiceNumber).image.crop((0,0,45 if Args.ShowIndex or Args.LargeLineName else 30,16)), position=(0, 16 * self.position)) self.IDisplayTime = ComposableImage(displayTimeTemp.image, position=(device.width - displayTimeTemp.width, 16 * self.position))
def displayflights(topline, bottomline): device.contrast(0) if device.height >= 16: font = make_font("code2000.ttf", 12) else: font = make_font("pixelmix.ttf", 8) image_composition = ImageComposition(device) try: # while True: synchroniser = Synchroniser() ci_top = ComposableImage(TextImage(device, topline, font).image, position=(0, 1)) ci_bottom = ComposableImage(TextImage(device, bottomline, font).image, position=(0, 16)) closest = Scroller(image_composition, ci_top, 10, synchroniser) furthest = Scroller(image_composition, ci_bottom, 10, synchroniser) cycles = 0 while cycles < 3: closest.tick() furthest.tick() time.sleep(0.025) cycles = furthest.get_cycles() with canvas(device, background=image_composition()) as draw: image_composition.refresh() # draw.rectangle(device.bounding_box, outline="white") # del closest # del furthest except KeyboardInterrupt: pass
def renderWidget(self): with canvas(self.device) as draw: if self.widget_config['icon']: self.icon_w, self.icon_h = draw.textsize( self.icon, self.icon_font) else: self.icon_w, self.icon_h = (0, 0) self.text_w, self.text_h = draw.textsize(self.text, self.text_font) self.icon_padding = 2 self.line_padding = 2 self.icon_w += (self.icon_padding + self.line_padding) self.icon_x = 0 self.icon_y = 0 if self.widget_config['icon']: self.text_x = self.icon_w else: self.text_x = 0 self.text_y = 0 self.widget_w = self.icon_w + self.text_w self.widget_h = max(self.icon_h, self.text_h) self.icon_image = Image.new(self.device.mode, (self.icon_w, self.icon_h)) draw = ImageDraw.Draw(self.icon_image) if self.widget_config['icon']: draw.text((self.line_padding, 0), text=self.icon, font=self.icon_font, fill="white") draw.line(((0, 0), (0, self.icon_h)), fill="white", width=1) self.ci_icon = ComposableImage(self.icon_image) del draw self.text_image = Image.new(self.device.mode, (self.text_w, self.text_h)) draw = ImageDraw.Draw(self.text_image) draw.text((0, 0), text=self.text, font=self.text_font, fill="white") self.ci_text = ComposableImage(self.text_image) del draw print( f"[renderWidget][{self.widget}] icon x: {self.icon_x}, y: {self.icon_y}, w: {self.icon_w}, h: {self.icon_h}" ) print( f"[renderWidget][{self.widget}] text x: {self.text_x}, y: {self.text_y}, w: {self.text_w}, h: {self.text_h}" ) print( f"[renderWidget][{self.widget}] total width: {self.widget_w}, height: {self.widget_h}" )
def generateCard(self, service): displayTimeTemp = TextImage(device, service.DisplayTime) IDestinationTemp = TextImageComplex(device, service.Destination, service.Via, displayTimeTemp.width) self.IDestination = ComposableImage(IDestinationTemp.image.crop( (0, 0, IDestinationTemp.width + 10, 16)), position=(0, 16 * self.position)) self.IDisplayTime = ComposableImage( displayTimeTemp.image, position=(device.width - displayTimeTemp.width, 16 * self.position))
def test_image_count(): ic = ImageComposition(dummy()) img1 = ComposableImage(Image.new("RGB", (1, 1))) img2 = ComposableImage(Image.new("RGB", (1, 1))) img3 = ComposableImage(Image.new("RGB", (1, 1))) ic.add_image(img1) ic.add_image(img2) ic.add_image(img3) assert len(ic.composed_images) == 3 ic.remove_image(img3) assert len(ic.composed_images) == 2 ic.remove_image(img2) assert len(ic.composed_images) == 1 ic.remove_image(img1) assert len(ic.composed_images) == 0
def test_composable_image_crop_same(): img_size = (128, 64) crop_size = img_size img = Image.new("RGB", img_size) ci = ComposableImage(img) cropped_img = ci.image(crop_size) assert cropped_img.size == crop_size
def changeCard(self, newService, device): if newService.ID == "0" and self.CurrentService.ID == "0": self.state = self.STUD self.synchroniser.ready(self) return self.synchroniser.busy(self) self.IStaticOld = ComposableImage(StaticTextImage( device, newService, self.CurrentService).image, position=(0, (16 * self.position))) self.image_composition.add_image(self.IStaticOld) self.image_composition.add_image(self.rectangle) if self.CurrentService.ID != "0": self.image_composition.remove_image(self.IDestination) self.image_composition.remove_image(self.IServiceNumber) self.image_composition.remove_image(self.IDisplayTime) del self.IDestination del self.IServiceNumber del self.IDisplayTime if self.partner != None and self.partner.CurrentService.ID != "0": self.partner.refresh() self.image_composition.refresh() self.generateCard(newService) self.CurrentService = newService self.max_pos = self.IDestination.width self.state = self.WAIT_STUD if (newService.ID == "0") else self.WAIT_OPENING
def set_info(self, song, artist): if (song != self.current_song) or (artist != self.current_artist): self.ci_song = ComposableImage(TextImage(self.device, song, self.font).image, position=(0, 1)) self.ci_artist = ComposableImage(TextImage(self.device, artist, self.font).image, position=(0, 20)) self.song_scroller = Scroller(self.image_composition, self.ci_song, 100, self.synchroniser) self.artist_scroller = Scroller(self.image_composition, self.ci_artist, 100, self.synchroniser) self.current_song = song self.current_artist = artist self.has_info = True
def test_composable_image_crop_size_greater_than_image_size(): img_size = (128, 64) crop_size = (1000, 1000) img = Image.new("RGB", img_size) ci = ComposableImage(img) cropped_img = ci.image(crop_size) assert cropped_img.size == img_size
def test_composable_image_crop_offset(): img_size = (128, 64) crop_size = (10, 10) img = Image.new("RGB", img_size) ci = ComposableImage(img, offset=(20, 20)) cropped_img = ci.image(crop_size) assert cropped_img.size == crop_size
def __init__(self, device, font): super(MusicScreen, self).__init__(device, font) self.ci_play = ComposableImage(graphutils.make_bitmap("play.png"), position=(60, 48)) self.ci_pause = ComposableImage(graphutils.make_bitmap("pause.png"), position=(60, 48)) self.image_composition = graphutils.ImageCompositionWithHideableImage( self.device) self.image_composition.add_image(self.ci_play) self.image_composition.add_image(self.ci_pause) self.synchroniser = Synchroniser() self.has_info = False self.is_paused = False self.song_scroller = None self.artist_scroller = None self.current_song = None self.current_artist = None
def generateCard(self,service): displayTimeTemp = TextImage(device, service.DisplayTime) displayInfoTemp = TextImage(device, service.DisplayText) sizeRemaining = device.width - (displayTimeTemp.width + displayInfoTemp.width) displayDestinationTemp = VariableTextImage(device, service.Destination, sizeRemaining) self.IDisplayText = ComposableImage(displayInfoTemp.image, position=(0, Offset + (FontSize * self.position))) self.IDestintion = ComposableImage(displayDestinationTemp.image, position=(displayInfoTemp.width, Offset + (FontSize * self.position))) self.IDisplayTime = ComposableImage(displayTimeTemp.image, position=(device.width - displayTimeTemp.width, Offset + (FontSize * self.position))) TempSCallingAt = TextImage(device, "Calling at:") TempICallingAt = LongTextImage(device, service.CallingAt) self.DirectService = ',' not in service.CallingAt self.ICallingAt = ComposableImage(TempICallingAt.image.crop((0,0,max(TempICallingAt.width + 3,256) ,FontSize)), position=(TempSCallingAt.width + 3, Offset + (FontSize * self.position))) self.SCallingAt = ComposableImage(TempSCallingAt.image.crop((0,0,TempSCallingAt.width,FontSize)), position=(0, Offset + (FontSize * self.position))) self.max_pos = TempICallingAt.width + 3
def test_composable_image_image(): ci = ComposableImage(Image.new("RGB", (1, 1))) with pytest.raises(AssertionError): ci.image((0, 0)) with pytest.raises(AssertionError): ci.image((1, 0)) with pytest.raises(AssertionError): ci.image((0, 1))
def updateCard(self, newService, device): self.state = self.SCROLL_DECIDER self.synchroniser.ready(self) self.image_composition.remove_image(self.IDisplayTime) displayTimeTemp = TextImage(device, newService.DisplayTime) self.IDisplayTime = ComposableImage(displayTimeTemp.image, position=(device.width - displayTimeTemp.width, 16 * self.position)) self.image_composition.add_image(self.IDisplayTime) self.image_composition.refresh()
def updateCard(self, newService, device): self.state = self.SCROLL_DECIDER self.synchroniser.ready(self) self.image_composition.remove_image(self.IDisplayTime) self.image_composition.remove_image(self.IDestintion) displayTimeTemp = TextImage(device, newService.DisplayTime) self.IDisplayTime = ComposableImage(displayTimeTemp.image, position=(device.width - displayTimeTemp.width, Offset + (FontSize * self.position))) tempDisplayText = TextImage(device, newService.DisplayText) sizeRemaining = device.width - (displayTimeTemp.width + tempDisplayText.width) displayDestinationTemp = VariableTextImage(device, newService.Destination, sizeRemaining) self.IDestintion = ComposableImage(displayDestinationTemp.image, position=(tempDisplayText.width, Offset + (FontSize * self.position))) self.image_composition.add_image(self.IDestintion) self.image_composition.add_image(self.IDisplayTime) self.image_composition.refresh()
def test_refresh(): ic = ImageComposition(dummy()) ic_img_before = list(ic().getdata()) img = Image.new("RGB", (25, 25)) draw = ImageDraw.Draw(img) draw.rectangle((10, 10, 20, 20), outline="white") del draw ci = ComposableImage(img) ic.add_image(ci) ic.refresh() assert ic_img_before != list(ic().getdata())
def test_composable_image_ctor(): pos = (78, 12) offs = (90, 12) img_size = (123, 234) img = Image.new("RGB", img_size) ci = ComposableImage(img) ci.position = pos ci.offset = offs assert ci.position == pos assert ci.offset == offs assert ci.width == img_size[0] assert ci.height == img_size[1] assert isinstance(ci.image((1, 1)), PIL.Image.Image)
def updateCard(self, newService, device): self.state = self.SCROLL_DECIDER self.synchroniser.ready(self) #Need to regenerate both because the width of the time displayed can shrink. self.image_composition.remove_image(self.IDestination) self.image_composition.remove_image(self.IDisplayTime) self.image_composition.refresh() displayTimeTemp = TextImage(device, newService.DisplayTime) self.IDisplayTime = ComposableImage( displayTimeTemp.image, position=(device.width - displayTimeTemp.width, 16 * self.position)) IDestinationTemp = TextImageComplex(device, newService.Destination, newService.Via, displayTimeTemp.width) self.IDestination = ComposableImage(IDestinationTemp.image.crop( (0, 0, IDestinationTemp.width + 10, 16)), position=(0, 16 * self.position)) self.image_composition.add_image(self.IDestination) self.image_composition.add_image(self.IDisplayTime) self.image_composition.refresh()
def __init__(self, image_composition, scroll_delay, device): self.Services = LiveTime.GetData() self.synchroniser = Synchroniser() self.scroll_delay = scroll_delay self.image_composition = image_composition self.device = device self.ticks = 0 self.setInitalCards() self.State = "alive" NoServiceTemp = NoService(device) self.NoServices = ComposableImage(NoServiceTemp.image, position=(int(device.width/2- NoServiceTemp.width/2),int(device.height/2-NoServiceTemp.height/2))) self.top.addPartner(self.middel) self.middel.addPartner(self.bottom)
def __init__( self, textimage: TextImage, position: tuple = (0, 0), offset: tuple = (0, 0), scrolling=False, direction="h", delay=0, initialdelay=None, ): self.initialdelay = initialdelay if initialdelay else delay self.delay = delay self.direction = direction self.scrolling = scrolling self.offset = offset self.position = position self.textimage = textimage self.last_delay_tick = 0.0 self.composableimage = ComposableImage(textimage.image, position, offset)
def tick(self): #Update X min till arrival. if self.CurrentService.TimePassedStatic() and ( self.state == self.SCROLL_DECIDER or self.state == self.SCROLLING_WAIT or self.state == self.SCROLLING or self.state == self.WAIT_SYNC): self.image_composition.remove_image(self.IDisplayTime) self.CurrentService.DisplayTime = self.CurrentService.GetDisplayTime( ) displayTimeTemp = TextImage(device, self.CurrentService.DisplayTime) self.IDisplayTime = ComposableImage( displayTimeTemp.image, position=(device.width - displayTimeTemp.width, 16 * self.position)) self.image_composition.add_image(self.IDisplayTime) self.image_composition.refresh() if self.state == self.WAIT_OPENING: if not self.is_waiting(): self.state = self.OPENING_SCROLL elif self.state == self.OPENING_SCROLL: if self.image_y_posA < 16: self.render() self.image_y_posA += self.speed else: self.state = self.OPENING_END elif self.state == self.OPENING_END: self.image_x_pos = 0 self.image_y_posA = 0 self.image_composition.remove_image(self.IStaticOld) self.image_composition.remove_image(self.rectangle) del self.IStaticOld self.image_composition.add_image(self.IDestination) self.image_composition.add_image(self.IServiceNumber) self.image_composition.add_image(self.IDisplayTime) self.render() self.synchroniser.ready(self) self.state = self.SCROLL_DECIDER elif self.state == self.SCROLL_DECIDER: if self.synchroniser.is_synchronised(): if not self.is_waiting(): if self.synchroniser.is_synchronised(): self.synchroniser.busy(self) # If not a valid via message or not wanting animations. if self.CurrentService.Via == "" or Args.ReducedAnimations: self.state = self.WAIT_SYNC elif self.CurrentService.ID == "0": self.synchroniser.ready(self) self.state = self.STUD else: self.state = self.SCROLLING_WAIT elif self.state == self.SCROLLING_WAIT: if not self.is_waiting(): self.state = self.SCROLLING elif self.state == self.SCROLLING: if self.image_x_pos < self.max_pos: self.render() self.image_x_pos += self.speed else: self.state = self.WAIT_SYNC elif self.state == self.WAIT_SYNC: if self.image_x_pos != 0: self.image_x_pos = 0 self.render() else: if not self.is_waiting(): self.Controller.requestCardChange(self, self.position + 1) elif self.state == self.WAIT_STUD: if not self.is_waiting(): self.state = self.STUD_SCROLL elif self.state == self.STUD_SCROLL: if self.image_y_posA < 16: self.render() self.image_y_posA += self.speed else: self.state = self.STUD_END elif self.state == self.STUD_END: self.image_x_pos = 0 self.image_y_posA = 0 self.image_composition.remove_image(self.IStaticOld) self.image_composition.remove_image(self.rectangle) del self.IStaticOld self.render() self.synchroniser.ready(self) self.state = self.STUD elif self.state == self.STUD: if not self.is_waiting(): self.Controller.requestCardChange(self, self.position + 1)
# ------- main device = get_device() if device.height >= 16: font = make_font("code2000.ttf", 12) else: font = make_font("pixelmix.ttf", 8) image_composition = ImageComposition(device) try: while True: for title in titles: synchroniser = Synchroniser() ci_song = ComposableImage(TextImage(device, title[0], font).image, position=(0, 1)) ci_artist = ComposableImage(TextImage(device, title[1], font).image, position=(0, 30)) song = Scroller(image_composition, ci_song, 100, synchroniser) artist = Scroller(image_composition, ci_artist, 100, synchroniser) cycles = 0 while cycles < 3: artist.tick() song.tick() time.sleep(0.025) cycles = song.get_cycles() with canvas(device, background=image_composition()) as draw: image_composition.refresh()
def tick(self): #Update X min till arrival. if self.CurrentService.TimePassedStatic() and (self.state == self.SCROLL_DECIDER or self.state == self.SCROLLING_WAIT or self.state == self.SCROLLING or self.state == self.WAIT_SYNC): self.image_composition.remove_image(self.IDisplayTime) self.CurrentService.DisplayTime = self.CurrentService.GetExptTime() displayTimeTemp = TextImage(device, self.CurrentService.DisplayTime) self.IDisplayTime = ComposableImage(displayTimeTemp.image, position=(device.width - displayTimeTemp.width, Offset + (FontSize * self.position))) self.image_composition.add_image(self.IDisplayTime) self.image_composition.refresh() if self.state == self.WAIT_OPENING: if not self.is_waiting(): self.state = self.OPENING_SCROLL elif self.state == self.OPENING_SCROLL: if self.image_y_posA < FontSize: self.render() self.image_y_posA += self.speed else: self.state = self.OPENING_END elif self.state == self.OPENING_END: self.image_x_pos = 0 self.image_y_posA = 0 self.image_composition.remove_image(self.IStaticOld) self.image_composition.remove_image(self.rectangle) del self.IStaticOld self.image_composition.add_image(self.IDisplayText) self.image_composition.add_image(self.IDestintion) self.image_composition.add_image(self.IDisplayTime) self.render() self.synchroniser.ready(self) self.state = self.SCROLL_DECIDER elif self.state == self.SCROLL_DECIDER: if self.synchroniser.is_synchronised(): if not self.is_waiting(): if self.synchroniser.is_synchronised(): self.synchroniser.busy(self) if Args.ReducedAnimations or (self.DirectService and not Args.ShowDirect): self.state = self.WAIT_SYNC elif self.CurrentService.ID == "0": self.synchroniser.ready(self) self.state = self.STUD else: self.state = self.SCROLLING_WAIT elif self.state == self.SCROLLING_WAIT: if not self.is_waiting(): self.image_composition.remove_image(self.IDisplayText) self.image_composition.remove_image(self.IDestintion) self.image_composition.remove_image(self.IDisplayTime) self.image_composition.add_image(self.ICallingAt) self.image_composition.add_image(self.SCallingAt) self.state = self.SCROLLING_PAUSE elif self.state == self.SCROLLING_PAUSE: if not self.is_waiting(): self.state = self.SCROLLING elif self.state == self.SCROLLING: if self.image_x_pos < self.max_pos: self.render() self.image_x_pos += self.speed else: self.image_composition.remove_image(self.SCallingAt) self.image_composition.remove_image(self.ICallingAt) self.image_composition.add_image(self.IDisplayText) self.image_composition.add_image(self.IDestintion) self.image_composition.add_image(self.IDisplayTime) self.state = self.WAIT_SYNC elif self.state == self.WAIT_SYNC: if self.image_x_pos != 0: self.image_x_pos = 0 self.render() else: if not self.is_waiting(): self.Controller.requestCardChange(self, self.position + 1) elif self.state == self.WAIT_STUD: if not self.is_waiting(): self.state = self.STUD_SCROLL elif self.state == self.STUD_SCROLL: if self.image_y_posA < FontSize: self.render() self.image_y_posA += self.speed else: self.state = self.STUD_END elif self.state == self.STUD_END: self.image_x_pos = 0 self.image_y_posA = 0 self.image_composition.remove_image(self.IStaticOld) self.image_composition.remove_image(self.rectangle) del self.IStaticOld self.render() self.synchroniser.ready(self) self.state = self.STUD elif self.state == self.STUD: if not self.is_waiting(): self.Controller.requestCardChange(self, self.position + 1)
def test_composable_image_none(): with pytest.raises(AssertionError): ComposableImage(None)