ochess/src/game_tab/left_panel/board/BoardCanvas.hpp

136 lines
4.8 KiB
C++
Raw Normal View History

2022-02-23 18:11:55 +01:00
#pragma once
#include "Theme.hpp"
#include "ochess.hpp"
#include <map>
#include <tuple>
#include <utility>
2023-01-07 18:19:59 +01:00
#include <algorithm>
2022-02-23 18:11:55 +01:00
#include <vector>
#include <wx/artprov.h>
2022-12-28 08:38:21 +01:00
#include <wx/dcbuffer.h>
2022-02-23 18:11:55 +01:00
// Local events
wxDECLARE_EVENT(PLAY_MOVE_EVENT, wxCommandEvent);
#define REFRESH_MOUSE_LOCATION() \
{ \
const wxPoint pt = wxGetMousePosition(); \
mouseX = pt.x - this->GetScreenPosition().x; \
mouseY = pt.y - this->GetScreenPosition().y; \
}
#define INIT_CURRENT_SQUARE() \
std::uint32_t file = 7 - (mouseX - boardX) / square_width; \
std::uint32_t rank = (mouseY - boardY) / square_width; \
if (!black_side) { \
file = 7 - file; \
rank = 7 - rank; \
} \
bool IsCurrentSquareValid = file >= 0 && file <= 7 && rank >= 0 && rank <= 7;
#define MOUSE_ON(x, y, width, height) \
(mouseX >= (x) && mouseX <= ((x) + (width)) && mouseY >= (y) && \
mouseY <= ((y) + (height)))
2022-12-30 14:55:59 +01:00
#define CAPTURE_FACTOR 0.35
2022-12-29 18:32:35 +01:00
#define SQUARE_NUM_PADDING 5
#define DEFAULT_ARROW(SRC,DST) {(SRC),(DST),wxNullColour,1}
#define DEFAULT_SQUARE(SQUARE) {(SQUARE),wxNullColour}
2023-01-06 16:01:11 +01:00
2022-02-23 18:11:55 +01:00
typedef std::tuple<short, short, short> ClockTime;
2022-12-29 13:00:23 +01:00
// Drawing buffer (ANIMATIONS)
typedef struct AnimState {
2022-12-29 13:24:23 +01:00
/// @brief Temporary buffer to reduce latency
2022-12-29 13:00:23 +01:00
wxBitmap *buffer;
2023-01-08 12:26:38 +01:00
/// @brief Should animation be played on refresh?
bool animate;
2022-12-29 13:24:23 +01:00
/// @brief Current animated frame
int frame;
/// @brief Total number of frames for the animation
int frames;
/// @brief Animation durations (in ms)
int duration,duration_fast;
/// @brief Animation FPS
std::uint8_t fps;
/// @brief Current animated piece
2022-12-29 13:00:23 +01:00
char piece_moved;
2022-12-29 13:24:23 +01:00
/// @brief Starting point of the animated piece
2022-12-29 13:00:23 +01:00
wxPoint src;
2022-12-29 13:24:23 +01:00
/// @brief Translation vector of the animated piece
2022-12-29 13:00:23 +01:00
wxPoint transVect;
} AnimState;
2023-01-02 10:56:27 +01:00
typedef struct GameState {
typedef struct Arrow {
std::string src,dst;
wxColour color=wxNullColour;
float scale=1;
} Arrow;
typedef struct Square {
std::string square;
wxColour color=wxNullColour;
} Square;
2023-01-02 10:56:27 +01:00
std::string white, black;
std::string board;
std::map<char, std::uint8_t> captures;
std::vector<Square> squares_hl;
std::vector<Arrow> arrows;
2023-01-02 10:56:27 +01:00
bool is_black_turn;
bool mat_black;
bool mat_white;
2023-01-02 12:43:46 +01:00
ClockTime black_time={-1,-1,-1}, white_time={-1,-1,-1};
2023-01-02 10:56:27 +01:00
} GameState;
2022-02-23 18:11:55 +01:00
class BoardCanvas : public wxPanel {
2022-12-28 10:37:57 +01:00
// *t is theme for board+pieces and
// *t_captures is theme for captured pieces (scale down version of t)
2022-02-23 18:11:55 +01:00
Theme *t, *t_captures;
2023-01-09 09:55:20 +01:00
wxColour color_arrows;
int arrows_offset;
std::uint8_t arrow_thickness;
2022-12-30 13:17:06 +01:00
std::string white_player,black_player;
// Current highlighted squares and arrows:
std::vector<GameState::Square> squares_hl;
std::vector<GameState::Arrow> arrows;
2022-12-28 10:37:57 +01:00
// Various canvas state variables
bool black_side, is_dragging, valid_drag, arrow_drag, is_black_turn;
2023-01-06 16:01:11 +01:00
std::uint32_t boardX, boardY, square_width, piece_width, mouseX, mouseY, lastClickX,
2022-02-23 18:11:55 +01:00
lastClickY;
wxSize canvas_size;
wxPoint active_square;
std::map<char, std::uint8_t> captures;
bool frozen,lock_square_size;
2022-12-29 13:24:23 +01:00
// Current animation state
2022-12-29 13:00:23 +01:00
AnimState adata;
2023-01-02 10:56:27 +01:00
GameState gs;
2022-12-28 10:01:32 +01:00
2023-01-06 20:34:14 +01:00
/// @brief Draw an arrow from a source point to a destination point on DC
2023-01-09 18:38:19 +01:00
void DrawArrow(wxDC &dc, int xsrc, int ysrc, int xdst, int ydst, std::uint8_t thickness=50);
2023-01-07 15:15:13 +01:00
/// @brief Draw an arrow with a L shape (such as knight moves)
2023-01-09 18:38:19 +01:00
void DrawLArrow(wxDC &dc, int xsrc, int ysrc, int xdst, int ydst, bool flip=false, std::uint8_t thickness=50);
2023-01-06 20:34:14 +01:00
2022-02-23 18:11:55 +01:00
public:
BoardCanvas(wxFrame *parent);
BoardCanvas(wxFrame *parent,std::uint32_t square_width, bool frozen);
~BoardCanvas();
2022-02-23 18:11:55 +01:00
void ApplyPreferences();
2023-01-08 17:27:22 +01:00
/// @brief Draw current state of the board (GameState) on the given wxDC
2022-12-28 10:37:57 +01:00
void DrawBoard(wxDC &dc);
2022-02-23 18:11:55 +01:00
void OnPaint(wxPaintEvent &event);
void MouseEvent(wxMouseEvent &event);
2023-01-08 17:27:22 +01:00
/// @brief Zomm in/out on the canvas
2022-02-23 18:11:55 +01:00
void Zoom(std::int32_t zoom);
2023-01-08 17:27:22 +01:00
/// @brief Change between black side and white side
2022-02-23 18:11:55 +01:00
void Swap();
2023-01-08 17:27:22 +01:00
/// @brief Display a position on the canvas
2023-01-02 11:36:13 +01:00
void SetupBoard(const GameState &new_gs);
2023-01-08 17:27:22 +01:00
/// @brief Animate a piece front src to dst from current position
2023-01-02 12:43:46 +01:00
void Animate(const GameState &new_gs, const std::string &src, const std::string &dst,bool faster);
2023-01-08 17:27:22 +01:00
/// @brief Setup clock on displayed on the canvas
2022-02-23 18:11:55 +01:00
void SetClockTime(short hours, short min, short sec, bool IsBlack);
};