1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
#pragma once
#include "Theme.hpp"
#include "ochess.hpp"
#include <map>
#include <tuple>
#include <utility>
#include <algorithm>
#include <vector>
#include <wx/artprov.h>
#include <wx/dcbuffer.h>
// Local events
wxDECLARE_EVENT(PLAY_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.35
#define SQUARE_NUM_PADDING 5
#define DEFAULT_ARROW(SRC,DST) {(SRC),(DST),wxNullColour,1}
#define DEFAULT_SQUARE(SQUARE) {(SQUARE),wxNullColour}
typedef std::tuple<short, short, short> ClockTime;
// Drawing buffer (ANIMATIONS)
typedef struct AnimState {
/// @brief Temporary buffer to reduce latency
wxBitmap *buffer;
/// @brief Should animation be played on refresh?
bool animate;
/// @brief Current animated frame
int frame;
/// @brief Total number of frames for the animation
int frames;
/// @brief Animation durations (in ms)
int duration,duration_fast;
/// @brief Animation FPS
std::uint8_t fps;
/// @brief Current animated piece
char piece_moved;
/// @brief Starting point of the animated piece
wxPoint src;
/// @brief Translation vector of the animated piece
wxPoint transVect;
} AnimState;
typedef struct GameState {
typedef struct Arrow {
std::string src,dst;
wxColour color=wxNullColour;
float scale=1;
} Arrow;
typedef struct Square {
std::string square;
wxColour color=wxNullColour;
} Square;
std::string white, black;
std::string board;
std::string promotion;
std::map<char, std::uint8_t> captures;
std::vector<Square> squares_hl;
std::vector<Arrow> arrows;
bool is_black_turn;
bool mat_black;
bool mat_white;
bool show_evalbar=false;
float eval=0;
ClockTime black_time={-1,-1,-1}, white_time={-1,-1,-1};
} GameState;
class BoardCanvas : public wxPanel {
// *t is theme for board+pieces and
// *t_captures is theme for captured pieces (scale down version of t)
Theme *t, *t_captures;
wxColour color_arrows;
int arrows_offset;
std::uint8_t arrow_thickness;
std::string white_player,black_player;
// Current highlighted squares and arrows:
std::vector<GameState::Square> squares_hl;
std::vector<GameState::Arrow> arrows;
// Various canvas state variables
bool black_side, is_dragging, valid_drag, arrow_drag, is_black_turn;
std::uint32_t boardX, boardY, square_width, piece_width, mouseX, mouseY, lastClickX,
lastClickY;
wxSize canvas_size;
wxPoint active_square;
std::map<char, std::uint8_t> captures;
bool frozen,lock_square_size;
// Current animation state
AnimState adata;
GameState gs;
/// @brief Draw an arrow from a source point to a destination point on DC
void DrawArrow(wxDC &dc, int xsrc, int ysrc, int xdst, int ydst, std::uint8_t thickness=50);
/// @brief Draw an arrow with a L shape (such as knight moves)
void DrawLArrow(wxDC &dc, int xsrc, int ysrc, int xdst, int ydst, bool flip=false, std::uint8_t thickness=50);
public:
BoardCanvas(wxFrame *parent);
BoardCanvas(wxFrame *parent,std::uint32_t square_width, bool frozen);
~BoardCanvas();
void ApplyPreferences();
/// @brief Draw current state of the board (GameState) on the given wxDC
void DrawBoard(wxDC &dc);
void OnPaint(wxPaintEvent &event);
void MouseEvent(wxMouseEvent &event);
/// @brief Zomm in/out on the canvas
void Zoom(std::int32_t zoom);
/// @brief Change between black side and white side
void Swap();
/// @brief Display a position on the canvas
void SetupBoard(const GameState &new_gs);
/// @brief Animate a piece front src to dst from current position
void Animate(const GameState &new_gs, const std::string &src, const std::string &dst,bool faster);
/// @brief Setup clock on displayed on the canvas
void SetClockTime(short hours, short min, short sec, bool IsBlack);
};
|