#!/usr/bin/env python # -*- coding: utf-8 -*- # # Copyright © 2024 Simon Forman # # This file is part of game # # game is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # game is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with game. If not see . # class Reticule: def __init__(self, canvas, radius_x=35, radius_y=20, color='green'): self.canvas = canvas self.radius_x = radius_x self.radius_y = radius_y self.color = color self.item_ids = [] self.init_reticule() def get_reticule_coords(self, x, y): ''' Given the width and height of a rectangle and x-y coords in that rectangle yield coords for four lines and an oval suitable for passing to canvas.coords() method. ''' width, height = int(self.canvas['width']), int(self.canvas['height']) top = y - self.radius_y left = x - self.radius_x bottom = y + self.radius_y right = x + self.radius_x yield 0, y, left, y yield right, y, width - 1, y yield x, 0, x, top yield x, bottom, x, height - 1 yield left, top, right, bottom def init_reticule(self): append = self.item_ids.append w, h = int(self.canvas['width']), int(self.canvas['height']) coords = self.get_reticule_coords(w >> 1, h >> 1) # Center. append(canvas.create_line(*next(coords), fill=self.color)) append(canvas.create_line(*next(coords), fill=self.color)) append(canvas.create_line(*next(coords), fill=self.color)) append(canvas.create_line(*next(coords), fill=self.color)) append(canvas.create_oval(*next(coords), outline=self.color)) def set_reticule(self, x, y): coords = self.get_reticule_coords(x, y) for item_id, item_coords in zip(self.item_ids, coords): self.canvas.coords(item_id, *item_coords) def handle_set_event(self, event): self.set_reticule(event.x, event.y) if __name__ == '__main__': from tkinter import * def handle_canvas_resize(event): # I don't know why the Tk system doesn't update these values. canvas['width'] = event.width canvas['height'] = event.height # update reticule here/now? # If the canvas window has enlarged then some of the lines will have # to be extended. canvas = Canvas(bg='black') canvas.bind('', handle_canvas_resize) canvas.pack(expand=True, fill=BOTH) canvas.update() # Let the configure event propagate and trigger the # handle_canvas_resize() callback to set the width # and height values of the canvas correctly so that # the reticule lines get drawn correctly. reticule = Reticule(canvas) canvas.bind('', reticule.handle_set_event) canvas.bind('', reticule.handle_set_event) #canvas.mainloop()