aboutsummaryrefslogtreecommitdiff
path: root/src/game_tab/left_panel/GameTabLeftPanel.cpp
blob: 5b8162cc981f0624dd0f3022681042f3eff4492c (plain)
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(); }