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
|
#include "GameTabLeftPanel.hpp"
#include <wx/clipbrd.h>
GameTabLeftPanel::GameTabLeftPanel(wxFrame *parent, std::shared_ptr<Game> game)
: TabGameLeftPanel(parent), game(game), repeat(false) {
// Configure toolbar (note that toolbar events are processed into the GameTab class)
game_toolbar->AddTool(0, wxT("Save As"),
wxArtProvider::GetBitmap(wxART_FILE_SAVE, wxART_TOOLBAR));
game_toolbar->AddTool(1, wxT("Duplicate Game"),
wxArtProvider::GetBitmap(wxART_COPY, wxART_TOOLBAR));
// Add board
board_canvas = new BoardCanvas((wxFrame *)this);
main_sizer->Insert(1, board_canvas, 1, wxEXPAND);
// Configure buttons
swap_button->SetBitmapLabel(LoadPNG("swap"));
zoomin_button->SetBitmapLabel(LoadPNG("zoomin"));
zoomout_button->SetBitmapLabel(LoadPNG("zoomout"));
// Configure FEN field
fen_text_field->SetFont(wxFont(*wxNORMAL_FONT).Bold().Larger());
last_move=game->GetCurrentMove();
// Bind events:
Bind(PLAY_MOVE_EVENT, &GameTabLeftPanel::OnPlay, this, wxID_ANY);
Bind(wxEVT_BUTTON, [bc=board_canvas](wxCommandEvent &event){bc->Zoom(10);}, ZOOM_IN_BTN);
Bind(wxEVT_BUTTON, [bc=board_canvas](wxCommandEvent &event){bc->Zoom(-10);}, ZOOM_OUT_BTN);
Bind(wxEVT_BUTTON, [bc=board_canvas](wxCommandEvent &event){bc->Swap();}, SWAP_BTN);
Bind(wxEVT_KEY_UP, [p=this](wxKeyEvent &e){p->repeat=false;});
Bind(wxEVT_KEY_DOWN, [p=this](wxKeyEvent &e){
if(e.GetKeyCode() == WXK_RIGHT){
p->game->Next();
p->Notify();
p->repeat=true;
} else if(e.GetKeyCode() == WXK_LEFT){
p->game->Previous();
p->Notify();
p->repeat=true;
}
// Notify other classes
wxCommandEvent event(GAME_CHANGE, p->GetId());
event.SetEventObject(p);
p->ProcessEvent(event);
});
Bind(wxEVT_MOUSEWHEEL, [p=this](wxMouseEvent& e){
if(e.GetWheelRotation()<0){
p->game->Next();
p->Notify();
}else {
p->game->Previous();
p->Notify();
}
// Notify other classes
wxCommandEvent event(GAME_CHANGE, p->GetId());
event.SetEventObject(p);
p->ProcessEvent(event);
});
}
void GameTabLeftPanel::OnPlay(wxCommandEvent &event) {
wxLogDebug("Game tab received PLAY_MOVE_EVENT");
if (game->Play(event.GetString().ToStdString())) {
// Notify other classes
wxCommandEvent event(GAME_CHANGE, GetId());
event.SetEventObject(this);
ProcessEvent(event);
}
Notify(true); // Redraw event is move failed! Otherwise piece not resets to it initial position after dragging
}
void GameTabLeftPanel::Notify(bool skip_animation) {
// Update fen and captures
std::string fen = game->GetFen();
std::map<char, std::uint8_t> captures;
bool animate=false;
HalfMove *m = game->GetCurrentMove();
std::string src,dst;
// Update capture and check if we should to animations during moves change:
if (m){
captures = m->GetLineCaptures();
if(m->HasParent(last_move)){
m->GetAbsoluteMove(src,dst);
animate=true;
}else if(m->HasChild(last_move)){
// Accessing last_move here is safe since it is still
// in the tree of moves (since HasChild found it so not deleted)
last_move->GetAbsoluteMove(dst,src);
animate=true;
}
} else if(game->GetNextMove()){ // First move animation
HalfMove *next=game->GetNextMove();
if(next==last_move){
game->GetNextMove()->GetAbsoluteMove(dst,src);
animate=true;
}
}
// Update board canvas:
GameState gs;
gs.board=chessarbiter::FENParser::Parse(fen).board;
gs.is_black_turn=game->IsBlackToPlay();
gs.captures=captures;
gs.white=game->GetTag("White");
gs.black=game->GetTag("Black");
gs.mat_black=game->IsCheckmate(true);
gs.mat_white=game->IsCheckmate(false);
if(m){
// There should be a valid src_hl or dst_hl ortherwise it explode:
std::string src_hl, dst_hl;
m->GetAbsoluteMove(src_hl,dst_hl);
if(src_hl.size()>0){ // Just in case
gs.squares_hl.push_back(src_hl+"d");
gs.squares_hl.push_back(dst_hl+"a");
}
}
if(skip_animation || !animate){
board_canvas->SetupBoard(gs);
}
else{
board_canvas->Animate(gs, src,dst,repeat);
}
// Update last move
last_move=m;
// Update fen field:
fen_text_field->SetValue(game->GetFen());
}
void GameTabLeftPanel::ApplyPreferences() { board_canvas->ApplyPreferences(); }
|