IUP, события мыши на матрице

У меня принципиальная путаница в понимании системы событий IUP. Теперь я говорю о матрице.

Вот как он создается:

Ihandle *create_mat(void)
{
mat = IupMatrix(NULL);

IupSetAttribute(mat, "READONLY", "YES");
IupSetCallback(mat, "CLICK_CB", (Icallback)click);
IupSetCallback(mat, "BUTTON_CB", (Icallback)button);
return mat;
}

Вот обратные вызовы:

int click(Ihandle *mat, int lin, int col)
{
char* value = IupMatGetAttribute(mat, "", lin, col);
if (!value) value = "NULL";
printf("click_cb(%d, %d)\n", lin, col);
return IUP_DEFAULT;
}

int button(Ihandle *mat, int button, int pressed, int x, int y, char* status)
{
printf("button %d, %d, %d, %d %s\n", button, pressed, x, y, status);
return IUP_DEFAULT;
}

Проблема в том, что мне нужны оба обратных вызова, но в показанной ситуации событие CLICK не запускается.
Если я отключу BUTTON_CB, то будет запущено событие CLICK. Но мне нужны оба, для щелчка, двойного щелчка левой кнопкой, отпускания правой кнопки и т. Д.

Это нормальное поведение, когда BUTTON_CB исключает CLICK_CB, или я делаю что-то не так?

На самом деле, как мне получить «lin» и «col» из обработчика BUTTON_CB или WHEEL_CB матрицы, если CLICK_CB, ENTERITEM_CB и LEAVEITEM_CB, которые дают lin и col, недоступны (не запускаются в описанной ситуации)?

И еще, как мне получить «активный элемент управления» (имя, тип элемента управления с фокусом) от обработчиков событий, используемых на уровне формы?


iup
person Wine Too    schedule 18.04.2013    source источник


Ответы (2)


Это нормальное поведение, когда BUTTON_CB исключает CLICK_CB, или я делаю что-то не так?

Да, это так. Поскольку BUTTON_CB - это обратный вызов IupCanvas, а CLICK_CB - обратный вызов IupMatrix. Помните, что IupMatrix наследуется от IupCanvas. Итак, внутри IupMatrix использует обратный вызов BUTTON_CB для реализации нескольких функций.

Итак, в этом случае вам нужно сохранить предыдущий обратный вызов перед назначением нового и вызвать старый изнутри вашего собственного. Что-то вроде этого:

old_callback = IupGetCallback(mat, "BUTTON_CB");
IupSetCallback(mat, "BUTTON_CB", new_callback);

int new_callback(...)
{
  return old_callback(...)
}

На самом деле, как мне получить «lin» и «col» из обработчика BUTTON_CB или WHEEL_CB матрицы, если CLICK_CB, ENTERITEM_CB и LEAVEITEM_CB, которые дают lin и col, недоступны (не запускаются в описанной ситуации)?

Используйте функцию pos = IupConvertXYToPos (mat, x, y), где pos = lin * numcol + col. Вычислить lin и col довольно просто, учитывая, что они являются целыми числами.

И еще, как мне получить «активный элемент управления» (имя, тип элемента управления с фокусом) от обработчиков событий, используемых на уровне формы?

Я не полностью понимаю ваш вопрос. Но я думаю, что IupGetFocus и IupGetClassName могут быть теми функциями, которые вам нужны.

person Antonio Scuri    schedule 19.04.2013

Я отвечу на свой вопрос, воспользовавшись советами Антонио, чтобы другие люди, интересующиеся IUP, могли извлечь пользу из этих сообщений.

Если я хорошо понимаю, что маловероятно, вот как я делаю обработчик BUTTON_CB для моей матрицы:

int button(Ihandle *mat, int button, int pressed, int x, int y, char* status)
{
//actually 'name' is Ihandle
//and class name is a 'type'
//in compare with other toolkits
char* name = IupGetClassName(mat);

//so since we have handle already
//we can't be here if we are not in concrete matrix
//and this comparision is not needed
if (strncmp(name, "matrix", sizeof(name)) == 0)
{
    //if left mouse button is down
    if (button == IUP_BUTTON1 && pressed == 1)
    {
        //my calculation is not 100% correct
        //but good enough for this sample
        int pos = IupConvertXYToPos(mat, x, y);
        _line = pos/numcol;
        _col = pos%numcol;

        //if is doubleclick
        if (status[5] == 'D')
        {
            //press ENTER key
            //and open another modal dialog
            //with argument 'sel'
            k_any(mat, K_CR);

            printf("Doubleclick\n");
            //say HANDLED for IUP
            //but not matter when READONLY is "YES"
            return IUP_IGNORE;
        }

        //calculate (public) sel
        //for select a clicked line
        sel = _line + from - 1;
        refreshl(from, sel);

        printf("Click\n");
        return IUP_IGNORE;
    }
}
return IUP_DEFAULT;
}

Эта работа соответствует ожиданиям.
Пожалуйста, предложите дополнительные предложения, если что-то не в порядке.

person Wine Too    schedule 19.04.2013
comment
Если вы установите этот обратный вызов в элементе IupMatrix, нет необходимости проверять имя класса и сравнивать его с матрицей, это всегда будет верно. - person Antonio Scuri; 28.04.2013
comment
Просто отсутствует вызов предыдущего обратного вызова BUTTON_CB. Поскольку это стандартная обработка мыши в IupMatrix, она будет проигнорирована. - person Antonio Scuri; 29.04.2013