ochess/src/game_tab/left_panel/GameTabLeftPanel.cpp
2023-01-09 16:36:48 +01:00

137 lines
4.4 KiB
C++

#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::SetEngineArrows(std::vector<std::string> arrows){
engine_arrows=arrows;
Notify(true);
}
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);
gs.arrows=engine_arrows;
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(); }