diff options
| -rw-r--r-- | TODO.md | 4 | ||||
| -rw-r--r-- | src/game_tab/left_panel/GameTabLeftPanel.cpp | 9 | ||||
| -rw-r--r-- | src/game_tab/left_panel/board/BoardCanvas.cpp | 144 | ||||
| -rw-r--r-- | src/game_tab/left_panel/board/BoardCanvas.hpp | 7 |
4 files changed, 92 insertions, 72 deletions
@@ -6,12 +6,12 @@ - [x] Ask before closing MainWindow/Tabs if anything is not saved - [x] Disable the save button in GameTab after saving (and re-enable it on new changes) - [ ] Make PGNGameBase use GotoNextGame() instead of ParseNextGame() in the NextGame() method to improve performance - - [ ] Clean and debug DragNDrop in BoardCanvas + - [x] Clean and debug DragNDrop in BoardCanvas ## Additional Features - [ ] Add a live evaluation bar to the BoardCanvas - [x] Be able to draw arrows on the Board - - [ ] Highlight the last played move + - [x] Highlight the last played move - [ ] Be able to play against an engine - [ ] Implement full chess engine game analyzer/annotator - [ ] Handle .si4 databases diff --git a/src/game_tab/left_panel/GameTabLeftPanel.cpp b/src/game_tab/left_panel/GameTabLeftPanel.cpp index 25ded2c..5b8162c 100644 --- a/src/game_tab/left_panel/GameTabLeftPanel.cpp +++ b/src/game_tab/left_panel/GameTabLeftPanel.cpp @@ -107,6 +107,15 @@ void GameTabLeftPanel::Notify(bool skip_animation) { 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); } diff --git a/src/game_tab/left_panel/board/BoardCanvas.cpp b/src/game_tab/left_panel/board/BoardCanvas.cpp index a31b0c6..7cca378 100644 --- a/src/game_tab/left_panel/board/BoardCanvas.cpp +++ b/src/game_tab/left_panel/board/BoardCanvas.cpp @@ -16,7 +16,7 @@ BoardCanvas::BoardCanvas(wxFrame *parent) color_arrows=wxColour(145, 233, 255); is_dragging = false; valid_drag = false; - valid_arrow = false; + arrow_drag = false; arrows_offset = t->GetSquaresSizes()/2.5; // Init animation data adata.duration=100; @@ -229,7 +229,8 @@ void BoardCanvas::DrawBoard(wxDC &dc) { } // Draw highlighted squares - for(const std::string &s:gs.squares_hl){ + for(int i=0;i<(gs.squares_hl.size()+squares_hl.size());i++){ + const std::string &s=i<gs.squares_hl.size() ? gs.squares_hl[i] : squares_hl[i-gs.squares_hl.size()]; std::uint8_t sfile = s[0]-'a'; std::uint8_t srank = s[1]-'1'; if (!black_side) { @@ -395,7 +396,8 @@ void BoardCanvas::DrawBoard(wxDC &dc) { boardY + square_width * 8 + numbers_size.y*2)); } // Draw arrows - for(const std::string arrow: gs.arrows){ + for(int i=0;i<(gs.arrows.size()+arrows.size());i++){ + const std::string &arrow= i<gs.arrows.size() ? gs.arrows[i] : arrows[i-gs.arrows.size()]; std::uint8_t sfile = arrow[0]-'a'; std::uint8_t srank = arrow[1]-'1'; std::uint8_t dfile = arrow[2]-'a'; @@ -427,14 +429,67 @@ void BoardCanvas::DrawBoard(wxDC &dc) { } void BoardCanvas::MouseEvent(wxMouseEvent &event) { - if (!frozen) { - if (event.Dragging()) { - if (valid_drag) { - is_dragging = true; - Refresh(); + // Disable mouse events if BoardCanvas is frozen: + if(frozen) + return; + + // Just redraw if a piece is currently being moved: + if (event.Dragging() && valid_drag) { + is_dragging = true; + Refresh(); + return; + } + + if (event.LeftDown() || event.RightDown()) { + // Start dragging (either piece or arrows drawing) + SetFocus(); + REFRESH_MOUSE_LOCATION(); + lastClickX = mouseX; + lastClickY = mouseY; + INIT_CURRENT_SQUARE(); + if (IsCurrentSquareValid) { + active_square.x = file; + active_square.y = rank; + if(event.LeftDown()){ + if (gs.board[(7 - rank) * 8 + file] != ' ') { + wxLogDebug("Drag start on square (%d,%d)", file, rank); + valid_drag = true; + } + } + else { + wxLogDebug("Arrow start on square (%d,%d)", file, rank); + arrow_drag = true; + } + } + } else if(event.LeftUp()) { + if(valid_drag){ + // Handle drop + REFRESH_MOUSE_LOCATION(); + INIT_CURRENT_SQUARE(); + + if (IsCurrentSquareValid) { + wxLogDebug("Drag end on square (%d,%d)", file, rank); + /// Play the move + wxCommandEvent event(PLAY_MOVE_EVENT, GetId()); + event.SetEventObject(this); + std::string move = ((char)('a' + active_square.x)) + + std::to_string(+active_square.y + 1) + + ((char)('a' + file)) + std::to_string(rank + 1); + event.SetString(move); + ProcessEvent(event); + } else { + // If square not valid just redraw (place piece back to its square) + Refresh(); // Note that there will be 2 Refresh() this one and the next after clear() of arrows and squares_hl but it is clearer like this } - } else if ((valid_arrow && event.RightUp()) || event.RightDClick()) { - valid_arrow=false; + } + arrows.clear(); + squares_hl.clear(); + Refresh(); + // In any left up, reset dragging variables + valid_drag = false; + is_dragging = false; + } else if(event.RightUp()){ + if(arrow_drag){ // Handle drop REFRESH_MOUSE_LOCATION(); INIT_CURRENT_SQUARE(); @@ -443,73 +498,28 @@ void BoardCanvas::MouseEvent(wxMouseEvent &event) { std::to_string(+active_square.y + 1); std::string dst=((char)('a' + file)) + std::to_string(rank + 1); if(src!=dst){ - gs.arrows.push_back(src+dst); + arrows.push_back(src+dst); wxLogDebug("Draw arrow %s",src+dst); } else { - if(std::count(gs.squares_hl.begin(), gs.squares_hl.end(), src)){ - gs.squares_hl.erase(std::remove(gs.squares_hl.begin(), gs.squares_hl.end(), src), gs.squares_hl.end()); + if(std::count(squares_hl.begin(), squares_hl.end(), src)){ + squares_hl.erase(std::remove(squares_hl.begin(), squares_hl.end(), src), squares_hl.end()); }else{ - gs.squares_hl.push_back(src); + squares_hl.push_back(src); wxLogDebug("Highlight square %s",src); } } Refresh(); } - } else { - if (is_dragging) { - is_dragging = false; - valid_drag = false; - // Handle drop - REFRESH_MOUSE_LOCATION(); - INIT_CURRENT_SQUARE(); - - if (IsCurrentSquareValid) { - wxLogDebug("Drag end on square (%d,%d)", file, rank); - /// Play the move - wxCommandEvent event(PLAY_MOVE_EVENT, GetId()); - event.SetEventObject(this); - std::string move = ((char)('a' + active_square.x)) + - std::to_string(+active_square.y + 1) + - ((char)('a' + file)) + std::to_string(rank + 1); - event.SetString(move); - ProcessEvent(event); - } else { - // If square not valid just redraw (place piece back to its square) - Refresh(); - } - } - if (event.LeftDown() || event.RightDown()) { - SetFocus(); - REFRESH_MOUSE_LOCATION(); - lastClickX = mouseX; - lastClickY = mouseY; - INIT_CURRENT_SQUARE(); - if (IsCurrentSquareValid) { - active_square.x = file; - active_square.y = rank; - if(event.LeftDown()){ - if (gs.board[(7 - rank) * 8 + file] != ' ') { - wxLogDebug("Drag start on square (%d,%d)", file, rank); - valid_drag = true; - } - } - else { - wxLogDebug("Arrow start on square (%d,%d)", file, rank); - valid_arrow = true; - } - } - } - else if(event.LeftUp()){ - gs.arrows.clear(); - gs.squares_hl.clear(); - Refresh(); - } } - } - // Let GameTableLeftPanel process mouse wheel events: - if (event.GetWheelRotation() != 0) { - event.ResumePropagation(1);event.Skip(); + // In any right up, reset dragging variables + is_dragging = false; + arrow_drag = false; + } else { + // Let GameTableLeftPanel process mouse wheel events: + if (event.GetWheelRotation() != 0) { + event.ResumePropagation(1);event.Skip(); + } } } diff --git a/src/game_tab/left_panel/board/BoardCanvas.hpp b/src/game_tab/left_panel/board/BoardCanvas.hpp index f387c22..a764fee 100644 --- a/src/game_tab/left_panel/board/BoardCanvas.hpp +++ b/src/game_tab/left_panel/board/BoardCanvas.hpp @@ -78,12 +78,13 @@ class BoardCanvas : public wxPanel { Theme *t, *t_captures; wxColour color_arrows; int arrows_offset; - // Board to draw (char version) - std::string board; std::string white_player,black_player; + // Current highlighted squares and arrows: + std::vector<std::string> squares_hl; + std::vector<std::string> arrows; // Various canvas state variables - bool black_side, is_dragging, valid_drag, valid_arrow, is_black_turn; + bool black_side, is_dragging, valid_drag, arrow_drag, is_black_turn; std::uint32_t boardX, boardY, square_width, piece_width, mouseX, mouseY, lastClickX, lastClickY; wxSize canvas_size; |
