Как добавить контент в видимый диалог - PullRequest
2 голосов
/ 14 апреля 2020

Как добавить элементы в видимый диалог, когда пользователь нажимает кнопку в сценарии dm?


Моя цель - это диалог ввода, который позволяет пользователю выбрать изображения, которые он хочет обработать. Это может быть более одного изображения. Поэтому я хотел разработать диалог, который предлагает кнопку add . Нажатие на кнопку добавляет поле выбора (DLGCreateImagePopup()) для выбора изображения.

Моя проблема в том, что я не нашел способ обновить интерфейс диалогов. Он не перерисовывает содержимое. Единственная вещь, которая приближается к моей проблеме, - в этом посте о , как включить и отключить элемент . В посте предлагается использовать UIFrame.close(), за которым следует UIFrame.display(), но появившийся диалог больше не является модальным. При изменении значения UIFrame.display() на UIFrame.pose() диалоговое окно просто исчезает. При попытке выполнить скрипт снова ошибка Класс уже объявлен: «TestDialog» появляется. Затем мне нужно перезапустить GMS.

Следующий скрипт создает диалог, показанный на картинке. При нажатии «Добавить» в строке «Кнопка нажата». должен появиться, но ничего не происходит.

Dialog

TagGroup dialog_items;
TagGroup dialog_tags = DLGCreateDialog("Test dialog", dialog_items);

TagGroup group = DLGCreateGroup();
group.DLGIdentifier("group");
dialog_items.DLGAddElement(group);

TagGroup label = DLGCreateLabel("Press the 'Add' button.");
group.DLGAddElement(label);

TagGroup add = DLGCreatePushButton("Add", "addButtonPressed");
group.DLGAddElement(add);

class TestDialog : UIFrame{
    void addButtonPressed(object self){
        TagGroup g = self.LookUpElement("group");
        TagGroup l = DLGCreateLabel("Button pressed.");
        g.DLGAddElement(l);

        self.ValidateView(); // <- does nothing

        // self.close();
        // self.display(""); // <- doesn't show as modal

        // self.close();
        // self.pose(); // <- doesn't show up, forces to restart GMS
    }
}

Object dialog = alloc(TestDialog).init(dialog_tags);

dialog.Pose();

Ответы [ 2 ]

2 голосов
/ 15 апреля 2020

Модель диалога скриптов в DM-скриптинге очень ограничена, и не поддерживает добавление или удаление элементов во время отображения (по состоянию на GMS 3.4).

Возможно, можно обойти эту проблему с большими усилиями, но в целом тратить слишком много времени на то, чтобы сделать диалоги сценариев "красивыми", чаще всего не стоит.

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

См. пример:

class CElementHideTest : UIframe
{
    TagGroup BuildDialog(object self)
    {
        TagGroup dlg,dlgItems
        dlg = DLGCreateDialog("test",dlgitems)

        TagGroup group = DLGCreateGroup().DLGIdentifier("group")
        dlgitems.DLGAddElement(group)

        TagGroup label = DLGCreateLabel("Toggle tests")
        group.DLGAddElement(label)

        TagGroup toggleEnabledButton = DLGCreatePushButton("Toggle Enabled", "toggleEnabled")
        group.DLGAddElement(toggleEnabledButton)

        TagGroup toggleShownButton = DLGCreatePushButton("Toggle Shown", "toggleShown")
        group.DLGAddElement(toggleShownButton)

        TagGroup field1 = DLGCreateIntegerField(5,5).DLGIdentifier("field")
        dlgitems.DLGAddElement(field1)

        return dlg
    }

    void toggleEnabled(object self)
    {
        number is = self.GetElementIsEnabled("field")
        self.SetElementIsEnabled("field",!is)
    }

    void toggleShown(object self)
    {
        number is = self.GetElementIsShown("field")
        self.SetElementIsShown("field",!is)
    }

