在Illustrator中列表有很多种,本篇介绍的是在一般控件上扩展出来的列表(如ComboBox),包括开发指南与实际开发2部分。
开发指南:
List Suite列表功能集合
ADM List功能集合可以用来访问ADM列表对象和ADM列表项。ADM列表是标准ADM对象的扩展属性,这个功能集合中缺少许多ADM对象通用函数。但是,可以访问列表的ADM Item,在其上做通用操作。使用这个功能集中的函数,可以初始化列表,创建、销毁、自定义和遍历列表项。使用列表功能集和ADM Entry功能集一起可以深入的访问列表相关信息。
请求这个功能集
调用SPBasicSuite::AcquireSuite()来请求这个功能集。使用名字和版本参数来确定获取的具体值。
列表和列表项
ADM列表用来给任何ADM Item来提供列表选择,包括列表框、弹出列表、弹出菜单、渐变编辑框、弹出文本编辑框。一个ADM列表由多个ADM列表项组成。
ADM列表没有许多标准属性,如插件和外框;但是,在列表的ADM Item上可以定义。为了访问它,使用sADMList->GetItem()函数,获取列表的所有者。
ADM列表有些特别的属性,如一个菜单资源ID和一组列表项。ADM列表项有额外的属性,包括索引和选择状态。ADM列表功能集用这些属性来访问列表项。索引是列表项在列表中的位置。选择状态标示了用户选择了此项(在多选列表中其他项也可能被选择)。
使用列表功能集
使用sADMItem->GetList获取列表对象:
ADMListRef theItemsList = sADMItem->GetList(theItem);
一旦完成,就可以使用ADM List和ADM Entry功能集的函数来修改它。
为了初始化一个列表,指定给它一个菜单资源ID:
sADMList->SetMenuID(theItemsList, gPluginRef, 16000, “Choices”);
你同样可以创建每一个列表项,使用sADMList->InsertEntry函数:
For(index = 0; index < kNumberEntries; index++)
{
Char menuText[255];
ADMEntryRef entry = sADMList->InsertEntry(theItemList, index);
sADMBasic->GetIndexString(thePlugin, 16000, index, menuText, 255);
sADMEntry->SetText(entry, menuText);
sADMEntry->SetID(entry, index);
}
注意:列表索引从0开始。
使用sADMList->GetActiveEntry函数来获取当前选中的项,然后获取索引,如:
Int GetListValue(ADMItem theListItem)
{
ADMListRef theList = sADMItem->GetList(theListItem);
ADMListEntryRef theEntry=sADMList->GetActiveEntry(theItemList);
Return sADMEntry->GetID(theEntry);
}
遍历多选项时:
Int count = sADMList->NumberOfSelectedEntries(theList);
For(index = 0; index < count; index++)
{
ADMEntryRef entry = sADMList->IndexSelectedEntry(theList, index);
doSomethingToSelectedEntry(theEntry);
}
自定义列表
可以自定义ADM列表,就和自定义其他ADM Item一样。这个工作通过定义一个或多个事件响应函数来完成。由于ADM列表和ADM列表项紧密关联,处理方式稍微有些不同。
ADM列表没有自己的事件处理函数。在单个事件中,为了对列表整体进行操作,需要设置列表事件处理函数。如,为了标注列表,设置一个绘图函数给列表。使用的是ADM Item功能集。
为了改变列表低级别的行为,设置列表项的消息处理函数。如,为了改变每一个列表项的绘图方式,设置列表项的绘图函数。使用ADM List功能集在列表级别上完成,就会应用到列表的所有列表项上。你不能直接给单个列表项设置事件处理函数。一个自定义的事件处理函数,应该可以处理列表的所有项。
为了使用列表的默认行为,使用ADM Item功能集的函数。为了使用默认的列表项行为,使用ADM Entry功能集的函数。不要使用ADM List功能集。
实际开发:
需要为地图插件添加一个标注功能,是将一个空间图形图层的各个要素的某个属性标注到另外一个图层中作为注记,如为某个省的区县标注区名。界面上包含有3个ComboBox:源图层,字段,目标图层,使用ADM列表来编写代码。主要包括列表清理和列表初始化、列表选项变化事件的处理。
//对话框的初始化Proc
ASErr ASAPI MdLabel::InitProc(ADMDialogRef dialog)
{
ASErr error = kNoErr;
ADMItemRef srcLayerItemRef = sADMDialog->GetItem(dialog, IDC_COMBO_SRCLAYER);
sADMItem->SetNotifyProc(srcLayerItemRef, SrcLayerPopupProc);
ADMItemRef desLayerItemRef = sADMDialog->GetItem(dialog, IDC_COMBO_DESLAYER);
sADMItem->SetNotifyProc(desLayerItemRef, DesLayerPopupProc);
ADMItemRef fieldItem = sADMDialog->GetItem(dialog, IDC_COMBO_FIELD);
sADMItem->SetNotifyProc(fieldItem, FieldPopupProc);
ADMItemRef btnItem = sADMDialog->GetItem(dialog, IDC_BUTTON_OK);
sADMItem->SetNotifyProc(btnItem, OkButtonProc);
gPlugin->fLabel->fDialogRef = dialog;
gPlugin->fLabel->UpdateLayer();
gPlugin->fLabel->fFieldIndex = -1;
return error;
}
//清理列表
void MdLabel::ClearList(ADMListRef list)
{
ADMInt32 count = sADMList->NumberOfEntries(list);
for(ADMInt32 i = 0; i < count; i++)
{
sADMList->RemoveEntry(list, i);
}
}
//更新图层信息
void MdLabel::UpdateLayer()
{
vector<string> layerVec;
GetLayers(layerVec);
//设置源图层
ADMItemRef srcLayerItemRef = sADMDialog->GetItem(fDialogRef, IDC_COMBO_SRCLAYER);
ADMListRef srcLayerListRef = sADMItem->GetList(srcLayerItemRef);
ClearList(srcLayerListRef);
int index = 0;
for(vector<string>::iterator itr = layerVec.begin(); itr != layerVec.end(); ++itr)
{
ADMEntryRef entry = sADMList->InsertEntry(srcLayerListRef, index);
sADMEntry->SetText(entry, itr->c_str());
sADMEntry->SetID(entry, index++);
}
//设置目标图层
ADMItemRef desLayerItemRef = sADMDialog->GetItem(fDialogRef, IDC_COMBO_DESLAYER);
ADMListRef desLayerListRef = sADMItem->GetList(desLayerItemRef);
ClearList(desLayerListRef);
index = 0;
for(vector<string>::iterator itr = layerVec.begin(); itr != layerVec.end(); ++itr)
{
ADMEntryRef entry = sADMList->InsertEntry(desLayerListRef, index);
sADMEntry->SetText(entry, itr->c_str());
sADMEntry->SetID(entry, index++);
}
}
//列表选项变化
void ASAPI MdLabel::SrcLayerPopupProc(ADMItemRef item, ADMNotifierRef notifier)
{
if(sADMNotifier->IsNotifierType(notifier, kADMUserChangedNotifier))
{
ADMListRef listRef = sADMItem->GetList(item);
ADMEntryRef activeEntry = sADMList->GetActiveEntry(listRef);
ASInt32 layerId = sADMEntry->GetID(activeEntry);
AILayerHandle layer = nil;
sAILayer->GetNthLayer(layerId, &layer);
//改变源图层
gPlugin->fLabel->SrcLayerChange(layer);
//更新字段
gPlugin->fLabel->UpdateFields();
}
}