00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "sys.h"
00027 #include <iomanip>
00028 #include <gtk/gtk.h>
00029 #include <gtkmm/box.h>
00030 #include <gtkmm/main.h>
00031 #include <gtkmm/window.h>
00032 #include <gtkmm/stock.h>
00033 #include <gtkmm/uimanager.h>
00034 #include <gtkmm/radioaction.h>
00035 #include <gtkmm/menu.h>
00036 #include <gtkmm/iconfactory.h>
00037 #include <cstring>
00038 #include <stack>
00039 #include <fstream>
00040 #include "ChessPositionWidget.h"
00041 #include "debug.h"
00042 #include "ChessNotation.h"
00043
00044 enum mode_type {
00045 mode_show_candidates,
00046 mode_show_reachables,
00047 mode_show_attacked,
00048 mode_show_defendables,
00049 mode_show_defended_black,
00050 mode_show_defended_white,
00051 mode_show_moves,
00052 mode_popup_menu
00053 };
00054
00055
00056 class MyChessboardWidget : public cwmm::ChessPositionWidget {
00057 private:
00058 gint M_arrow_begin_col;
00059 gint M_arrow_begin_row;
00060 ColorHandle M_colors[10];
00061 gpointer M_en_passant_arrow;
00062 cwchess::Index M_en_passant_arrow_index;
00063 mode_type M_mode;
00064
00065 protected:
00066 virtual void draw_hud_layer(cairo_t* cr, gint sside, guint hud);
00067 virtual bool on_button_press(gint col, gint row, GdkEventButton const* event);
00068 virtual bool on_button_release(gint col, gint row, GdkEventButton const* event);
00069
00070 public:
00071 void on_menu_mode_editposition(void)
00072 {
00073 if (get_widget_mode() != mode_edit_position)
00074 set_widget_mode(mode_edit_position);
00075 }
00076 void on_menu_mode_editgame(void)
00077 {
00078 if (get_widget_mode() != mode_edit_game)
00079 set_widget_mode(mode_edit_game);
00080 }
00081 void on_menu_mode_showcandidates(void) { M_mode = mode_show_candidates; }
00082 void on_menu_mode_showreachables(void) { M_mode = mode_show_reachables; }
00083 void on_menu_mode_showattacked(void) { M_mode = mode_show_attacked; }
00084 void on_menu_mode_showdefendables(void) { M_mode = mode_show_defendables; }
00085 void on_menu_mode_showdefended_black(void) { M_mode = mode_show_defended_black; }
00086 void on_menu_mode_showdefended_white(void) { M_mode = mode_show_defended_white; }
00087 void on_menu_mode_showmoves(void) { M_mode = mode_show_moves; }
00088 void on_menu_mode_placepieces(void) { M_mode = mode_popup_menu; }
00089
00090 void picked_up(cwchess::Index const& index, cwchess::ChessPosition const& chess_position);
00091 void dropped(gint col, gint row, cwchess::ChessPosition const& chess_position);
00092 void moved(cwchess::Move const& move, cwchess::ChessPosition const& previous_position, cwchess::ChessPosition const& current_position);
00093 void illegal(cwchess::Move const& move, cwchess::ChessPosition const& chess_position);
00094
00095 public:
00096 MyChessboardWidget(Gtk::Window* drawable);
00097
00098 private:
00099 void show_reachables(int col, int row, mode_type mode);
00100 void update_en_passant_arrow(void);
00101 void show_pinning();
00102
00103 private:
00104 enum colors_t {
00105 background = 0,
00106 red,
00107 green,
00108 blue,
00109 brown
00110 };
00111
00112 private:
00113 void init_colors(void);
00114 ColorHandle get_color_handle(int index, colors_t color);
00115 };
00116
00117 MyChessboardWidget::MyChessboardWidget(Gtk::Window* drawable) : cwmm::ChessPositionWidget(drawable), M_en_passant_arrow(NULL)
00118 {
00119 init_colors();
00120 }
00121
00122 struct rgb_t { gdouble red; gdouble green; gdouble blue; };
00123
00124 rgb_t mix(rgb_t col1, gdouble alpha1, rgb_t col2, gdouble alpha2)
00125 {
00126 rgb_t result;
00127 result.red = (col1.red * alpha1 + col2.red * alpha2) / sqrt(alpha1 * alpha1 + alpha2 * alpha2);
00128 result.green = (col1.green * alpha1 + col2.green * alpha2) / sqrt(alpha1 * alpha1 + alpha2 * alpha2);
00129 result.blue = (col1.blue * alpha1 + col2.blue * alpha2) / sqrt(alpha1 * alpha1 + alpha2 * alpha2);
00130 return result;
00131 }
00132
00133 void MyChessboardWidget::init_colors(void)
00134 {
00135 gdouble alpha = 0.5;
00136
00137 rgb_t rgb_red = { 1.0, 0, 0 };
00138 rgb_t rgb_green = { 0, 1.0, 0 };
00139 rgb_t rgb_blue = { 0, 0, 1.0 };
00140 rgb_t rgb_brown = { 1.0, 0, 1.0 };
00141
00142 GdkColor dark_background;
00143 GdkColor light_background;
00144
00145 get_dark_square_color(dark_background);
00146 get_light_square_color(light_background);
00147
00148 rgb_t rgb_background_dark = { dark_background.red / 65535.0, dark_background.green / 65535.0, dark_background.blue / 65535.0 };
00149 rgb_t rgb_background_light = { light_background.red / 65535.0, light_background.green / 65535.0, light_background.blue / 65535.0 };
00150
00151 rgb_t tmp;
00152
00153 int const dark = 0;
00154 int const light = 1;
00155 M_colors[2 * background + dark] = 0;
00156 M_colors[2 * background + light] = 0;
00157 tmp = mix(rgb_background_dark, 1.0, rgb_red, alpha);
00158 M_colors[2 * red + dark] = allocate_color_handle_rgb(tmp.red, tmp.green, tmp.blue);
00159 tmp = mix(rgb_background_light, 1.0, rgb_red, alpha);
00160 M_colors[2 * red + light] = allocate_color_handle_rgb(tmp.red, tmp.green, tmp.blue);
00161 tmp = mix(rgb_background_dark, 1.0, rgb_green, alpha);
00162 M_colors[2 * green + dark] = allocate_color_handle_rgb(tmp.red, tmp.green, tmp.blue);
00163 tmp = mix(rgb_background_light, 1.0, rgb_green, alpha);
00164 M_colors[2 * green + light] = allocate_color_handle_rgb(tmp.red, tmp.green, tmp.blue);
00165 tmp = mix(rgb_background_dark, 1.0, rgb_blue, alpha);
00166 M_colors[2 * blue + dark] = allocate_color_handle_rgb(tmp.red, tmp.green, tmp.blue);
00167 tmp = mix(rgb_background_light, 1.0, rgb_blue, alpha);
00168 M_colors[2 * blue + light] = allocate_color_handle_rgb(tmp.red, tmp.green, tmp.blue);
00169 tmp = mix(rgb_background_dark, 1.0, rgb_brown, alpha);
00170 M_colors[2 * brown + dark] = allocate_color_handle_rgb(tmp.red, tmp.green, tmp.blue);
00171 tmp = mix(rgb_background_light, 1.0, rgb_brown, alpha);
00172 M_colors[2 * brown + light] = allocate_color_handle_rgb(tmp.red, tmp.green, tmp.blue);
00173 }
00174
00175 MyChessboardWidget::ColorHandle MyChessboardWidget::get_color_handle(int index, colors_t color)
00176 {
00177 int const dark = 0;
00178 int const light = 1;
00179 int offset = ((index & 1) == ((index >> 3) & 1)) ? dark : light;
00180 return M_colors[2 * color + offset];
00181 }
00182
00183 void MyChessboardWidget::show_pinning(void)
00184 {
00185 using namespace cwchess;
00186 BitBoard bb1 = attackers(black) | attackers(white);
00187 BitBoard bb2 = pinned(black) | pinned(white);
00188 ColorHandle handles[64];
00189 std::memset(handles, 0, sizeof(handles));
00190 for (Index index = index_begin; index != index_end; ++index)
00191 if (bb1.test(index) && !bb2.test(index))
00192 handles[index()] = get_color_handle(index(), blue);
00193 else if (bb2.test(index) && !bb1.test(index))
00194 handles[index()] = get_color_handle(index(), red);
00195 else if (bb1.test(index) && bb2.test(index))
00196 handles[index()] = get_color_handle(index(), brown);
00197 set_background_colors(handles);
00198 }
00199
00200 void MyChessboardWidget::show_reachables(int col, int row, mode_type mode)
00201 {
00202 using namespace cwchess;
00203
00204 Index index(col, row);
00205 BitBoard bb;
00206 switch (mode)
00207 {
00208 case mode_show_candidates:
00209 bb = candidates(index);
00210 Dout(dc::notice, "candidates: 0x" << std::hex << bb() << std::dec << " " << bb);
00211 break;
00212 case mode_show_reachables:
00213 bb = reachables(index);
00214 Dout(dc::notice, "reachables: 0x" << std::hex << bb() << std::dec << " " << bb);
00215 break;
00216 case mode_show_attacked:
00217 bb = reachables(index, true);
00218 Dout(dc::notice, "attacked reachables: 0x" << std::hex << bb() << std::dec << " " << bb);
00219 break;
00220 case mode_show_defendables:
00221 {
00222 bool battery = false;
00223 bb = defendables(piece_at(index).code(), index, battery);
00224 Dout(dc::notice, "defendables: 0x" << std::hex << bb() << std::dec << " " << bb);
00225 break;
00226 }
00227 case mode_show_defended_black:
00228 {
00229 bb = get_defended()[black].any();
00230 for (int row = 7; row >= 0; --row)
00231 {
00232 for (int col = 0; col <= 7; ++col)
00233 {
00234 Index i(col, row);
00235 std::cout << get_defended()[black].count(i) << " ";
00236 }
00237 std::cout << '\n';
00238 }
00239 break;
00240 }
00241 case mode_show_defended_white:
00242 {
00243 bb = get_defended()[white].any();
00244 for (int row = 7; row >= 0; --row)
00245 {
00246 for (int col = 0; col <= 7; ++col)
00247 {
00248 Index i(col, row);
00249 std::cout << get_defended()[white].count(i) << " ";
00250 }
00251 std::cout << '\n';
00252 }
00253 break;
00254 }
00255 default:
00256 {
00257 cwchess::Color color(to_move());
00258 cwchess::Piece piece(piece_at(col, row));
00259 if (!piece.code().is_nothing())
00260 to_move(piece.color());
00261 bb = moves(index);
00262 if (get_widget_mode() == mode_edit_game)
00263 to_move(color);
00264 Dout(dc::notice, "moves: 0x" << std::hex << bb() << std::dec << " " << bb);
00265 break;
00266 }
00267 }
00268 if (mode != mode_show_defended_black && mode != mode_show_defended_white)
00269 disable_hud_layer(1);
00270 ColorHandle handles[64];
00271 std::memset(handles, 0, sizeof(handles));
00272 for (Index index = index_begin; index != index_end; ++index)
00273 if (bb.test(index))
00274 handles[index()] = get_color_handle(index(), red);
00275 set_background_colors(handles);
00276 update_en_passant_arrow();
00277 }
00278
00279 void MyChessboardWidget::update_en_passant_arrow(void)
00280 {
00281 cwchess::EnPassant const& en_passant(this->en_passant());
00282 if (en_passant.exists())
00283 {
00284 if (M_en_passant_arrow_index != en_passant.index())
00285 {
00286 remove_arrow(M_en_passant_arrow);
00287 M_en_passant_arrow = NULL;
00288 }
00289 if (!M_en_passant_arrow)
00290 {
00291 cwchess::Index from(en_passant.from_index());
00292 cwchess::Index to(en_passant.pawn_index());
00293 GdkColor color = { 0, 0, 65535, 65535 };
00294 M_en_passant_arrow = add_arrow(from.col(), from.row(), to.col(), to.row(), color);
00295 M_en_passant_arrow_index = en_passant.index();
00296 }
00297 }
00298 else if (M_en_passant_arrow)
00299 {
00300 remove_arrow(M_en_passant_arrow);
00301 M_en_passant_arrow = NULL;
00302 }
00303 }
00304
00305 bool MyChessboardWidget::on_button_press(gint col, gint row, GdkEventButton const* event)
00306 {
00307
00308 if (event->type == GDK_2BUTTON_PRESS)
00309 return false;
00310 if (event->button == 2)
00311 {
00312
00313 if (col != -1)
00314 {
00315 show_cursor();
00316
00317 set_marker_color(col, row, 1);
00318 M_arrow_begin_col = col;
00319 M_arrow_begin_row = row;
00320 }
00321 }
00322 else if (event->button == 3)
00323 {
00324
00325 if (col != -1)
00326 {
00327 switch (M_mode)
00328 {
00329 case mode_show_candidates:
00330 case mode_show_reachables:
00331 case mode_show_attacked:
00332 case mode_show_defendables:
00333 case mode_show_defended_black:
00334 case mode_show_defended_white:
00335 case mode_show_moves:
00336 show_reachables(col, row, M_mode);
00337 show_cursor();
00338 return true;
00339 case mode_popup_menu:
00340
00341 break;
00342 }
00343 show_cursor();
00344 }
00345 }
00346 else if (event->button == 10)
00347 {
00348 enable_hud_layer(1);
00349 show_reachables(0, 0, mode_show_defended_white);
00350 }
00351 return false;
00352 }
00353
00354 bool MyChessboardWidget::on_button_release(gint col, gint row, GdkEventButton const* event)
00355 {
00356 hide_cursor();
00357 if (event->button == 2)
00358 {
00359 GdkColor color = { 0, 0, 0, 65535 };
00360
00361 set_marker_color(M_arrow_begin_col, M_arrow_begin_row, 0);
00362
00363 if ((M_arrow_begin_col != col || M_arrow_begin_row != row)&&
00364 is_inside_board(M_arrow_begin_col, M_arrow_begin_row)&&
00365 is_inside_board(col, row))
00366 add_arrow(M_arrow_begin_col, M_arrow_begin_row, col, row, color);
00367 }
00368 return false;
00369 }
00370
00371 void MyChessboardWidget::moved(cwchess::Move const& move, cwchess::ChessPosition const& previous_position, cwchess::ChessPosition const& UNUSED(current_position))
00372 {
00373 DoutEntering(dc::notice, "MyChessboardWidget::moved(" << cwchess::ChessNotation(previous_position, move) << ", ...)");
00374
00375 update_en_passant_arrow();
00376 }
00377
00378 void MyChessboardWidget::illegal(cwchess::Move const& move, cwchess::ChessPosition const& UNUSED(chess_position))
00379 {
00380 DoutEntering(dc::notice, "MyChessboardWidget::illegal(" << cwchess::ChessNotation(*this, move) << ", ...)");
00381 }
00382
00383 void MyChessboardWidget::picked_up(cwchess::Index const& index, cwchess::ChessPosition const& UNUSED(chess_position))
00384 {
00385 DoutEntering(dc::notice, "MyChessboardWidget::picked_up(" << cwchess::ChessNotation(*this, index) << ", ...)");
00386 if (get_widget_mode() == mode_edit_game)
00387 {
00388
00389 show_reachables(index.col(), index.row(), mode_show_moves);
00390 show_cursor();
00391 }
00392 else if (get_widget_mode() == mode_edit_position)
00393
00394 show_pinning();
00395 }
00396
00397 void MyChessboardWidget::dropped(gint col, gint row, cwchess::ChessPosition const& UNUSED(chess_position))
00398 {
00399 DoutEntering(dc::notice, "MyChessboardWidget::dropped(" << col << ", " << row << ", ...)");
00400
00401 hide_cursor();
00402 show_pinning();
00403 }
00404
00405 void MyChessboardWidget::draw_hud_layer(cairo_t* cr, gint sside, guint hud)
00406 {
00407 DoutEntering(dc::notice, "draw_hud_layer(" << cr << ", " << sside << ", " << hud << ")");
00408 cairo_text_extents_t extents;
00409 cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
00410 cairo_set_font_size(cr, 20);
00411 cairo_text_extents(cr, "3",& extents);
00412 double x, y;
00413 for (int col = 0; col < 8; ++col)
00414 {
00415 for (int row = 0; row < 8; ++row)
00416 {
00417 static char const* number[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
00418 cwchess::Index i(col, row);
00419 int count = get_defended()[cwchess::white].count(i);
00420 char const* utf8 = number[count % 10];
00421 x = col * sside + 1;
00422 y = (7 - row) * sside + extents.height + 2;
00423 cairo_move_to(cr, x, y);
00424 if (count > 9)
00425 cairo_show_text(cr, number[1]);
00426 cairo_show_text(cr, utf8);
00427 }
00428 }
00429 }
00430
00431
00432 class GtkTest : public Gtk::Window {
00433 public:
00434 GtkTest(int width, int height);
00435 virtual ~GtkTest() { }
00436
00437
00438 MyChessboardWidget& chessboard_widget(void) { return m_chessboard_widget; }
00439 MyChessboardWidget const& chessboard_widget(void) const { return m_chessboard_widget; }
00440
00441 private:
00442 void setup_menu(void);
00443
00444 protected:
00445
00446 virtual void on_menu_file_quit();
00447 virtual void on_menu_file_open();
00448 virtual void on_menu_file_save();
00449 virtual void on_menu_file_new();
00450 virtual void on_menu_file_clear();
00451 virtual void on_menu_file_export();
00452 virtual void on_menu_file_undo();
00453 virtual void on_menu_file_flip();
00454 virtual void on_menu_mode_editposition(void)
00455 {
00456 m_chessboard_widget.on_menu_mode_editposition();
00457 if (m_chessboard_widget.get_widget_mode() == cwmm::ChessPositionWidget::mode_edit_game)
00458 M_ModePlacePieces_action->set_active(true);
00459 m_chessboard_widget.set_widget_mode(cwmm::ChessPositionWidget::mode_edit_position);
00460 }
00461 virtual void on_menu_mode_editgame(void)
00462 {
00463 m_chessboard_widget.on_menu_mode_editgame();
00464 m_chessboard_widget.set_widget_mode(cwmm::ChessPositionWidget::mode_edit_game);
00465 }
00466
00467 void moved(cwchess::Move const& move, cwchess::ChessPosition const& previous_position, cwchess::ChessPosition const& current_position);
00468
00469
00470 Gtk::VBox m_vbox;
00471 MyChessboardWidget m_chessboard_widget;
00472
00473
00474 Glib::RefPtr<Gtk::UIManager> m_refUIManager;
00475 Glib::RefPtr<Gtk::ActionGroup> m_refActionGroup;
00476 Glib::RefPtr<Gtk::RadioAction> M_ModePlacePieces_action;
00477 Glib::RefPtr<Gtk::RadioAction> M_ModeEditPosition_action;
00478
00479 std::stack<cwchess::ChessPosition> M_history;
00480 };
00481
00482 void GtkTest::moved(cwchess::Move const& move, cwchess::ChessPosition const& previous_position, cwchess::ChessPosition const& UNUSED(current_position))
00483 {
00484 DoutEntering(dc::notice, "GtkTest::moved(" << cwchess::ChessNotation(previous_position, move) << ", ...)");
00485 M_history.push(previous_position);
00486 }
00487
00488 GtkTest::GtkTest(int width, int height) : m_vbox(FALSE, 0), m_chessboard_widget(this)
00489 {
00490
00491 set_title("ChessboardWidget Test");
00492
00493
00494 set_border_width(10);
00495
00496
00497 set_default_size(width, height);
00498
00499
00500 add(m_vbox);
00501
00502
00503 setup_menu();
00504
00505
00506 m_vbox.add(m_chessboard_widget);
00507
00508
00509 show_all_children();
00510
00511
00512 m_chessboard_widget.signal_moved().connect(sigc::mem_fun(this,& GtkTest::moved));
00513
00514
00515 m_chessboard_widget.signal_moved().connect(sigc::mem_fun(m_chessboard_widget,& MyChessboardWidget::moved));
00516
00517
00518 m_chessboard_widget.signal_illegal().connect(sigc::mem_fun(m_chessboard_widget,& MyChessboardWidget::illegal));
00519
00520
00521 m_chessboard_widget.signal_picked_up().connect(sigc::mem_fun(m_chessboard_widget,& MyChessboardWidget::picked_up));
00522 m_chessboard_widget.signal_dropped().connect(sigc::mem_fun(m_chessboard_widget,& MyChessboardWidget::dropped));
00523 }
00524
00525 void GtkTest::on_menu_file_quit(void)
00526 {
00527 hide();
00528 }
00529
00530 void GtkTest::on_menu_file_save(void)
00531 {
00532 std::ofstream file;
00533 file.open("FEN.out");
00534 file << chessboard_widget().FEN() << std::endl;
00535 file.close();
00536 }
00537
00538 void GtkTest::on_menu_file_undo(void)
00539 {
00540 if (M_history.empty())
00541 return;
00542 chessboard_widget().set_position(M_history.top());
00543 M_history.pop();
00544 }
00545
00546 void GtkTest::on_menu_file_new(void)
00547 {
00548 chessboard_widget().initial_position();
00549 }
00550
00551 void GtkTest::on_menu_file_clear(void)
00552 {
00553 chessboard_widget().clear();
00554 Dout(dc::notice, "Calling M_ModeEditPosition_action->set_active(true)");
00555 M_ModeEditPosition_action->set_active(true);
00556 }
00557
00558 void GtkTest::on_menu_file_flip(void)
00559 {
00560 chessboard_widget().set_flip_board(!chessboard_widget().get_flip_board());
00561 }
00562
00563 void GtkTest::on_menu_file_export(void)
00564 {
00565 using namespace cwchess;
00566 std::cout << " chess_position.load_FEN(\"" << chessboard_widget().FEN() << "\");\n";
00567 std::cout << " static mask_t moves1[] = {\n";
00568 int color_count = 0;
00569 bool first = true;
00570 for (Color color(black); color_count < 2; ++color_count, color = white)
00571 {
00572 for (PieceIterator piece_iter = chessboard_widget().piece_begin(color); piece_iter != chessboard_widget().piece_end(); ++piece_iter)
00573 {
00574 if (first)
00575 {
00576 std::cout << " ";
00577 first = false;
00578 }
00579 else
00580 std::cout << ", ";
00581 std::cout << std::hex << "0x" << chessboard_widget().moves(piece_iter.index())() << std::dec;
00582 }
00583 }
00584 std::cout << "\n };" << std::endl;
00585 }
00586
00587 void GtkTest::on_menu_file_open(void)
00588 {
00589 std::ifstream file;
00590 file.open("FEN.out");
00591 std::string fen;
00592 std::getline(file, fen);
00593 file.close();
00594 chessboard_widget().load_FEN(fen);
00595 }
00596
00597 void GtkTest::setup_menu(void)
00598 {
00599
00600 m_refActionGroup = Gtk::ActionGroup::create();
00601
00602
00603 m_refActionGroup->add(Gtk::Action::create("FileMenu", "File"));
00604
00605 m_refActionGroup->add(Gtk::Action::create("FileQuit", Gtk::Stock::QUIT),
00606 sigc::mem_fun(*this,& GtkTest::on_menu_file_quit));
00607
00608 m_refActionGroup->add(Gtk::Action::create("FileOpen", Gtk::Stock::OPEN, "Load", "Load position from file FEN.out"),
00609 sigc::mem_fun(*this,& GtkTest::on_menu_file_open));
00610
00611 m_refActionGroup->add(Gtk::Action::create("FileSave", Gtk::Stock::SAVE, "Save", "Save position to file FEN.out"),
00612 sigc::mem_fun(*this,& GtkTest::on_menu_file_save));
00613
00614 m_refActionGroup->add(Gtk::Action::create("FileConvert", Gtk::Stock::CONVERT, "Export"),
00615 sigc::mem_fun(*this,& GtkTest::on_menu_file_export));
00616
00617 m_refActionGroup->add(Gtk::Action::create("FileClear", Gtk::Stock::CLEAR, "Clear", "Remove all pieces and switch to Mode 'Edit position'."),
00618 sigc::mem_fun(*this,& GtkTest::on_menu_file_clear));
00619
00620 m_refActionGroup->add(Gtk::Action::create("FileNew", Gtk::Stock::NEW, "New", "Set up initial position."),
00621 sigc::mem_fun(*this,& GtkTest::on_menu_file_new));
00622
00623 m_refActionGroup->add(Gtk::Action::create("FileUndo", Gtk::Stock::UNDO, "Undo"),
00624 sigc::mem_fun(*this,& GtkTest::on_menu_file_undo));
00625
00626 m_refActionGroup->add(Gtk::Action::create("FileFlip", Gtk::Stock::REFRESH, "Flip"),
00627 sigc::mem_fun(*this,& GtkTest::on_menu_file_flip));
00628
00629
00630 m_refActionGroup->add(Gtk::Action::create("ModeMenu", "Mode"));
00631 Gtk::RadioAction::Group group_widget_mode;
00632 Gtk::RadioAction::Group group_rightclick_mode;
00633
00634 M_ModeEditPosition_action = Gtk::RadioAction::create(group_widget_mode, "ModeEditPosition", "Edit position");
00635 m_refActionGroup->add(M_ModeEditPosition_action, sigc::mem_fun(*this,& GtkTest::on_menu_mode_editposition));
00636
00637 Glib::RefPtr<Gtk::RadioAction> ModeEditGame_action(Gtk::RadioAction::create(group_widget_mode, "ModeEditGame", "Edit game"));
00638 m_refActionGroup->add(ModeEditGame_action, sigc::mem_fun(*this,& GtkTest::on_menu_mode_editgame));
00639
00640 m_refActionGroup->add(Gtk::RadioAction::create(group_rightclick_mode, "ModeShowCandidates", "Show candidates"),
00641 sigc::mem_fun(m_chessboard_widget,& MyChessboardWidget::on_menu_mode_showcandidates));
00642
00643 m_refActionGroup->add(Gtk::RadioAction::create(group_rightclick_mode, "ModeShowReachables", "Show reachables"),
00644 sigc::mem_fun(m_chessboard_widget,& MyChessboardWidget::on_menu_mode_showreachables));
00645
00646 m_refActionGroup->add(Gtk::RadioAction::create(group_rightclick_mode, "ModeShowAttacked", "Show attacked"),
00647 sigc::mem_fun(m_chessboard_widget,& MyChessboardWidget::on_menu_mode_showattacked));
00648
00649 m_refActionGroup->add(Gtk::RadioAction::create(group_rightclick_mode, "ModeShowDefendables", "Show defendables"),
00650 sigc::mem_fun(m_chessboard_widget,& MyChessboardWidget::on_menu_mode_showdefendables));
00651
00652 m_refActionGroup->add(Gtk::RadioAction::create(group_rightclick_mode, "ModeShowDefendedBlack", "Show defended by black"),
00653 sigc::mem_fun(m_chessboard_widget,& MyChessboardWidget::on_menu_mode_showdefended_black));
00654
00655 m_refActionGroup->add(Gtk::RadioAction::create(group_rightclick_mode, "ModeShowDefendedWhite", "Show defended by white"),
00656 sigc::mem_fun(m_chessboard_widget,& MyChessboardWidget::on_menu_mode_showdefended_white));
00657
00658 Glib::RefPtr<Gtk::RadioAction> ModeShowMoves_action(Gtk::RadioAction::create(group_rightclick_mode, "ModeShowMoves", "Show moves"));
00659 m_refActionGroup->add(ModeShowMoves_action, sigc::mem_fun(m_chessboard_widget,& MyChessboardWidget::on_menu_mode_showmoves));
00660
00661 M_ModePlacePieces_action = Gtk::RadioAction::create(group_rightclick_mode, "ModePlacePieces", "Place pieces");
00662 m_refActionGroup->add(M_ModePlacePieces_action, sigc::mem_fun(m_chessboard_widget,& MyChessboardWidget::on_menu_mode_placepieces));
00663
00664
00665 #if 1
00666 Dout(dc::notice, "Calling ModeEditGame_action->set_active(true)");
00667 ModeEditGame_action->set_active(true);
00668 Dout(dc::notice, "Calling ModeShowMoves_action->set_active(true)");
00669 ModeShowMoves_action->set_active(true);
00670 #else
00671 Dout(dc::notice, "Calling M_ModeEditPosition_action->set_active(true)");
00672 M_ModeEditPosition_action->set_active(true);
00673 Dout(dc::notice, "Calling M_ModePlacePieces_action->set_active(true)");
00674 M_ModePlacePieces_action->set_active(true);
00675 #endif
00676
00677
00678 m_refUIManager = Gtk::UIManager::create();
00679 m_refUIManager->insert_action_group(m_refActionGroup);
00680
00681
00682 add_accel_group(m_refUIManager->get_accel_group());
00683
00684
00685 Glib::ustring ui_info =
00686 "<ui>"
00687 " <menubar name='MenuBar'>"
00688 " <menu action='FileMenu'>"
00689 " <menuitem action='FileOpen'/>"
00690 " <menuitem action='FileSave'/>"
00691 " <menuitem action='FileQuit'/>"
00692 " </menu>"
00693 " <menu action='ModeMenu'>"
00694 " <menuitem action='ModeEditPosition'/>"
00695 " <menuitem action='ModeEditGame'/>"
00696 " <separator/>"
00697 " <menuitem action='ModeShowCandidates'/>"
00698 " <menuitem action='ModeShowReachables'/>"
00699 " <menuitem action='ModeShowAttacked'/>"
00700 " <menuitem action='ModeShowDefendables'/>"
00701 " <menuitem action='ModeShowDefendedBlack'/>"
00702 " <menuitem action='ModeShowDefendedWhite'/>"
00703 " <menuitem action='ModeShowMoves'/>"
00704 " <menuitem action='ModePlacePieces'/>"
00705 " </menu>"
00706 " </menubar>"
00707 " <toolbar name='ToolBar'>"
00708 " <toolitem action='FileQuit'/>"
00709 " <toolitem action='FileOpen'/>"
00710 " <toolitem action='FileSave'/>"
00711 " <toolitem action='FileNew'/>"
00712 " <toolitem action='FileClear'/>"
00713 " <toolitem action='FileConvert'/>"
00714 " <toolitem action='FileUndo'/>"
00715 " <toolitem action='FileFlip'/>"
00716 " </toolbar>"
00717 "</ui>";
00718
00719 #ifdef GLIBMM_EXCEPTIONS_ENABLED
00720 try
00721 {
00722 m_refUIManager->add_ui_from_string(ui_info);
00723 }
00724 catch(const Glib::Error& ex)
00725 {
00726 std::cerr << "building menus failed: " << ex.what();
00727 }
00728 #else
00729 std::auto_ptr<Glib::Error> ex;
00730 m_refUIManager->add_ui_from_string(ui_info, ex);
00731 if(ex.get())
00732 {
00733 std::cerr << "building menus failed: " << ex->what();
00734 }
00735 #endif // GLIBMM_EXCEPTIONS_ENABLED
00736
00737
00738 Gtk::Widget* pMenubar = m_refUIManager->get_widget("/MenuBar");
00739 if(pMenubar)
00740 m_vbox.pack_start(*pMenubar, Gtk::PACK_SHRINK);
00741
00742 Gtk::Widget* pToolbar = m_refUIManager->get_widget("/ToolBar") ;
00743 if(pToolbar)
00744 m_vbox.pack_start(*pToolbar, Gtk::PACK_SHRINK);
00745 }
00746
00747 int main(int argc, char* argv[])
00748 {
00749 using namespace cwchess;
00750
00751 Debug(debug::init());
00752 Dout(dc::notice, "Entered main()");
00753
00754 Gtk::Main kit(argc, argv);
00755
00756
00757 GtkTest application(500, 532);
00758
00759
00760 MyChessboardWidget& chessboard_widget(application.chessboard_widget());
00761
00762 ChessPosition chess_position;
00763
00764 chess_position.load_FEN("rnbqkbnr/4p1pp/1p6/p1p1PpP1/1P1p4/2P5/P2P1P1P/RNBQKBNR w KQkq f6 0 7");
00765 #if 0
00766 std::ifstream file;
00767 file.open("FEN.out");
00768 std::string fen;
00769 std::getline(file, fen);
00770 file.close();
00771 chess_position.load_FEN(fen);
00772 #endif
00773
00774
00775 chessboard_widget.set_position(chess_position);
00776
00777
00778 uint32_t border_color_html = 0x597359;
00779 GdkColor brown = { 0, (border_color_html & 0xff0000) >> 8, (border_color_html & 0xff00), (border_color_html & 0xff) << 8 };
00780 chessboard_widget.set_border_color(brown);
00781
00782
00783 Gtk::Main::run(application);
00784
00785 return 0;
00786 }