如何向可见对话框添加内容
How to add content to a visible dialog
当用户点击 dm 脚本中的按钮时,如何将元素添加到可见对话框?
我的目标是一个输入对话框,允许用户 select 他想要处理的图像。这可以是多个图像。因此我想设计一个提供 add 按钮的对话框。单击该按钮会添加一个 select 框 (DLGCreateImagePopup()
),用于选择图像。
我的问题是我没有找到更新对话框的方法 UI。它不会重绘内容。唯一接近我的问题的是关于 的 post。 post 建议使用 UIFrame.close()
后跟 UIFrame.display()
但出现的对话框不再是模态的。将 UIFrame.display()
更改为 UIFrame.pose()
对话框就消失了。当再次尝试执行脚本时,错误 Class already declared: 'TestDialog' 出现了。那我得重启GMS了。
以下脚本创建图中所示的对话框。单击 'Add' 时,应该会出现 'Button pressed.' 行,但什么也没有发生。
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();
The script dialog model in DM-scripting is very limited and does not support adding or removing items during display (as of GMS 3.4).
也许可以通过大量努力来解决该问题,但总的来说,花太多时间制作脚本对话框 "pretty" 通常是不值得的。
您能做的最好的事情就是利用现有项目的 shown 属性来显示或隐藏它们。
参见示例:
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()
虽然可以在显示时调整对话框 window 的大小,但这对模态对话框没有多大用处,因为 OK | 的位置取消按钮在启动时固定。因此,您只能创建一个 "ugly" 对话框,其中包含许多空的 space 项目将出现在其中。
但是,如果您的脚本 运行 在后台线程上运行,则您可以创建自己的模态对话框,如下例所示。这将允许您在显示项目时使用 window 调整大小和 shrink/extend 对话框。
注意,这不能在主线程中的脚本上工作,因为对话框显示代码 也在主线程中 运行s。因此,等待对话框会阻止对话框正确显示。
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")
不是您问题的直接答案,也可能不是您想要的,但作为一个想法提供者:
如果您只想选择最多四张图片,也可以使用现有的 Get...Images()
命令来发挥一点创意,例如 f.e:
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()+">" )
}
}
}
当用户点击 dm 脚本中的按钮时,如何将元素添加到可见对话框?
我的目标是一个输入对话框,允许用户 select 他想要处理的图像。这可以是多个图像。因此我想设计一个提供 add 按钮的对话框。单击该按钮会添加一个 select 框 (DLGCreateImagePopup()
),用于选择图像。
我的问题是我没有找到更新对话框的方法 UI。它不会重绘内容。唯一接近我的问题的是关于 UIFrame.close()
后跟 UIFrame.display()
但出现的对话框不再是模态的。将 UIFrame.display()
更改为 UIFrame.pose()
对话框就消失了。当再次尝试执行脚本时,错误 Class already declared: 'TestDialog' 出现了。那我得重启GMS了。
以下脚本创建图中所示的对话框。单击 'Add' 时,应该会出现 'Button pressed.' 行,但什么也没有发生。
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();
The script dialog model in DM-scripting is very limited and does not support adding or removing items during display (as of GMS 3.4).
也许可以通过大量努力来解决该问题,但总的来说,花太多时间制作脚本对话框 "pretty" 通常是不值得的。
您能做的最好的事情就是利用现有项目的 shown 属性来显示或隐藏它们。
参见示例:
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()
虽然可以在显示时调整对话框 window 的大小,但这对模态对话框没有多大用处,因为 OK | 的位置取消按钮在启动时固定。因此,您只能创建一个 "ugly" 对话框,其中包含许多空的 space 项目将出现在其中。
但是,如果您的脚本 运行 在后台线程上运行,则您可以创建自己的模态对话框,如下例所示。这将允许您在显示项目时使用 window 调整大小和 shrink/extend 对话框。
注意,这不能在主线程中的脚本上工作,因为对话框显示代码 也在主线程中 运行s。因此,等待对话框会阻止对话框正确显示。
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")
不是您问题的直接答案,也可能不是您想要的,但作为一个想法提供者:
如果您只想选择最多四张图片,也可以使用现有的 Get...Images()
命令来发挥一点创意,例如 f.e:
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()+">" )
}
}
}