对话框面板在开关上没有正确隐藏 - 有解决方法吗?

Dialog panels do not hide properly on switch - is there a workaround?

我有一个包含两个面板的对话框,如下所示,是使用给定代码创建的。如右图所示,第二个面板仍然包含第一个面板的内容。

有解决办法吗?

我觉得应该在 Whosebug 上提及此类错误。

class TestDialog : UIFrame{
    TagGroup panel_list;
    
    /**
     * Switch to the `index`-th panel.
     */
    void switchToPanel(object self, number index){
        panel_list.DLGValue(index);
    }
    
    void switchToPanel0(object self){self.switchToPanel(0);}
    void switchToPanel1(object self){self.switchToPanel(1);}
    
    /**
     * Create the dialog content
     */
    TagGroup createContent(object self){
        panel_list = DLGCreatePanelList(0);
        
        TagGroup box, switch_button, input, panel;

        // panel 1
        box = DLGCreateBox("Panel 1");
        
        // switch panel button
        switch_button = DLGCreatePushButton("Switch to panel 2", "switchToPanel1");
        box.DLGAddElement(switch_button);
        
        // input field
        input = DLGCreateStringField("ABC");
        box.DLGAddElement(input);
        
        panel = DLGCreatePanel();
        panel.DLGAddElement(box);
        panel_list.DLGAddElement(panel);

        // panel 2
        box = DLGCreateBox("Panel 2");
        
        // switch panel button
        switch_button = DLGCreatePushButton("Switch to panel 1", "switchToPanel0");
        box.DLGAddElement(switch_button);
        
        // add a label so both boxes have different heights
        box.DLGAddElement(DLGCreateLabel(""));
        
        // input field
        input = DLGCreateStringField("DEF");
        box.DLGAddElement(input);
        
        panel = DLGCreatePanel();
        panel.DLGAddElement(box);
        panel_list.DLGAddElement(panel);
        
        TagGroup wrapper = DLGCreateGroup();
        wrapper.DLGAddElement(panel_list);

        return wrapper;
    }

    object init(object self){
        return self.super.init(self.createContent())
    }
}

alloc(TestDialog).init().pose()

修复:手动隐藏

经过大量尝试后,我认为手动触发 UIFrame::SetElementIsShown() 可以解决此问题。在给定的示例中,可以将标识符 input0 添加到第一个输入,将 input1 添加到第二个输入,然后将 TestDialog::switchToPanel() 函数更改为以下内容:

/**
* Switch to the `index`-th panel.
*/
void switchToPanel(object self, number index){
    panel_list.DLGValue(index);
    
    if(index == 0){
        self.setElementIsShown("input0", 1);
        self.setElementIsShown("input1", 0);
    }
    else{
        self.setElementIsShown("input0", 0);
        self.setElementIsShown("input1", 1);
    }
}

那么完整的代码是:

class TestDialog : UIFrame{
    TagGroup panel_list;
    
    /**
    * Switch to the `index`-th panel.
    */
    void switchToPanel(object self, number index){
        panel_list.DLGValue(index);
        
        if(index == 0){
            self.setElementIsShown("input0", 1);
            self.setElementIsShown("input1", 0);
        }
        else{
            self.setElementIsShown("input0", 0);
            self.setElementIsShown("input1", 1);
        }
    }
    
    void switchToPanel0(object self){self.switchToPanel(0);}
    void switchToPanel1(object self){self.switchToPanel(1);}
    
    /**
     * Create the dialog content
     */
    TagGroup createContent(object self){
        panel_list = DLGCreatePanelList(0);
        
        TagGroup box, switch_button, input, panel;

        // panel 1
        box = DLGCreateBox("Panel 1");
        
        // switch panel button
        switch_button = DLGCreatePushButton("Switch to panel 2", "switchToPanel1");
        box.DLGAddElement(switch_button);
        
        // input field
        input = DLGCreateStringField("ABC");
        input.DLGIdentifier("input0");
        box.DLGAddElement(input);
        
        panel = DLGCreatePanel();
        panel.DLGAddElement(box);
        panel_list.DLGAddElement(panel);

        // panel 2
        box = DLGCreateBox("Panel 2");
        
        // switch panel button
        switch_button = DLGCreatePushButton("Switch to panel 1", "switchToPanel0");
        box.DLGAddElement(switch_button);
        
        // add a label so both boxes have different heights
        box.DLGAddElement(DLGCreateLabel(""));
        
        // input field
        input = DLGCreateStringField("DEF");
        input.DLGIdentifier("input1");
        box.DLGAddElement(input);
        
        panel = DLGCreatePanel();
        panel.DLGAddElement(box);
        panel_list.DLGAddElement(panel);
        
        TagGroup wrapper = DLGCreateGroup();
        wrapper.DLGAddElement(panel_list);

        return wrapper;
    }

    object init(object self){
        return self.super.init(self.createContent())
    }
}

alloc(TestDialog).init().pose()

解决方法:使用制表符

我还发现选项卡使用完全相同的代码。因此,如果可能的话,可以将面板替换为标签。

class TestDialog : UIFrame{
    TagGroup tab_list;
    TagGroup inputs;
    
    /**
     * Create the dialog content
     */
    TagGroup createContent(object self){
        inputs = NewTagList();
        tab_list = DLGCreateTabList(0);
        
        TagGroup box, input, tab;

        // panel 1
        box = DLGCreateBox("Panel 1");
        
        // input field
        input = DLGCreateStringField("ABC");
        box.DLGAddElement(input);
        // save the input field in a TagList, this creates the problem
        inputs.TagGroupInsertTagAsTagGroup(infinity(), input);
        
        tab = DLGCreateTab("Tab 1");
        tab.DLGAddElement(box);
        tab_list.DLGAddElement(tab);

        // panel 2
        box = DLGCreateBox("Panel 2");
        
        // add a label so both boxes have different heights
        box.DLGAddElement(DLGCreateLabel(""));
        
        // input field
        input = DLGCreateStringField("DEF");
        box.DLGAddElement(input);
        inputs.TagGroupInsertTagAsTagGroup(infinity(), input);
        
        tab = DLGCreateTab("Tab 2");
        tab.DLGAddElement(box);
        tab_list.DLGAddElement(tab);
        
        TagGroup wrapper = DLGCreateGroup();
        wrapper.DLGAddElement(tab_list);

        return wrapper;
    }

    object init(object self){
        return self.super.init(self.createContent())
    }
}

object dialog = alloc(TestDialog).Init();
dialog.pose();