Сохранить Fl: значение кнопки из обратного вызова (FLTK)

Я пытаюсь написать программу, имитирующую шахматную партию с библиотекой FLTK.

Моя проблема в том, что я хочу выполнить два обратных вызова для двухмерного массива кнопок, я хочу нажать кнопку, затем нажать другую кнопку, и при нажатии второй кнопки метка первой кнопки переключается на метку второй кнопку, а затем удалите метку первой кнопки.

Я чувствую, что мне нужно как-то сохранить значение первой нажатой кнопки, например, если я нажимаю FBoard [1] [2], у меня есть переменная, которая равна FBoard [1] [2], и открываю второй щелчок заменяет метку FBoard [1] [2] пустой (при условии, что FBoard [1] [2] - это ячейка на доске, на которой есть фигура. Но я не уверен, как и даже если это правильный подход.

Вот файл cpp:

  #include"Window.h"
  #include"ChessBoard.h"

  const char *  DisplayWindow::LastLabel;
  bool   DisplayWindow::flag;
  DisplayWindow::DisplayWindow(int width, int height, const char*)
  :Fl_Window(800, 650, "Chess"){   


                for (int X = 0; X <= 7; ++X){
                    for (int Y = 0; Y <= 7; ++Y){
                    // Leaves all positions that arent occupied by
                    // a figure at the start of the game blank
                        FBoard[X][Y] = new Fl_Button(10 + 50*Y, 100 + 50*X, 50, 50,"");
                        FBoard[X][Y]->callback((Fl_Callback*)DisplayWindow::ChangeButton);
                    }
                }

         flag = false;
         MakeLabel(); 
         LabelButton(); 
         show();
}


 DisplayWindow::~DisplayWindow(){}

 void DisplayWindow::MakeLabel(){

  for (int X = 0; X <= 7; ++X){
    for (int Y = 0; Y <= 7; ++Y){

            LBoard[X][Y] = ("  ");
    }
  }

  for (int X = 0; X <= 7; ++X){ 
        LBoard[1][X] = ("WP");
    // Occupies second row with white pawns

  }
    LBoard[0][0] = ("WR");
    LBoard[0][1] = ("WH");
    LBoard[0][2] = ("WB");
    LBoard[0][3] = ("WQ");
    LBoard[0][4] = ("WK");
    LBoard[0][5] = ("WB");
    LBoard[0][6] = ("WH");
    LBoard[0][7] = ("WR");


  for (int X = 0; X <= 7; ++X){
        LBoard[6][X] = ("BP");
  }

    LBoard[7][0] = ("BR");
    LBoard[7][1] = ("BH");
    LBoard[7][2] = ("BB");
    LBoard[7][3] = ("BQ");
    LBoard[7][4] = ("BK");
    LBoard[7][5] = ("BB");
    LBoard[7][6] = ("BH");
    LBoard[7][7] = ("BR");
}


void DisplayWindow::LabelButton(){

    for (int X = 0; X <= 7; ++X){ 
        FBoard[1][X]->label(LBoard[1][X]);
    // Occupies second row with white pawns

    }
    FBoard[0][0]->label(LBoard[0][0]);
    FBoard[0][1]->label(LBoard[0][1]);
    FBoard[0][2]->label(LBoard[0][2]);
    FBoard[0][3]->label(LBoard[0][3]);
    FBoard[0][4]->label(LBoard[0][4]);
    FBoard[0][5]->label(LBoard[0][5]);
    FBoard[0][6]->label(LBoard[0][6]);
    FBoard[0][7]->label(LBoard[0][7]);


    for (int X = 0; X <= 7; ++X){
        FBoard[6][X]->label(LBoard[6][X]);
    }

    FBoard[7][0] ->label(LBoard[7][0]);
    FBoard[7][1] ->label(LBoard[7][1]);
    FBoard[7][2] ->label(LBoard[7][2]);
    FBoard[7][3] ->label(LBoard[7][3]);
    FBoard[7][4] ->label(LBoard[7][4]);
    FBoard[7][5] ->label(LBoard[7][5]);
    FBoard[7][6] ->label(LBoard[7][6]);
    FBoard[7][7] ->label(LBoard[7][7]);

    for(int i=0 ; i<=7 ; i++)
    {
        for(int j=0 ; j<=7 ; j++)
        {
            int k=i+j;

                    if(k % 2 != 0 ){
                            FBoard[i][j]->color(FL_WHITE);
                    }

                    else if (k % 2 ==0 ){ 
                            FBoard[i][j]->color(FL_YELLOW); 
                    }
        }
    }
 }
 void DisplayWindow::ChangeButton(Fl_Widget * o, void * v){
    DisplayWindow* Win = (DisplayWindow *) v;
    Fl_Button * NewBoard = (Fl_Button*) o;

      if (Win->flag == false){
        DisplayWindow::LastLabel =  NewBoard->label();
        NewBoard->label("  ");
        Win->flag = true;
      }
      else{
         NewBoard->label(DisplayWindow::LastLabel);
         Win->flag = false;
      }         
 }

И файл заголовка:

class DisplayWindow: public Fl_Window {
public:

DisplayWindow(int width, int height, const char* title=0);

virtual ~DisplayWindow();

void MakeLabel();
void LabelButton();
static void ChangeButton(Fl_Button * o, void * );
static bool flag;
bool flag1;
static const char * LastLabel;

private:
Fl_Button *  FBoard[8][8];
char * LBoard[8][8];
};

#endif

person RodionRomanovichRaskolnikov    schedule 10.12.2015    source источник
comment
Как ChangeButton узнает, что v является DisplayWin, если обратный вызов не предоставляет this в качестве параметра? Вы пробовали запустить программу, чтобы проверить, работает ли обратный вызов?   -  person cup    schedule 11.12.2015
comment
Во время копирования и вставки я мог кое-что перепутать? Я разместил исправленный код ниже. Обратный вызов работает, но не так, как я хочу, он удаляет метку первой кнопки, как только она нажата, а не при нажатии второй кнопки.   -  person RodionRomanovichRaskolnikov    schedule 11.12.2015


Ответы (1)


cpp:

#include"Window.h"
#include"ChessBoard.h"

const char *  DisplayWindow::LastLabel;
bool   DisplayWindow::flag;
DisplayWindow::DisplayWindow(int width, int height, const char*)
:Fl_Window(800, 650, "Chess"){   


                             for (int X = 0; X <= 7; ++X){
                                    for (int Y = 0; Y <= 7; ++Y){
         // Leaves all positions that arent occupied by
         // a figure at the start of the game blank
                                        FBoard[X][Y] = new Fl_Button(10 + 50*Y, 100 + 50*X, 50, 50,"");
                                        FBoard[X][Y]->callback((Fl_Callback*)DisplayWindow::ChangeButton);


            //FBoard[X][Y]->callback(ChangeButton);
                                    }
                             }
                             flag = false;
                             MakeLabel(); 
                             LabelButton(); 
                             show();
                          }

DisplayWindow::~DisplayWindow(){}

void DisplayWindow::MakeLabel(){

  for (int X = 0; X <= 7; ++X){
    for (int Y = 0; Y <= 7; ++Y){

            LBoard[X][Y] = ("  ");
    }
  }

  for (int X = 0; X <= 7; ++X){ 
        LBoard[1][X] = ("WP");
    // Occupies second row with white pawns

  }
    LBoard[0][0] = ("WR");
    LBoard[0][1] = ("WH");
    LBoard[0][2] = ("WB");
    LBoard[0][3] = ("WQ");
    LBoard[0][4] = ("WK");
    LBoard[0][5] = ("WB");
    LBoard[0][6] = ("WH");
    LBoard[0][7] = ("WR");


  for (int X = 0; X <= 7; ++X){
        LBoard[6][X] = ("BP");
  }

    LBoard[7][0] = ("BR");
    LBoard[7][1] = ("BH");
    LBoard[7][2] = ("BB");
    LBoard[7][3] = ("BQ");
    LBoard[7][4] = ("BK");
    LBoard[7][5] = ("BB");
    LBoard[7][6] = ("BH");
    LBoard[7][7] = ("BR");
}

void DisplayWindow::LabelButton(){

    for (int X = 0; X <= 7; ++X){ 
        FBoard[1][X]->label(LBoard[1][X]);
    // Occupies second row with white pawns

    }
    FBoard[0][0]->label(LBoard[0][0]);
    FBoard[0][1]->label(LBoard[0][1]);
    FBoard[0][2]->label(LBoard[0][2]);
    FBoard[0][3]->label(LBoard[0][3]);
    FBoard[0][4]->label(LBoard[0][4]);
    FBoard[0][5]->label(LBoard[0][5]);
    FBoard[0][6]->label(LBoard[0][6]);
    FBoard[0][7]->label(LBoard[0][7]);


    for (int X = 0; X <= 7; ++X){
        FBoard[6][X]->label(LBoard[6][X]);
    }

    FBoard[7][0] ->label(LBoard[7][0]);
    FBoard[7][1] ->label(LBoard[7][1]);
    FBoard[7][2] ->label(LBoard[7][2]);
    FBoard[7][3] ->label(LBoard[7][3]);
    FBoard[7][4] ->label(LBoard[7][4]);
    FBoard[7][5] ->label(LBoard[7][5]);
    FBoard[7][6] ->label(LBoard[7][6]);
    FBoard[7][7] ->label(LBoard[7][7]);

    for(int i=0 ; i<=7 ; i++)
    {
        for(int j=0 ; j<=7 ; j++)
        {
            int k=i+j;

                    if(k % 2 != 0 ){
                            FBoard[i][j]->color(FL_WHITE);
                    }

                    else if (k % 2 ==0 ){ 
                            FBoard[i][j]->color(FL_YELLOW); 
                    }
        }
    }
}

void DisplayWindow::ChangeButton(Fl_Widget * o, void * v){
DisplayWindow* Win = (DisplayWindow *) v;
Fl_Button * NewBoard = (Fl_Button*) o;

if (Win->flag == false){
    DisplayWindow::LastLabel =  NewBoard->label();
    NewBoard->label("  ");
    Win->flag = true;
}
else{
    NewBoard->label(DisplayWindow::LastLabel);
    Win->flag = false;
    }           
}

h:

    #ifndef WINDOW_H_
#define WINDOW_H_
#include<vector>
#include<limits>
#include<string>
#include<iostream>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Button.H>




class DisplayWindow: public Fl_Window {
public:

 DisplayWindow(int width, int height, const char* title=0);

virtual ~DisplayWindow();

 void MakeLabel();
 void LabelButton();
 static void ChangeButton(Fl_Widget * o, void * );
 static bool flag;
 bool flag1;
 static const char * LastLabel;
private:
 Fl_Button *  FBoard[8][8];
 char * LBoard[8][8];
};

#endif
person RodionRomanovichRaskolnikov    schedule 11.12.2015