1 #include "chess_ui.hpp"
2 
3 #include <signals/slot.hpp>
4 
5 #include <cppurses/system/focus.hpp>
6 
7 #include "no_rules.hpp"
8 #include "player_human.hpp"
9 #include "player_random_ai.hpp"
10 #include "side.hpp"
11 #include "standard_rules.hpp"
12 
13 using namespace chess;
14 using namespace cppurses;
15 
Left_side()16 Left_side::Left_side() {
17     stack.set_name("stack in Left_side");
18     board.set_name("board in Left_side");
19 
20     this->set_name("Left_side");
21     this->width_policy.fixed(26);
22 
23     // Stack
24     stack.set_active_page(0);
25     stack.height_policy.fixed(10);
26     stack.give_focus_on_change(false);
27 
28     // Settings Pane
29     settings.return_btn.clicked.connect(
30         cppurses::slot::set_active_page(stack, 0));
31     settings.show_moves_box.toggled.connect(
32         ::slot::toggle_show_moves(board.chessboard));
33 
34     // Black AI
35     settings.black_ai.cycle_box.add_option("Human").connect(
36         ::slot::set_player<chess::Player_human>(board.chessboard.engine(),
37                                                 Side::Black));
38     settings.black_ai.cycle_box.add_option("Random").connect(
39         ::slot::set_player<Player_random_ai>(board.chessboard.engine(),
40                                              Side::Black));
41     // White AI
42     settings.white_ai.cycle_box.add_option("Human").connect(
43         ::slot::set_player<chess::Player_human>(board.chessboard.engine(),
44                                                 Side::White));
45     settings.white_ai.cycle_box.add_option("Random").connect(
46         ::slot::set_player<Player_random_ai>(board.chessboard.engine(),
47                                              Side::White));
48     // Rulesets
49     settings.ruleset.cycle_box.add_option("Standard")
50         .connect(
51             ::slot::set_ruleset<Standard_rules>(board.chessboard.engine()));
52     settings.ruleset.cycle_box.add_option("No Rules")
53         .connect(::slot::set_ruleset<No_rules>(board.chessboard.engine()));
54 
55     // Reset Button
56     settings.reset_btn.clicked.connect(::slot::reset_game(board.chessboard));
57 
58     // Lower_pane
59     lower_pane.settings_btn.clicked.connect(
60         cppurses::slot::set_active_page(stack, 1));
61     lower_pane.move_input.reset_requested.connect(
62         ::slot::reset_game(board.chessboard));
63     board.chessboard.move_made.connect(
64         ::slot::toggle_status(lower_pane, board.chessboard));
65     board.chessboard.board_reset.connect(
66         [this] { lower_pane.toggle_status(board.chessboard); });
67 }
68 
enable(bool enable,bool post_child_polished_event)69 void Left_side::enable(bool enable, bool post_child_polished_event) {
70     this->enable_and_post_events(enable, post_child_polished_event);
71     stack.enable(enable, post_child_polished_event);
72     if (lower_pane_enabled) {
73         lower_pane.enable(enable, post_child_polished_event);
74     } else {
75         lower_pane.disable(true, post_child_polished_event);
76     }
77 }
78 
Chess_UI()79 Chess_UI::Chess_UI() {
80     this->set_name("Chess_UI - main chess widget");
81 
82     // left_side.settings
83     left_side.settings.hide_log_box.toggled.connect(::slot::toggle_logs(*this));
84 
85     // left_side.board
86     left_side.board.chessboard.move_made.connect(
87         ::slot::post_move_message(right_side));
88     left_side.board.chessboard.move_made.connect(
89         ::slot::toggle_status(right_side, left_side.board.chessboard));
90     left_side.board.chessboard.capture.connect(
91         ::slot::post_capture_message(right_side));
92     left_side.board.chessboard.invalid_move.connect(
93         ::slot::post_invalid_move_message(right_side));
94     left_side.board.chessboard.checkmate.connect(
95         ::slot::post_checkmate_message(right_side));
96     left_side.board.chessboard.check.connect(
97         ::slot::post_check_message(right_side));
98     left_side.board.chessboard.board_reset.connect(
99         [this] { right_side.toggle_status(left_side.board.chessboard); });
100     left_side.board.chessboard.board_reset.connect(
101         [this]() { right_side.chess_log.clear(); });
102 
103     // right_side
104     right_side.settings_btn.clicked.connect(
105         cppurses::slot::set_active_page(left_side.stack, 1));
106     right_side.move_input.reset_requested.connect(
107         ::slot::reset_game(left_side.board.chessboard));
108 }
109 
toggle_logs()110 void Chess_UI::toggle_logs() {
111     left_side.lower_pane_enabled = !left_side.lower_pane_enabled;
112     if (left_side.lower_pane_enabled) {
113         left_side.settings.border.segments.south_west = L'│';
114         left_side.settings.border.segments.north_east = L'╮';
115     } else {
116         left_side.settings.border.segments.south_west = L'╰';
117         left_side.settings.border.segments.north_east = L'─';
118     }
119     this->enable(this->enabled());
120     Focus::clear();
121     this->update();
122 }
123 
enable(bool enable,bool post_child_polished_event)124 void Chess_UI::enable(bool enable, bool post_child_polished_event) {
125     this->enable_and_post_events(enable, post_child_polished_event);
126     left_side.enable(enable, post_child_polished_event);
127     if (left_side.lower_pane_enabled) {
128         right_side.disable(true, post_child_polished_event);
129     } else {
130         right_side.enable(enable, post_child_polished_event);
131     }
132 }
133 
134 namespace slot {
135 
toggle_logs(Chess_UI & cfui)136 sig::Slot<void()> toggle_logs(Chess_UI& cfui) {
137     sig::Slot<void()> slot{[&cfui] { cfui.toggle_logs(); }};
138     slot.track(cfui.destroyed);
139     return slot;
140 }
141 
142 }  // namespace slot
143