twisted 0.1.3

A speedcubing and smart-cube library.
Documentation
// SPDX-FileCopyrightText: 2022 Declan Rixon <twisted.cubing@gmail.com>
//
// SPDX-License-Identifier: GPL-3.0-only

use crate::cube::Face;
use crate::gui::ColorScheme;
use crate::gui::Grid;
use crate::method::substep::Solved;
use sdl2::rect::Rect;
use sdl2::render::Canvas;
use sdl2::video::Window;

pub struct Net {
    pub grid: Grid,
    pub color_scheme: ColorScheme,
    pub corners: Vec<Corner>,
    pub edges: Vec<Edge>,
    pub centers: Vec<Center>,
}

impl Net {
    pub fn size(&self) -> (u32, u32) {
        let mut width = 0;
        let mut height = 0;
        for x in &self.corners {
            let br = x.rect.bottom_right();
            let b = br.y + &self.grid.sticker_gap.unwrap_or(0);
            let r = br.x + &self.grid.sticker_gap.unwrap_or(0);
            if b > height {
                height = b
            }
            if r > width {
                width = r
            }
        }
        for x in &self.edges {
            let br = x.rect.bottom_right();
            let b = br.y + &self.grid.sticker_gap.unwrap_or(0);
            let r = br.x + &self.grid.sticker_gap.unwrap_or(0);
            if b > height {
                height = b
            }
            if r > width {
                width = r
            }
        }
        for x in &self.centers {
            let br = x.rect.bottom_right();
            let b = br.y + &self.grid.sticker_gap.unwrap_or(0);
            let r = br.x + &self.grid.sticker_gap.unwrap_or(0);
            if b > height {
                height = b
            }
            if r > width {
                width = r
            }
        }
        (width as u32, height as u32)
    }

    pub fn t(grid: Grid, color_scheme: ColorScheme) -> Self {
        use Face::*;
        let centers = vec![
            grid.center_sq(B, 4, 1),
            grid.center_sq(U, 4, 4),
            grid.center_sq(F, 4, 7),
            grid.center_sq(D, 4, 10),
            grid.center_sq(L, 1, 4),
            grid.center_sq(R, 7, 4),
        ];
        let corners = vec![
            // B
            grid.corner_sq(4, 1, 3, 0),
            grid.corner_sq(5, 2, 5, 0),
            grid.corner_sq(1, 1, 5, 2),
            grid.corner_sq(0, 2, 3, 2),
            // U
            grid.corner_sq(0, 0, 3, 3),
            grid.corner_sq(1, 0, 5, 3),
            grid.corner_sq(2, 0, 5, 5),
            grid.corner_sq(3, 0, 3, 5),
            // L
            grid.corner_sq(4, 2, 0, 3),
            grid.corner_sq(0, 1, 2, 3),
            grid.corner_sq(3, 2, 2, 5),
            grid.corner_sq(7, 1, 0, 5),
            // R
            grid.corner_sq(1, 2, 6, 3),
            grid.corner_sq(2, 1, 6, 5),
            grid.corner_sq(5, 1, 8, 3),
            grid.corner_sq(6, 2, 8, 5),
            // F
            grid.corner_sq(3, 1, 3, 6),
            grid.corner_sq(2, 2, 5, 6),
            grid.corner_sq(6, 1, 5, 8),
            grid.corner_sq(7, 2, 3, 8),
            // D
            grid.corner_sq(7, 0, 3, 9),
            grid.corner_sq(6, 0, 5, 9),
            grid.corner_sq(5, 0, 5, 11),
            grid.corner_sq(4, 0, 3, 11),
        ];
        let edges = vec![
            // B
            grid.edge_sq(8, false, 4, 0),
            grid.edge_sq(5, true, 5, 1),
            grid.edge_sq(0, false, 4, 2),
            grid.edge_sq(4, true, 3, 1),
            // U
            grid.edge_sq(0, true, 4, 3),
            grid.edge_sq(1, true, 5, 4),
            grid.edge_sq(2, true, 4, 5),
            grid.edge_sq(3, true, 3, 4),
            // L
            grid.edge_sq(3, false, 2, 4),
            grid.edge_sq(7, false, 1, 5),
            grid.edge_sq(11, false, 0, 4),
            grid.edge_sq(4, false, 1, 3),
            // R
            grid.edge_sq(1, false, 6, 4),
            grid.edge_sq(5, false, 7, 3),
            grid.edge_sq(9, false, 8, 4),
            grid.edge_sq(6, false, 7, 5),
            // F
            grid.edge_sq(2, false, 4, 6),
            grid.edge_sq(6, true, 5, 7),
            grid.edge_sq(10, false, 4, 8),
            grid.edge_sq(7, true, 3, 7),
            // D
            grid.edge_sq(10, true, 4, 9),
            grid.edge_sq(9, true, 5, 10),
            grid.edge_sq(8, true, 4, 11),
            grid.edge_sq(11, true, 3, 10),
        ];
        Self {
            grid,
            color_scheme,
            corners,
            edges,
            centers,
        }
    }

    fn draw_corners(&self, state: &Solved, canvas: &mut Canvas<Window>) {
        for corner in &self.corners {
            let face = state.corner_sticker(corner.piece, corner.sticker).unwrap();
            let color = self.color_scheme.color(face);
            canvas.set_draw_color(color);
            canvas.fill_rect(corner.rect).unwrap();
        }
    }

    fn draw_edges(&self, state: &Solved, canvas: &mut Canvas<Window>) {
        for edge in &self.edges {
            let face = state.edge_sticker(edge.piece, edge.top).unwrap();
            let color = self.color_scheme.color(face);
            canvas.set_draw_color(color);
            canvas.fill_rect(edge.rect).unwrap();
        }
    }

    fn draw_centers(&self, canvas: &mut Canvas<Window>) {
        for center in &self.centers {
            let color = self.color_scheme.color(center.face);
            canvas.set_draw_color(color);
            canvas.fill_rect(center.rect).unwrap();
        }
    }

    pub fn draw(&self, state: &Solved, canvas: &mut Canvas<Window>) {
        // Should reset the canvas' draw color as to not surprise anyone.
        canvas.set_draw_color(self.color_scheme.background());
        canvas.clear();
        self.draw_corners(state, canvas);
        self.draw_edges(state, canvas);
        self.draw_centers(canvas);
    }
}

pub struct Corner {
    pub piece: usize,
    pub sticker: i32,
    pub rect: Rect,
}

pub struct Edge {
    pub piece: usize,
    pub top: bool,
    pub rect: Rect,
}

pub struct Center {
    pub face: Face,
    pub rect: Rect,
}