#include "GameTabLeftPanel.hpp" #include GameTabLeftPanel::GameTabLeftPanel(wxFrame *parent, std::shared_ptr 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 arrows){ engine_arrows=arrows; Notify(true); } void GameTabLeftPanel::Notify(bool skip_animation) { // Update fen and captures std::string fen = game->GetFen(); std::map 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(); }