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

Примере:

class ButtonDialog : UIFrame{
    void button_pressed(object self){
        // how do I get this button
        TagGroup pressed_button = ?;
        result("The button " + pressed_button + " is pressed.\n");
    }
    
    object init(object self){
        TagGroup dlg, dlg_items, button1, button2;
        
        dlg = DLGCreateDialog("Press a button", dlg_items);
        
        button1 = DLGCreatePushButton("Button 1", "button_pressed");
        button1.DLGIdentifier("button1");
        dlg_items.DLGAddElement(button1);
        
        button2 = DLGCreatePushButton("Button 2", "button_pressed");
        button2.DLGIdentifier("button2");
        dlg_items.DLGAddElement(button2);
        
        self.super.init(dlg);
        return self;
    }
}

object dialog = alloc(ButtonDialog).init();
dialog.pose();

В моей текущей программе у меня есть несколько строк, созданных из TagGroup. В каждой строке есть несколько кнопок, выполняющих одно и то же, но для своей конкретной строки. Поэтому мне нужно знать, какая это кнопка, чтобы изменить строку. Также длина TagGroup и, следовательно, количество строк не фиксированы. Поэтому я не могу создавать функции button1_pressed, button2_pressed, ..., кроме как делать какие-то странные вещи с оценкой кода на лету, чего я хочу по возможности избегать.

1
miile7 18 Авг 2020 в 10:52

2 ответа

Лучший ответ

Тот факт, что вы не можете передать аргумент в простом обратном вызове кнопки, немного обескураживает. Самое простое решение (хотя и не изящное) - использовать простые однострочные методы обратного вызова, которые уникальны, но сами вызывают обобщенный метод, как в приведенном ниже коде.

Конечно, mile7 заявил, что количество кнопок не фиксируется во время компиляции, что здесь является проблемой. Но если (потенциальное) количество кнопок не велико, этот подход по-прежнему остается самым простым и чистым, а поскольку каждый "жестко закодированный" обратный вызов представляет собой только одну строку с очень системным изменением, использование Notepad ++ или аналогично предоставить достаточно обширный набор таких вызовов. (Не повредит, если некоторые из них на самом деле никогда не используются.)

class ButtonDialog : UIFrame{
    void button_pressed(object self, string buttonID){
        // how do I get this button
        TagGroup pressed_button = self.LookUpElement(buttonID);
        if ( pressed_button.TagGroupIsValid() )
            result("The button " + buttonID + " is pressed.\n");
        else
            result("The button " + buttonID + " was not found!\n");
    }
    
    // Need to be done for each button
    void button_pressed_0(object self) { self.button_pressed("button0"); }
    void button_pressed_1(object self) { self.button_pressed("button1"); }
    
    object init(object self){
        TagGroup dlg, dlg_items
        
        dlg = DLGCreateDialog("Press a button", dlg_items);
        number nButtons = 2
        for( number n=0; n<nButtons; n++ ){
            TagGroup button = DLGCreatePushButton("Button " + n , "button_pressed_" + n);
            button.DLGIdentifier("button" + n);
            dlg_items.DLGAddElement(button);
        }
        
        self.super.init(dlg);
        return self;
    }
}

object dialog = alloc(ButtonDialog).init();
dialog.pose();
1
BmyGuest 18 Авг 2020 в 22:09

Так что я как бы нашел ответ, с которым могу жить, но я все еще надеюсь на лучшие результаты.

Моя текущая идея - использовать DualStateBevelButtons. При нажатии кнопки состояние изменяется, и выполняется обратный вызов. Затем проверяются все кнопки на предмет изменения состояния. Если да, то это нажатая кнопка, и состояние сбрасывается.

Очень-очень большой недостаток этого решения заключается в том, что разрешены только кнопки с изображениями, текст невозможен. Так что это не совсем универсальное решение для работы.

rgbimage button_img = RGBImage("button-image", 4, 16, 16);
button_img = max(0, 255 - iradius / 8 * 255);

class ButtonDialog : UIFrame{
    TagGroup buttons;
    
    void button_pressed(object self){
        for(number i = 0; i < buttons.TagGroupCountTags(); i++){
            TagGroup button;
            if(buttons.TagGroupGetIndexedTagAsTagGroup(i, button)){
                if(button.DLGGetValue() == 1){
                    // this button is toggled so it is clicked
                    string identifier;
                    button.DLGGetIdentifier(identifier);
                    
                    result("Button " + i + " (" + identifier + ") is clicked.\n");
                    
                    // reset button state
                    button.DLGBevelButtonOn(0);
                    
                    // do not continue searching, found pressed button already
                    break;
                }
            }
        }
    }
    
    object init(object self){
        TagGroup dlg, dlg_items, button1, button2;
        
        dlg = DLGCreateDialog("Press a button", dlg_items);
        buttons = NewTagList();
        
        button1 = DLGCreateDualStateBevelButton("button1", button_img, button_img, "button_pressed");
        buttons.TagGroupInsertTagAsTagGroup(infinity(), button1);
        dlg_items.DLGAddElement(button1);
        
        button2 = DLGCreateDualStateBevelButton("button2", button_img, button_img, "button_pressed");
        buttons.TagGroupInsertTagAsTagGroup(infinity(), button2);
        dlg_items.DLGAddElement(button2);
        
        self.super.init(dlg);
        return self;
    }
}

object dialog = alloc(ButtonDialog).init();
dialog.pose();
0
miile7 18 Авг 2020 в 08:41