mirror of
https://gitlab.com/manzerbredes/ochess.git
synced 2025-07-03 02:37:39 +00:00
Refactoring game tab
This commit is contained in:
parent
7178f18ab8
commit
bf485fa577
16 changed files with 68 additions and 69 deletions
294
src/game_tab/left_panel/board/BoardCanvas.cpp
Normal file
294
src/game_tab/left_panel/board/BoardCanvas.cpp
Normal file
|
@ -0,0 +1,294 @@
|
|||
#include "BoardCanvas.hpp"
|
||||
|
||||
wxDEFINE_EVENT(PLAY_MOVE_EVENT, wxCommandEvent);
|
||||
|
||||
BoardCanvas::BoardCanvas(wxFrame *parent)
|
||||
: wxPanel(parent), black_side(false), is_black_turn(true), frozen(false),
|
||||
lock_square_size(false), t(new Theme()), t_captures(new Theme()) {
|
||||
board = "rnbqkbnrpppppppp PPPPPPPPRNBQKBNR";
|
||||
is_dragging = false;
|
||||
valid_drag = false;
|
||||
t_captures->ResizePieces(t->GetPiecesSizes() * CAPTURE_FACTOR);
|
||||
SetClockTime(-1, -1, -1, false);
|
||||
SetClockTime(-1, -1, -1, true);
|
||||
ApplyPreferences();
|
||||
}
|
||||
|
||||
BoardCanvas::BoardCanvas(wxFrame *parent, std::uint32_t square_width,
|
||||
bool frozen)
|
||||
: BoardCanvas(parent) {
|
||||
t->ResizeSquaresAndPieces(square_width);
|
||||
t_captures->ResizePieces(t->GetPiecesSizes() * CAPTURE_FACTOR);
|
||||
this->frozen = true;
|
||||
lock_square_size = true;
|
||||
}
|
||||
|
||||
void BoardCanvas::OnPaint(wxPaintEvent &event) {
|
||||
wxPaintDC dc(this);
|
||||
REFRESH_MOUSE_LOCATION();
|
||||
square_width = t->GetSquaresSizes();
|
||||
canvas_size = dc.GetSize();
|
||||
boardX = (canvas_size.x - (8 * square_width)) / 2;
|
||||
boardY = (canvas_size.y - (8 * square_width)) / 2;
|
||||
if (boardX > canvas_size.x)
|
||||
boardX = 0;
|
||||
if (boardY > canvas_size.y)
|
||||
boardY = 0;
|
||||
DrawBoard(dc);
|
||||
}
|
||||
|
||||
void BoardCanvas::ApplyPreferences() {
|
||||
if (t != NULL)
|
||||
delete t;
|
||||
if (t_captures != NULL)
|
||||
delete t_captures;
|
||||
t = new Theme();
|
||||
t_captures = new Theme();
|
||||
|
||||
CONFIG_OPEN(config);
|
||||
black_side = config->Read("board/black_by_default", false);
|
||||
if (lock_square_size) {
|
||||
t->ResizeSquaresAndPieces(square_width);
|
||||
} else {
|
||||
t->ResizeSquaresAndPieces(config->Read("board/square_size", 80));
|
||||
}
|
||||
t->SetSquareRadius(config->Read("board/corner_radius", 10));
|
||||
t_captures->ResizePieces(t->GetPiecesSizes() * CAPTURE_FACTOR);
|
||||
CONFIG_CLOSE(config);
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void BoardCanvas::SetupBoard(std::string board, bool is_black_turn,
|
||||
std::map<char, std::uint8_t> captures) {
|
||||
this->board = board;
|
||||
this->is_black_turn = is_black_turn;
|
||||
this->captures = captures;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void BoardCanvas::DrawBoard(wxPaintDC &dc) {
|
||||
std::uint32_t piece_width = t->GetPiecesSizes();
|
||||
std::uint32_t centrer_offset = (square_width - piece_width) / 2;
|
||||
|
||||
bool DrawDraggingPiece = false;
|
||||
char dp = 'p';
|
||||
std::uint32_t dpx = 0, dpy = 0;
|
||||
for (std::int8_t file = 7; file >= 0; file--) {
|
||||
for (std::uint8_t rank = 0; rank <= 7; rank++) {
|
||||
std::uint32_t x = boardX + (7 - file) * square_width;
|
||||
std::uint32_t y = boardY + rank * square_width;
|
||||
if ((file + rank) % 2 == 0) {
|
||||
if (file == 0 && rank == 0) {
|
||||
dc.DrawBitmap(*t->Get('1'), x, y, true);
|
||||
} else if (file == 7 && rank == 7) {
|
||||
dc.DrawBitmap(*t->Get('2'), x, y, true);
|
||||
} else {
|
||||
dc.DrawBitmap(*t->Get('s'), x, y, true);
|
||||
}
|
||||
} else {
|
||||
if (file == 7 && rank == 0) {
|
||||
dc.DrawBitmap(*t->Get('0'), x, y, true);
|
||||
} else if (file == 0 && rank == 7) {
|
||||
dc.DrawBitmap(*t->Get('3'), x, y, true);
|
||||
} else {
|
||||
dc.DrawBitmap(*t->Get('S'), x, y, true);
|
||||
}
|
||||
}
|
||||
|
||||
std::uint8_t prank = rank;
|
||||
std::uint8_t pfile = file;
|
||||
if (black_side) {
|
||||
prank = 7 - rank;
|
||||
pfile = 7 - file;
|
||||
}
|
||||
std::uint32_t px = x + centrer_offset;
|
||||
std::uint32_t py = y + centrer_offset;
|
||||
char piece = board[(7 - pfile) + 8 * prank];
|
||||
if (is_dragging && (7 - pfile) == active_square.x &&
|
||||
(7 - prank) == active_square.y) {
|
||||
dp = piece;
|
||||
dpx = px - (lastClickX - mouseX);
|
||||
dpy = py - (lastClickY - mouseY);
|
||||
DrawDraggingPiece = true;
|
||||
continue;
|
||||
}
|
||||
if (piece != ' ') {
|
||||
dc.DrawBitmap(*t->Get(piece), px, py, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw badge
|
||||
dc.SetPen(wxPen(*wxBLACK, 3));
|
||||
std::uint32_t badgeY = boardY;
|
||||
std::uint32_t badgeWidth = square_width / 2;
|
||||
if (is_black_turn) {
|
||||
dc.SetBrush(*wxBLACK_BRUSH);
|
||||
if (black_side) {
|
||||
badgeY = boardY + (8 * square_width) - badgeWidth;
|
||||
}
|
||||
} else {
|
||||
dc.SetBrush(*wxWHITE_BRUSH);
|
||||
if (!black_side) {
|
||||
badgeY = boardY + (8 * square_width) - badgeWidth;
|
||||
}
|
||||
}
|
||||
wxRect badge(boardX + (8 * square_width) + badgeWidth / 2, badgeY, badgeWidth,
|
||||
badgeWidth);
|
||||
dc.DrawRectangle(badge);
|
||||
|
||||
// Draw captures first for white then for black
|
||||
std::uint32_t captures_size = t_captures->GetPiecesSizes();
|
||||
std::uint8_t padding = 10;
|
||||
std::uint32_t offsetX = 0;
|
||||
std::uint32_t offsetY = -(captures_size + padding);
|
||||
if (black_side) {
|
||||
offsetY = 8 * square_width + padding;
|
||||
}
|
||||
for (char p : {'P', 'N', 'B', 'R', 'Q'}) {
|
||||
if (captures.find(p) != captures.end()) {
|
||||
for (std::uint8_t i = 0; i < captures[p]; i++) {
|
||||
dc.DrawBitmap(*t_captures->Get(p), boardX + offsetX, boardY + offsetY);
|
||||
offsetX += captures_size / 2;
|
||||
}
|
||||
offsetX += captures_size / 2;
|
||||
}
|
||||
}
|
||||
offsetX = 0;
|
||||
if (black_side) {
|
||||
offsetY = -(captures_size + padding);
|
||||
} else {
|
||||
offsetY = 8 * square_width + padding;
|
||||
}
|
||||
for (char p : {'p', 'n', 'b', 'r', 'q'}) {
|
||||
if (captures.find(p) != captures.end()) {
|
||||
for (std::uint8_t i = 0; i < captures[p]; i++) {
|
||||
dc.DrawBitmap(*t_captures->Get(p), boardX + offsetX, boardY + offsetY);
|
||||
offsetX += captures_size / 2;
|
||||
}
|
||||
offsetX += captures_size / 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw dragging piece
|
||||
if (DrawDraggingPiece) {
|
||||
dc.DrawBitmap(*t->Get(dp), dpx, dpy, false);
|
||||
}
|
||||
|
||||
// Draw numbers
|
||||
for (char l = 'a'; l < 'a' + 8; l++) {
|
||||
dc.DrawText(wxString(l), wxPoint(boardX + l - 'a' * square_width,
|
||||
boardY + 8 * square_width + 10));
|
||||
}
|
||||
|
||||
// Draw Clocks
|
||||
if (std::get<0>(black_time) >= 0) {
|
||||
wxFont font = dc.GetFont();
|
||||
ClockTime clock = black_side ? white_time : black_time;
|
||||
wxString time =
|
||||
wxString::Format("%ds", std::get<1>(clock), std::get<2>(clock));
|
||||
if (std::get<0>(clock) > 0) {
|
||||
time = wxString::Format("%d:%d", std::get<0>(clock), std::get<1>(clock));
|
||||
} else if (std::get<1>(clock) > 0) {
|
||||
time = wxString::Format("%d:%ds", std::get<1>(clock), std::get<2>(clock));
|
||||
}
|
||||
dc.SetFont(font.Scale(1.5).MakeBold());
|
||||
wxCoord width, height;
|
||||
dc.GetTextExtent(time, &width, &height);
|
||||
dc.DrawText(time,
|
||||
wxPoint(boardX + square_width * 8 - width, boardY - height));
|
||||
clock = black_side ? black_time : white_time;
|
||||
time = wxString::Format("%ds", std::get<1>(clock), std::get<2>(clock));
|
||||
if (std::get<0>(clock) > 0) {
|
||||
time = wxString::Format("%d:%d", std::get<0>(clock), std::get<1>(clock));
|
||||
} else if (std::get<1>(clock) > 0) {
|
||||
time = wxString::Format("%d:%ds", std::get<1>(clock), std::get<2>(clock));
|
||||
}
|
||||
dc.GetTextExtent(time, &width, &height);
|
||||
dc.DrawText(time, wxPoint(boardX + square_width * 8 - width,
|
||||
boardY + square_width * 8));
|
||||
}
|
||||
}
|
||||
|
||||
void BoardCanvas::MouseEvent(wxMouseEvent &event) {
|
||||
if (!frozen) {
|
||||
if (event.Dragging()) {
|
||||
if (valid_drag) {
|
||||
is_dragging = true;
|
||||
Refresh();
|
||||
}
|
||||
} else {
|
||||
if (is_dragging) {
|
||||
is_dragging = false;
|
||||
valid_drag = false;
|
||||
// Handle drop
|
||||
REFRESH_MOUSE_LOCATION();
|
||||
INIT_CURRENT_SQUARE();
|
||||
|
||||
if (IsCurrentSquareValid) {
|
||||
wxLogDebug("Drag end on square (%d,%d)", file, rank);
|
||||
/// Play the move
|
||||
wxCommandEvent event(PLAY_MOVE_EVENT, GetId());
|
||||
event.SetEventObject(this);
|
||||
std::string move = ((char)('a' + active_square.x)) +
|
||||
std::to_string(+active_square.y + 1) +
|
||||
((char)('a' + file)) + std::to_string(rank + 1);
|
||||
event.SetString(move);
|
||||
ProcessEvent(event);
|
||||
}
|
||||
}
|
||||
if (event.LeftDown()) {
|
||||
SetFocus();
|
||||
REFRESH_MOUSE_LOCATION();
|
||||
lastClickX = mouseX;
|
||||
lastClickY = mouseY;
|
||||
INIT_CURRENT_SQUARE();
|
||||
if (IsCurrentSquareValid) {
|
||||
active_square.x = file;
|
||||
active_square.y = rank;
|
||||
if (board[(7 - rank) * 8 + file] != ' ') {
|
||||
wxLogDebug("Drag start on square (%d,%d)", file, rank);
|
||||
valid_drag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BoardCanvas::Zoom(std::int32_t zoom) {
|
||||
t->Zoom(zoom);
|
||||
t_captures->ResizePieces(t->GetPiecesSizes() * CAPTURE_FACTOR);
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void BoardCanvas::Swap() {
|
||||
black_side = !black_side;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void BoardCanvas::OnKeyEvent(wxKeyEvent &event) {
|
||||
if (event.GetKeyCode() == WXK_LEFT) {
|
||||
wxCommandEvent previousEvent(PREVIOUS_MOVE_EVENT, GetId());
|
||||
previousEvent.SetEventObject(this);
|
||||
ProcessEvent(previousEvent);
|
||||
} else if (event.GetKeyCode() == WXK_RIGHT) {
|
||||
wxCommandEvent nextEvent(NEXT_MOVE_EVENT, GetId());
|
||||
nextEvent.SetEventObject(this);
|
||||
ProcessEvent(nextEvent);
|
||||
}
|
||||
}
|
||||
|
||||
void BoardCanvas::SetClockTime(short hours, short min, short sec,
|
||||
bool IsBlack) {
|
||||
if (IsBlack) {
|
||||
black_time = std::make_tuple(hours, min, sec);
|
||||
} else {
|
||||
white_time = std::make_tuple(hours, min, sec);
|
||||
}
|
||||
}
|
||||
|
||||
wxBEGIN_EVENT_TABLE(BoardCanvas, wxPanel) EVT_PAINT(BoardCanvas::OnPaint)
|
||||
EVT_MOUSE_EVENTS(BoardCanvas::MouseEvent)
|
||||
EVT_CHAR_HOOK(BoardCanvas::OnKeyEvent) wxEND_EVENT_TABLE()
|
68
src/game_tab/left_panel/board/BoardCanvas.hpp
Normal file
68
src/game_tab/left_panel/board/BoardCanvas.hpp
Normal file
|
@ -0,0 +1,68 @@
|
|||
#pragma once
|
||||
|
||||
#include "Theme.hpp"
|
||||
#include "ochess.hpp"
|
||||
#include <map>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <wx/artprov.h>
|
||||
|
||||
// Local events
|
||||
wxDECLARE_EVENT(PLAY_MOVE_EVENT, wxCommandEvent);
|
||||
|
||||
// Foreign events
|
||||
wxDECLARE_EVENT(PREVIOUS_MOVE_EVENT, wxCommandEvent);
|
||||
wxDECLARE_EVENT(NEXT_MOVE_EVENT, wxCommandEvent);
|
||||
|
||||
#define REFRESH_MOUSE_LOCATION() \
|
||||
{ \
|
||||
const wxPoint pt = wxGetMousePosition(); \
|
||||
mouseX = pt.x - this->GetScreenPosition().x; \
|
||||
mouseY = pt.y - this->GetScreenPosition().y; \
|
||||
}
|
||||
|
||||
#define INIT_CURRENT_SQUARE() \
|
||||
std::uint32_t file = 7 - (mouseX - boardX) / square_width; \
|
||||
std::uint32_t rank = (mouseY - boardY) / square_width; \
|
||||
if (!black_side) { \
|
||||
file = 7 - file; \
|
||||
rank = 7 - rank; \
|
||||
} \
|
||||
bool IsCurrentSquareValid = file >= 0 && file <= 7 && rank >= 0 && rank <= 7;
|
||||
|
||||
#define MOUSE_ON(x, y, width, height) \
|
||||
(mouseX >= (x) && mouseX <= ((x) + (width)) && mouseY >= (y) && \
|
||||
mouseY <= ((y) + (height)))
|
||||
|
||||
#define CAPTURE_FACTOR 0.5
|
||||
|
||||
typedef std::tuple<short, short, short> ClockTime;
|
||||
|
||||
class BoardCanvas : public wxPanel {
|
||||
Theme *t, *t_captures;
|
||||
std::string board;
|
||||
bool black_side, is_dragging, valid_drag, is_black_turn;
|
||||
std::uint32_t boardX, boardY, square_width, mouseX, mouseY, lastClickX,
|
||||
lastClickY;
|
||||
wxSize canvas_size;
|
||||
wxPoint active_square;
|
||||
std::map<char, std::uint8_t> captures;
|
||||
ClockTime black_time, white_time;
|
||||
bool frozen,lock_square_size;
|
||||
|
||||
public:
|
||||
BoardCanvas(wxFrame *parent);
|
||||
BoardCanvas(wxFrame *parent,std::uint32_t square_width, bool frozen);
|
||||
void ApplyPreferences();
|
||||
void DrawBoard(wxPaintDC &dc);
|
||||
void OnPaint(wxPaintEvent &event);
|
||||
void OnKeyEvent(wxKeyEvent &event);
|
||||
void MouseEvent(wxMouseEvent &event);
|
||||
void Zoom(std::int32_t zoom);
|
||||
void Swap();
|
||||
void SetupBoard(std::string board, bool is_black_turn,
|
||||
std::map<char, std::uint8_t> captures);
|
||||
void SetClockTime(short hours, short min, short sec, bool IsBlack);
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
184
src/game_tab/left_panel/board/Theme.cpp
Normal file
184
src/game_tab/left_panel/board/Theme.cpp
Normal file
|
@ -0,0 +1,184 @@
|
|||
#include "Theme.hpp"
|
||||
#include <wx/filename.h>
|
||||
|
||||
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<char, wxBitmap *> 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<char, wxImage> 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));
|
||||
}
|
37
src/game_tab/left_panel/board/Theme.hpp
Normal file
37
src/game_tab/left_panel/board/Theme.hpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
|
||||
#include "ochess.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#define ELT_DIM 200
|
||||
#define DEFAULT_SIZE 80
|
||||
#define PIECE_SIZE_FACTOR 0.8 // Should be between 0 and 1
|
||||
#define DEFAULT_PIECE_THEME "assets/pieces/cburnett.png"
|
||||
#define DEFAULT_SQUARE_THEME "assets/boards/chesscom_8bits.png"
|
||||
|
||||
class Theme {
|
||||
private:
|
||||
std::unordered_map<char, wxImage> skin;
|
||||
std::unordered_map<char, wxBitmap *> skin_scaled;
|
||||
std::uint8_t square_radius;
|
||||
wxMask *RoundedMask(std::uint32_t width, std::uint8_t corner);
|
||||
|
||||
public:
|
||||
Theme();
|
||||
Theme(std::string piece, std::string square);
|
||||
~Theme();
|
||||
void LoadPiecesSkin(wxImage skin);
|
||||
void LoadSquaresSkin(wxImage iskin);
|
||||
void ResizePieces(std::uint32_t width);
|
||||
void ResizeSquares(std::uint32_t width);
|
||||
void ResizeSquaresAndPieces(std::uint32_t width);
|
||||
void SetSquareRadius(std::uint8_t radius);
|
||||
std::uint8_t GetSquareRadius();
|
||||
void Zoom(int amount);
|
||||
double GetPiecesSizes();
|
||||
double GetSquaresSizes();
|
||||
|
||||
wxBitmap *Get(char c);
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue