如何确保滑块只返回整数值?
有任何示例代码片段或最佳实践可用于实施吗?
interface DialogWithSliderInterface
{
void SetSliderFieldValue(Object self, Number newSliderValue);
}
class SliderFieldView
{
Number sliderSize;
Number parentDialogID;
ImageDocument sliderViewDoc;
ROI sliderROI;
Object Init(Object self, Object parentDialog, String valueLabel, Number initialValue, Number sliderSizeIn)
{
parentDialogID = parentDialog.ScriptObjectGetID();
sliderSize = sliderSizeIn;
// Create slider view as LinePlot with single ROI of fixed width 0
String sliderViewName = valueLabel + " slider view";
Image sliderImage := IntegerImage(sliderViewName, 1, 0, sliderSize + 1);
sliderImage = 1;
sliderViewDoc = NewImageDocument(sliderViewName);
sliderROI = NewROI();
sliderROI.ROISetRange(initialValue, initialValue + 1);
sliderROI.ROISetName(valueLabel);
sliderROI.ROISetLabel(" ");
sliderROI.ROISetResizable(0);
sliderROI.ROISetMoveable(1);
sliderROI.ROISetDeletable(0);
sliderROI.ROISetVolatile(0);
ImageDisplay sliderView = sliderViewDoc.ImageDocumentAddImageDisplay(sliderImage, 3);
sliderView.LinePlotImageDisplaySetDoAutoSurvey(0, 0);
sliderView.LinePlotImageDisplaySetContrastLimits(0, 1);
sliderView.ImageDisplaySetCaptionOn(0);
sliderView.LinePlotImageDisplaySetFrameOn(0);
sliderView.ImageDisplayAddROI(sliderROI);
sliderView.ImageDisplaySetROISelected(sliderROI, 1);
// Connect a listener to the ROI
ConnectObject(sliderROI.ROIGetID(), "changed", valueLabel, self, "DoSliderChange");
sliderViewDoc.ImageDocumentShowAtRect(450, 200, 500, 600);
sliderViewDoc.ImageDocumentClean();
return self;
}
void ShowView(Object self)
{
sliderViewDoc.ImageDocumentShow();
sliderViewDoc.ImageDocumentClean();
}
void SetSlider(Object self, Number newSliderValue)
{
Number sliderValue = newSliderValue.Clip(0, sliderSize).Round();
sliderROI.ROISetRange(sliderValue, sliderValue + 1);
self.ShowView();
}
void DoSliderChange(Object self, ROI changedROI)
{
if (changedROI.ROIGetID() == sliderROI.ROIGetID())
{
Number sliderValue, sliderEnd;
sliderROI.ROIGetRange(sliderValue, sliderEnd);
Object parentDialog = GetScriptObjectFromID(parentDialogID);
parentDialog.SetSliderFieldValue(sliderValue);
sliderViewDoc.ImageDocumentClean();
}
}
void DisconnectROI(Object self)
{
DisconnectObject(sliderROI.ROIGetID(), "changed", sliderROI.ROIGetName());
}
~SliderFieldView(Object self)
{
sliderViewDoc.ImageDocumentClose(0);
}
}
class DialogWithSliderField : UIFrame
{
TagGroup sliderFieldSpec;
Object sliderFieldView;
Object Init(Object self, Number sliderSize)
{
// Create integer field that will have slider view associated with it
Number initialValue = sliderSize / 2;
Number fieldWidth = Log10(sliderSize) + 2;
String fieldLabel = "Parameter 1";
TagGroup integerFieldGroupSpec = DLGCreateIntegerField(fieldLabel, sliderFieldSpec, initialValue, fieldWidth);
integerFieldGroupSpec.DLGExternalPadding(8, 8);
sliderFieldSpec.DLGChangedMethod("DoSliderFieldChange");
// Create and attach slider view
sliderFieldView = Alloc(SliderFieldView).Init(self, fieldLabel, initialValue, sliderSize);
// Create the dialog specification, adding the integer field group
String dialogTitle = "Slider Field UI";
TagGroup dialogSpec = DLGCreateDialog(dialogTitle);
TagGroup dialogItems = dialogSpec.DLGGetItems();
dialogItems.DLGAddElement(integerFieldGroupSpec);
// Add a "Show Slider View" button
TagGroup showSliderButtonSpec = DLGCreatePushButton("Show Slider View", "ShowSliderView");
dialogItems.DLGAddElement(showSliderButtonSpec);
// Create and display dialog
self = self.super.Init(dialogSpec);
self.Display(dialogTitle);
DocumentWindow viewWindow = self.GetFrameWindow();
viewWindow.WindowSetFramePosition(200, 200);
return self;
}
void SetSliderFieldValue(Object self, Number newSliderValue)
{
Number sliderValue = sliderFieldSpec.DLGGetValue();
if (newSliderValue != sliderValue)
sliderFieldSpec.DLGValue(newSliderValue);
}
void DoSliderFieldChange(Object self, TagGroup fieldSpec)
{
sliderFieldView.SetSlider(fieldSpec.DLGGetValue());
}
void ShowSliderView(Object self)
{
sliderFieldView.ShowView();
}
Number AboutToCloseDocument(Object self, Number verify)
{
sliderFieldView.DisconnectROI();
return 0;
}
}
void main()
{
Object sliderDialog = Alloc(DialogWithSliderField).Init(100);
}
main();
DialogWithSliderField
仅存储parent对话框对象的ID中的ID很重要。如果一个人要保存实际的对象引用,则可以在两个对象之间设置一个参考周期,即使它们手动关闭两个窗口,它们也永远不会被划分。
指出在
SliderFieldView
方法DisconnectROI
AboutToCloseDocument
的明确调用。这对于打破
DialogWithSliderField
对象及其连接的ROI侦听器之间的参考周期很重要。没有这个,即使手动关闭窗口,视图对象也永远不会被划分。
DM处理对话框UI Windows和图像显示窗口完全不同,因此前面的“浮动”在所有工作区上,而“滑块视图”窗口将连接到当前工作区。这也意味着用于定位对话框窗口和滑块视图窗口的坐标系与彼此不一致。
事实证明,将滑块ROI的宽度设置为0不起作用,因为DM似乎不喜欢线图上的零宽ROI。即使将ROI设置为不可避免的,与零宽的ROI相互作用不可避免地会导致其具有非零的宽度。将宽度设置为单个通道似乎可以正常工作。注意,在DM UI中关闭时,Slider View ImageDocument不会被划分,因为两个Live对象继续引用它(其主机
SliderFieldView
对象和ROI侦听器)。因此,如果已关闭(或隐藏或最小化),则将按钮添加到对话框UI中,以使Slider View Im ImagedOcument再次可见。