mirror of
https://gitlab.com/manzerbredes/ochess.git
synced 2025-04-07 02:26:29 +02:00
176 lines
5.7 KiB
C++
176 lines
5.7 KiB
C++
#include "GameTabLeftPanel.hpp"
|
|
#include <wx/clipbrd.h>
|
|
|
|
GameTabLeftPanel::GameTabLeftPanel(wxFrame *parent, std::shared_ptr<Game> game)
|
|
: TabGameLeftPanel(parent), game(game), repeat(false), is_engine_on(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) {
|
|
engine_arrows.clear(); // Remove displayed engine arrows
|
|
std::string move=event.GetString().ToStdString();
|
|
int size=move.size();
|
|
char promote=(char)event.GetInt();
|
|
// First check if it is a promotion move (to prompt the user for a piece)
|
|
if(size>0 && game->IsPromotionMove(move)){
|
|
promote_on=move.substr(2,2); // Will trigger the piece prompt on next Notify()
|
|
promotion_move=move; // Save the move that should be played for the promotion
|
|
} else {
|
|
if(size==0){ // It is a promotion move?
|
|
move=promotion_move; // Play the save promotion move
|
|
promote_on.clear(); // Clear user prompte (cf. Notify())
|
|
promotion_move.clear();
|
|
}
|
|
if(game->Play(move,promote)){
|
|
// 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::SetEngineEvaluation(EngineEvaluation eval){
|
|
if(is_engine_on){
|
|
engine_arrows.clear();
|
|
float scale=1;
|
|
unsigned char color=0;
|
|
for(auto const &arrow: eval.best_lines){
|
|
std::string src=arrow.substr(0,2);
|
|
std::string dst=arrow.substr(2,2);
|
|
engine_arrows.push_back({src,dst,wxColour(color,color,color),scale});
|
|
scale=std::max(0.1,scale-0.25);
|
|
color=std::min(255,color+70);
|
|
}
|
|
eval_cp=eval.eval;
|
|
Notify(true);
|
|
}
|
|
}
|
|
|
|
void GameTabLeftPanel::SetLiveEngineState(bool isOn){
|
|
is_engine_on=isOn;
|
|
if(!is_engine_on){
|
|
engine_arrows.clear();
|
|
eval_cp=0;
|
|
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->IsVariation()){
|
|
m->GetAbsoluteMove(src,dst);
|
|
animate=true;
|
|
}else if(m->HasChild(last_move) && !last_move->IsVariation()){ // call to IsVariation is safe because of HasChild() before! cf below
|
|
// 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;
|
|
gs.promotion=promote_on;
|
|
gs.show_evalbar=is_engine_on;
|
|
gs.eval=eval_cp/100;
|
|
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,wxColour(255,190,190)});
|
|
gs.squares_hl.push_back({dst_hl,wxColour(255,100,100)});
|
|
}
|
|
}
|
|
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(); }
|