    object Init(object self)
    {
        return self.Init(self.BuildDialog())
    }
}

Alloc(CElementHideTest).init().Pose()

enter image description here enter image description here

Хотя можно изменить размер диалогового окна при отображении, это не очень полезно для модального диалога, потому что позиция OK | Кнопки отмены фиксируются при запуске. Следовательно, вы можете только создать «уродливый» диалог с большим количеством пустого пространства, где будут появляться элементы.

Однако, если ваш скрипт выполняется в фоновом потоке, вы можете создать свой собственный модальный диалог, как в пример ниже. Это позволит вам использовать окно изменения размера и сжатия / расширения диалогового окна при отображении элементов.

Обратите внимание, что это не может работать на сценарии в основном потоке, как код отображения диалогового окна также работает в основном потоке. Следовательно, ожидание диалогового окна не позволит правильно отображать диалоговое окно.

Class CScriptModalDialog : UIFrame
{
    object contSignal

    TagGroup BuildDialog(object self)
    {
        TagGroup dlg,dlgItems
        dlg = DLGCreateDialog("test",dlgitems)

        TagGroup group = DLGCreateGroup().DLGIdentifier("group")
        dlgitems.DLGAddElement(group)

        TagGroup label = DLGCreateLabel("Display as modal dialog")
        group.DLGAddElement(label)

        TagGroup toggleEnabledButton = DLGCreatePushButton("Continue", "ContinuePressed")
        group.DLGAddElement(toggleEnabledButton)

        contSignal = NewSignal(0)

        return dlg
    }

    void ContinuePressed(object self)
    {
        contSignal.SetSignal()
    }

    number PoseScriptDlg(object self, number timeOutSec )
    {
        self.Init(self.BuildDialog())
        self.Display("Script dialog")
        object cancelSignal = NewCancelSignal()
        number success = contSignal.WaitOnSignal(timeOutSec,cancelSignal)   // Could also use Infinity() as timeout
        self.Close()
        return success
    }

    number WaitOnOK(object self)
    {
        object cancelSignal = NewCancelSignal()
        return contSignal.WaitOnSignal(1,cancelSignal)
    }
}

class CMain
{
    object continueDlg
    CMain(object self) { continueDlg=Alloc(CScriptModalDialog); }

    void RunMethod(object self)
    {
        ClearResults()
        Result("Waiting on user for 3 sec...\n")
        if ( continueDlg.PoseScriptDlg(3) )
            Result("Continue\n")
        else
            Result("TimeOut\n")
    }
}

Alloc(CMain).StartThread("RunMethod")
1 голос
/ 15 апреля 2020

Не прямой ответ на ваш вопрос, и, возможно, не то, что вы хотите, а в качестве идеи: если вы заинтересованы только в выборе до четырех изображений, вы также можете проявить творческий подход к существующим Get...Images() команды, например, например:

image img1,img2,img3,img4
if (GetFourlabeledImagesWithPrompt( "Select up to 4 images.\nDouble selected images will be used once.","Titel", "first:",img1, "second:",img2,"third:",img3,"fourth:",img4))
{
    // Make list of used ID's removing doubles
    taggroup list = NewTagGroup()
    list.TagGroupSetTagAsBoolean( img1.ImageGetLabel(), 1 )
    list.TagGroupSetTagAsBoolean( img2.ImageGetLabel(), 1 )
    list.TagGroupSetTagAsBoolean( img3.ImageGetLabel(), 1 )
    list.TagGroupSetTagAsBoolean( img4.ImageGetLabel(), 1 )

    number nUsed = list.TagGroupCountTags()
    Result("\n Unique images chosen: " + nUsed)
    for( number i=0; i<nUsed; i++)
    {
        image img := FindImageByLabel( list.TagGroupGetTagLabel(i) )
        if ( img.ImageIsValid() )
        {
            Result("\n\t Image #"+i+": <"+img.ImageGetName()+">" )
        }
    }
}

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...