Code:
from tkinter import * # type: ignore
from tkinter.ttk import * # type: ignore
from cargobot import *
from typing import List

window_background_color = "#ECECEC"

COLUMN_WIDTH = 50
BOX_SIDE_LENGTH = 30
BOX_SPACING = 4
TOP_MARGIN = 10
CRANE_ARM_TOP_Y = TOP_MARGIN + 20
CRANE_ARM_BOTTOM_Y = CRANE_ARM_TOP_Y + 30


class CraneView(Canvas):
    def __init__(self, parent: Tk, crane: Crane) -> None:
        Canvas.__init__(self, parent, width=crane.num_columns * COLUMN_WIDTH, highlightthickness=0)
        self.crane = crane

    def draw_box(self, center_x: int, center_y: int, box: str) -> None:
        self.create_rectangle(
            center_x - BOX_SIDE_LENGTH // 2,
            center_y - BOX_SIDE_LENGTH // 2,
            center_x + BOX_SIDE_LENGTH // 2,
            center_y + BOX_SIDE_LENGTH // 2,
            outline="grey",
            width=1.5,
            fill="white",
        )
        self.create_text(center_x, center_y, text=box)

    def redraw(self) -> None:
        canvas_height = self.winfo_height()
        canvas_width = self.winfo_width()
        self.delete(ALL)

        self.create_rectangle(0, 0, canvas_width, canvas_height, fill=window_background_color, width=0)

        # dessin de la ligne supérieure
        num_columns = self.crane.num_columns
        width = num_columns * COLUMN_WIDTH
        self.create_line(0, TOP_MARGIN, width, TOP_MARGIN, width=2)

        # dessin de la grue à la bonne position
        position = self.crane.position
        crane_center_x = position * COLUMN_WIDTH + COLUMN_WIDTH // 2
        crane_left_arm_x = crane_center_x - BOX_SIDE_LENGTH // 2 - 4
        crane_right_arm_x = crane_center_x + BOX_SIDE_LENGTH // 2 + 4
        self.create_line(
            crane_center_x, TOP_MARGIN, crane_center_x, CRANE_ARM_TOP_Y, width=2
        )  # vertical
        self.create_line(
            crane_left_arm_x,
            CRANE_ARM_TOP_Y,
            crane_right_arm_x,
            CRANE_ARM_TOP_Y,
            width=2,
        )  # horizontal
        self.create_line(
            crane_left_arm_x,
            CRANE_ARM_TOP_Y,
            crane_left_arm_x,
            CRANE_ARM_BOTTOM_Y,
            width=2,
        )  # bras de gauche
        self.create_line(
            crane_right_arm_x,
            CRANE_ARM_TOP_Y,
            crane_right_arm_x,
            CRANE_ARM_BOTTOM_Y,
            width=2,
        )  # bras de droite

        # boîte dans la grue si nécessaire
        if self.crane.held_box is not None:
            self.draw_box(crane_center_x, 30 + 4 + BOX_SIDE_LENGTH // 2, self.crane.held_box)

        # boîte dans les colonnes
        bottom = canvas_height - 10
        self.create_line(0, bottom + 2, width, bottom + 2)
        for col_index, column in enumerate(self.crane.box_placements):
            for box_index, box in enumerate(column):
                box_center_x = col_index * COLUMN_WIDTH + COLUMN_WIDTH // 2
                box_center_y = (
                    bottom
                    - box_index * (BOX_SIDE_LENGTH + BOX_SPACING)
                    - BOX_SIDE_LENGTH // 2
                    - 2
                )
                self.draw_box(box_center_x, box_center_y, box)
Last modified: Thursday, 5 December 2019, 3:59 PM