From 8eab96431d710984279f52bfad62147583e05aa6 Mon Sep 17 00:00:00 2001 From: Simon Forman Date: Tue, 16 Apr 2024 11:57:39 -0700 Subject: [PATCH] A simple reticule for highlighting current star. --- reticule.py | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 reticule.py diff --git a/reticule.py b/reticule.py new file mode 100644 index 0000000..fa8c424 --- /dev/null +++ b/reticule.py @@ -0,0 +1,96 @@ +#!/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()