From ce941c146aea7925bded6b9d2a0d0559d3156ad3 Mon Sep 17 00:00:00 2001 From: Loic Guegan Date: Wed, 23 Feb 2022 18:11:55 +0100 Subject: Create repository --- src/game_tab/board/Theme.cpp | 184 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 src/game_tab/board/Theme.cpp (limited to 'src/game_tab/board/Theme.cpp') diff --git a/src/game_tab/board/Theme.cpp b/src/game_tab/board/Theme.cpp new file mode 100644 index 0000000..6ecbafc --- /dev/null +++ b/src/game_tab/board/Theme.cpp @@ -0,0 +1,184 @@ +#include "Theme.hpp" +#include + +Theme::Theme() : square_radius(10) { + // Load config + CONFIG_OPEN(config); + std::string piece = + config->Read("board/theme/pieces/path", "default").ToStdString(); + wxFileName piece_file(piece); + std::string square = + config->Read("board/theme/squares/path", "default").ToStdString(); + wxFileName square_file(square); + CONFIG_CLOSE(config); + // Piece + if (piece == "default" || !piece_file.FileExists()) { + wxLogDebug("Loading piece skin from binres"); + LoadPiecesSkin(LoadPNG("cburnett").ConvertToImage()); + } else { + wxLogDebug("Loading piece skin: %s", piece); + LoadPiecesSkin(wxImage(piece, wxBITMAP_TYPE_PNG)); + } + // Square + if (square == "default" || !square_file.FileExists()) { + wxLogDebug("Loading square skin from binres"); + LoadSquaresSkin(LoadPNG("chesscom_8bits").ConvertToImage()); + } else { + wxLogDebug("Loading square skin: %s", square); + LoadSquaresSkin(wxImage(square, wxBITMAP_TYPE_PNG)); + } +} + +Theme::Theme(std::string piece, std::string square) : square_radius(10) { + wxLogDebug("Loading piece skin: %s", piece); + LoadPiecesSkin(wxImage(piece, wxBITMAP_TYPE_PNG)); + wxLogDebug("Loading square skin: %s", square); + LoadSquaresSkin(wxImage(square, wxBITMAP_TYPE_PNG)); +} + +Theme::~Theme() { + for (std::pair c : skin_scaled) { + delete c.second; + } +} + +std::uint8_t Theme::GetSquareRadius() { return (square_radius); } + +void Theme::LoadPiecesSkin(wxImage iskin) { + if (iskin.GetWidth() != 2 * ELT_DIM || iskin.GetHeight() != 6 * ELT_DIM) { + throw "Invalid piece theme"; + } + + int offset = 0; + // Kings + skin['k'] = iskin.GetSubImage(wxRect(0, offset, ELT_DIM, ELT_DIM)); + skin['K'] = iskin.GetSubImage(wxRect(ELT_DIM, offset, ELT_DIM, ELT_DIM)); + // Queen + offset = ELT_DIM; + skin['q'] = iskin.GetSubImage(wxRect(0, offset, ELT_DIM, ELT_DIM)); + skin['Q'] = iskin.GetSubImage(wxRect(ELT_DIM, offset, ELT_DIM, ELT_DIM)); + // Rook + offset = ELT_DIM * 2; + skin['r'] = iskin.GetSubImage(wxRect(0, offset, ELT_DIM, ELT_DIM)); + skin['R'] = iskin.GetSubImage(wxRect(ELT_DIM, offset, ELT_DIM, ELT_DIM)); + // Bishop + offset = ELT_DIM * 3; + skin['b'] = iskin.GetSubImage(wxRect(0, offset, ELT_DIM, ELT_DIM)); + skin['B'] = iskin.GetSubImage(wxRect(ELT_DIM, offset, ELT_DIM, ELT_DIM)); + // Knight + offset = ELT_DIM * 4; + skin['n'] = iskin.GetSubImage(wxRect(0, offset, ELT_DIM, ELT_DIM)); + skin['N'] = iskin.GetSubImage(wxRect(ELT_DIM, offset, ELT_DIM, ELT_DIM)); + // Pawn + offset = ELT_DIM * 5; + skin['p'] = iskin.GetSubImage(wxRect(0, offset, ELT_DIM, ELT_DIM)); + skin['P'] = iskin.GetSubImage(wxRect(ELT_DIM, offset, ELT_DIM, ELT_DIM)); + + // Update scaled version + ResizePieces(DEFAULT_SIZE * PIECE_SIZE_FACTOR); +} + +void Theme::LoadSquaresSkin(wxImage iskin) { + if (iskin.GetWidth() != 2 * ELT_DIM || iskin.GetHeight() != ELT_DIM) { + throw "Invalid piece theme"; + } + + // Square + skin['s'] = iskin.GetSubImage(wxRect(0, 0, ELT_DIM, ELT_DIM)); + skin['S'] = iskin.GetSubImage(wxRect(ELT_DIM, 0, ELT_DIM, ELT_DIM)); + + // Update scaled version + ResizeSquares(DEFAULT_SIZE); +} + +wxBitmap *Theme::Get(char c) { return (skin_scaled[c]); } + +void Theme::ResizePieces(std::uint32_t width) { + for (std::pair c : skin) { + if (c.first != 's' && c.first != 'S') { + if (skin_scaled.count(c.first)) + delete skin_scaled[c.first]; + skin_scaled[c.first] = + new wxBitmap(c.second.Scale(width, width, wxIMAGE_QUALITY_HIGH)); + } + } +} + +void Theme::ResizeSquaresAndPieces(std::uint32_t width) { + ResizeSquares(width); + ResizePieces(width * PIECE_SIZE_FACTOR); +} + +void Theme::ResizeSquares(std::uint32_t width) { + if (skin_scaled.count('s')) + delete skin_scaled['s']; + skin_scaled['s'] = + new wxBitmap(skin['s'].Scale(width, width, wxIMAGE_QUALITY_HIGH)); + if (skin_scaled.count('S')) + delete skin_scaled['S']; + skin_scaled['S'] = + new wxBitmap(skin['S'].Scale(width, width, wxIMAGE_QUALITY_HIGH)); + + skin_scaled['0'] = new wxBitmap(*skin_scaled['S']); + skin_scaled['1'] = new wxBitmap(*skin_scaled['s']); + skin_scaled['2'] = new wxBitmap(*skin_scaled['s']); + skin_scaled['3'] = new wxBitmap(*skin_scaled['S']); + + skin_scaled['0']->SetMask(RoundedMask(width, 0)); + skin_scaled['1']->SetMask(RoundedMask(width, 1)); + skin_scaled['2']->SetMask(RoundedMask(width, 2)); + skin_scaled['3']->SetMask(RoundedMask(width, 3)); +} + +void Theme::Zoom(int amount) { + double width = skin_scaled['s']->GetWidth() + amount; + ResizeSquares(std::max(width, 1.0)); + ResizePieces(std::max(width * PIECE_SIZE_FACTOR, 1.0)); +} + +void Theme::SetSquareRadius(std::uint8_t radius) { + square_radius = radius; + Zoom(0); // Refresh scale +} + +/** + * This will never fail since k entry always exists (cf constructor and + * ResizePieces) + */ +double Theme::GetPiecesSizes() { return (skin_scaled['k']->GetWidth()); } + +/** + * This will never fail since s entry always exists (cf constructor and + * ResizeSquares) + */ +double Theme::GetSquaresSizes() { return (skin_scaled['s']->GetWidth()); } + +wxMask *Theme::RoundedMask(std::uint32_t width, std::uint8_t corner) { + + wxBitmap b(width, width, 1); + wxMemoryDC dc; + dc.SelectObject(b); + dc.SetPen(*wxBLACK_PEN); + dc.SetBrush(*wxBLACK_BRUSH); + dc.DrawRectangle(0, 0, width, width); + dc.SetBrush(*wxWHITE_BRUSH); + dc.SetPen(*wxWHITE_PEN); + dc.DrawRoundedRectangle(0, 0, width, width, square_radius); + + dc.SetBrush(*wxWHITE_BRUSH); + dc.SetPen(*wxWHITE_PEN); + if (corner == 0) { + dc.DrawRectangle(0, width / 2, width, width); + dc.DrawRectangle(width / 2, 0, width, width); + } else if (corner == 1) { + dc.DrawRectangle(0, 0, width / 2, width); + dc.DrawRectangle(0, width / 2, width, width); + } else if (corner == 2) { + dc.DrawRectangle(0, 0, width, width / 2); + dc.DrawRectangle(width / 2, 0, width, width); + } else if (corner == 3) { + dc.DrawRectangle(0, 0, width / 2, width); + dc.DrawRectangle(0, 0, width, width / 2); + } + return (new wxMask(b)); +} -- cgit v1.2.3