Creating the Color Combo Box Inspector Panel
Graphic object inspectors derive from the class IlvStInspectorPanel. Since in our example, the inspected graphic object is also a gadget, the inspector panel we are going to create derives from IlvStIGadgetInspectorPanel, a subclass of IlvStInspectorPanel.
class IlvColorComboBoxInspectorPanel
: public IlvStIGadgetInspectorPanel {
public:
IlvColorComboBoxInspectorPanel(IlvManager* manager,
IlvSystemView transientFor = 0,
IlvStIAccessor::UpdateMode =
IlvStIAccessor::OnApply);
virtual void initializeEditors();
};
As we said in the section Components of an Inspector Panel, inspector panels are implemented with accessors and editors. These must be declared in the method initializeEditors. In our example, the definition of this method is divided in two parts, corresponding each to the implementation of the two notebook pages that make up the inspector panel (see Pages of the Color Combo Box Inspector Panel). These pages are described in the following two sections.
Note: The General and Callback pages are created automatically.
Implementing the Specific Page
The Specific page has been designed to inspect the following properties:
*Color name offset  Specifies the offset used to display the name of the color. This property is defined by the following value:
IlvListGadgetItemHolder::_labelOffsetValue
*Color rectangle horizontal margin  Specifies the margin between the vertical border of the color rectangle and the border of the gadget item. This property is defined by the following value:
IlvColorDrawInfo::_HColorRectMarginValue
*Color rectangle vertical margin  Specifies the margin between the horizontal border of the color rectangle and the border of the gadget item. This property is defined by the following value:
IlvColorDrawInfo::_VColorRectMarginValue
*Small rectangle  Specifies whether the color rectangle in the gadget item should be drawn in the margin specified by the color name offset property or occupy the whole gadget item. The property is defined by the following value:
IlvColorDrawInfo::_SmallColorRectValue
*Rounded rectangle radius  Specifies the radius applied to the rectangle corners. For the purpose of this example, this property is ignored if the small rectangle property has been set. The property is defined by the following value:
IlvColorDrawInfo::_ColorRoundRectRadius
*Visible items  Specifies which items appear in the drop-down list of the combo box. The property is defined by the following value:
IlvScrolledComboBox::_nbVisibleItemsValue
*Enable large list option  Specifies the “Enable large list” option for the combo box. For details about this option, see the class IlvScrolledComboBox in the Views Reference Manual. The property is defined by the following value:
IlvScrolledComboBox::_largeListValue
To inspect the above properties, you must define the initializeEditors member function as follows:
void
IlvColorComboBoxInspectorPanel::initializeEditors()
{
 
// Color name offset.
link("ColorNameOffset", IlvListGadgetItemHolder::_labelOffsetValue);
 
// Horizontal margin.
link("XColorMargin", IlvColorDrawInfo::_HColorRectMarginValue);
 
// Vertical margin.
link("YColorMargin", IlvColorDrawInfo::_VColorRectMarginValue);
 
// Small rectangle editor.
link("SmallRect", IlvColorDrawInfo::_SmallColorRectValue);
 
// Rounded rectangle editor.
link("RoundRadius", IlvColorDrawInfo::_ColorRoundRectRadius);
 
// Visible items.
link("ComboVisibleItems", IlvScrolledComboBox::_nbVisibleItemsValue);
}
The link method automatically builds an editor and associates it with the gadget whose name is passed as its first parameter. It also creates an accessor to the property provided as its second parameter. It then links the editor and the accessor, which will be used in conjunction to inspect the property. For more information about this function, refer to the class IlvStInspectorPanel in the reference manual.
Previewing Changes
The changes made to the color combo box properties via the inspector panel can be reflected in a preview gadget. To achieve this, you have to create an accessor to the gadget that you decide to use as the preview gadget. To create this accessor, we recommend that you use the class IlvStIGraphicContainerAccessor. Once this is done, you register the accessor as the preview accessor to the inspected property using the setPreviewAccessor or setPreviewValueAccessor member functions (IlvStIEditor and IlvStIPropertyAccessor). Here is what you should do to implement a preview gadget for the properties mentioned earlier in this section:
void
IlvColorComboBoxInspectorPanel::initializeEditors()
{
IlvStIPropertyAccessor* previewGadgetAcc =
new IlvStIGraphicContainerAccessor(getHolder(), "ColorItemsList");
IlvStIEditor* editor;
 
// Color name offset.
editor = link("ColorNameOffset",
IlvListGadgetItemHolder::_labelOffsetValue);
editor->setPreviewValueAccessor(
previewGadgetAcc,
IlvListGadgetItemHolder::_labelOffsetValue);
 
// Horizontal margin.
editor = link("XColorMargin", IlvColorDrawInfo::_HColorRectMarginValue);
editor->setPreviewValueAccessor(previewGadgetAcc,
IlvColorDrawInfo::_HColorRectMarginValue);
 
// Vertical margin.
editor = link("YColorMargin", IlvColorDrawInfo::_VColorRectMarginValue);
editor->setPreviewValueAccessor(previewGadgetAcc,
IlvColorDrawInfo::_VColorRectMarginValue);
 
// Small rectangle editor.
editor = link("SmallRect", IlvColorDrawInfo::_SmallColorRectValue);
editor->setPreviewValueAccessor(previewGadgetAcc,
IlvColorDrawInfo::_SmallColorRectValue);
 
// Rounded rectangle editor.
editor = link("RoundRadius", IlvColorDrawInfo::_ColorRoundRectRadius);
editor->setPreviewValueAccessor(previewGadgetAcc,
IlvColorDrawInfo::_ColorRoundRectRadius);
}
Using Preconditions
Earlier in this section, we said that the Rounded rectangle radius property is ignored when the small rectangle property is set. The following code shows you how to implement this condition:
// Small rectangle editor.
editor = link("SmallRect", IlvColorDrawInfo::_SmallColorRectValue);
IlvStIPropertyAccessor* smallRectAcc =
(IlvStIPropertyAccessor*)editor->getAccessor();
 
// Rounded rectangle editor.
editor = link("RoundRadius", IlvColorDrawInfo::_ColorRoundRectRadius);
editor->getAccessor()->setPrecondition(
new IlvStIPreconditionValue(smallRectAcc,
IlFalse, (IlvInt)0));
...
Implementing the Items Page
The Items page allows the user to edit the list of colors displayed in the combo box. To handle the list of colors, we must first define a list accessor by deriving the class IlvStIPropertyListAccessor, as illustrated below. List accessors are described in the List Accessors.
class IlvColorItemsAccessor
: public IlvStIPropertyListAccessor {
public:
// ----------------------------------------------------------------------
// Constructor / destructor
....
// ----------------------------------------------------------------------
IlvListGadgetItemHolder* getListGadgetItemHolder() const;
 
protected:
IlvGadgetItem* getGadgetItem(const IlvStIProperty* property) const;
 
virtual IlvStIProperty** getInitialProperties(IlUInt& count);
virtual IlvStIProperty* createDefaultProperty() const;
virtual void addProperty(IlvStIProperty* property, IlUInt index);
virtual void replaceProperty(IlvStIProperty* origProperty,
IlvStIProperty* newProperty,
IlUInt index);
virtual void deleteNewProperty(IlvStIProperty* property);
virtual void deleteProperty(IlvStIProperty* property, IlUInt index);
};
The getListGadgetItemHolder method returns the gadget item holder that contains the colors to be displayed. This value is the one returned by the IlvStIPropertyAccessor passed to the constructor.
IlvListGadgetItemHolder*
IlvColorItemsAccessor::getListGadgetItemHolder()const
{
IlvStIProperty* property = (_accessor? _accessor->get() : 0);
return (property? (IlvListGadgetItemHolder*)property->getPointer() : 0);
}
The getGadgetItem method returns the gadget item stored in the property provided as its parameter.
IlvGadgetItem*
IlvColorItemsAccessor::getGadgetItem(const IlvStIProperty* property)const
{
return (IlvGadgetItem*)(property? property->getPointer() : 0);
}
The getInitialProperties method returns an array of properties which corresponds to the initial colors contained in the combo box.
IlvStIProperty**
IlvColorItemsAccessor::getInitialProperties(IlUInt& count)
{
IlvListGadgetItemHolder* listHolder = getListGadgetItemHolder();
if (!listHolder)
return 0;
 
count = (IlUInt)listHolder->getCardinal();
if (!count)
return 0;
IlvStIProperty** properties = new IlvStIProperty*[count];
for(IlUInt i = 0; i < count; i++) {
properties[i] =
new IlvStIValueProperty(
(IlvAny)listHolder->getItem((IlvUShort)i), "Item");
}
return properties;
}
The createDefaultProperty method is called when the user presses the Add button to create a new color. By default, this color is black.
IlvStIProperty*
IlvColorItemsAccessor::createDefaultProperty() const
{
IlvListGadgetItemHolder* listHolder = getListGadgetItemHolder();
if (!listHolder)
return 0;
IlvValue valueInfo(IlvColorDrawInfo::_ColorInfosValue->name());
IlvColorDrawInfo* colorInfo = (IlvColorDrawInfo*)(IlvAny)
listHolder->getGadget()->queryValue(valueInfo);
return new IlvStIValueProperty(
new IlvColorGadgetItem(listHolder->getGadget()->
getDisplay()->getColor("Black"),
colorInfo),
"Item");
}
The addProperty method is called when changes are applied to add the gadget item contained in the property given as its first parameter to the position specified by the index parameter. The gadget item is added to the combo box.
void
IlvColorItemsAccessor::addProperty(IlvStIProperty* property, IlUInt index)
{
IlvListGadgetItemHolder* listHolder = getListGadgetItemHolder();
if (listHolder)
listHolder->insertItem(getGadgetItem(property),
(IlvShort)(IlvUShort)index);
}
The replaceProperty method is called when changes are applied to replace the gadget item contained in the property given as its first parameter by the gadget item contained in the property given as its second parameter. The third parameter indicates the position of the replaced gadget item in the combo box.
void
IlvColorItemsAccessor::replaceProperty(IlvStIProperty* origProperty,
IlvStIProperty* newProperty,
IlUInt)
{
IlvListGadgetItemHolder* listHolder = getListGadgetItemHolder();
if (!listHolder)
return;
IlvGadgetItem* origGadgetItem = getGadgetItem(origProperty);
IlvGadgetItem* newGadgetItem = getGadgetItem(newProperty);
*(origGadgetItem) = *newGadgetItem;
newProperty->setPointer(origGadgetItem);
}
The deleteNewProperty method deletes the gadget item contained in the property passed as its parameter. This method is invoked when the changes made by the user are cancelled, to destroy the gadget item created by pressing the Add button. Since this gadget item is not actually added to the combo box, it does not have to be removed from it.
void
IlvColorItemsAccessor::deleteNewProperty(IlvStIProperty* property)
{
IlvGadgetItem* gadgetItem = getGadgetItem(property);
if (gadgetItem)
delete gadgetItem;
}
The deleteProperty method is called when changes are applied to remove the gadget item contained in the property given as the parameter from the color combo box.
void
IlvColorItemsAccessor::deleteProperty(IlvStIProperty*, IlUInt index)
{
IlvListGadgetItemHolder* listHolder = getListGadgetItemHolder();
if (!listHolder)
return;
listHolder->removeItem((IlvShort)(IlvUShort)index);
}
Reusing the Color List Accessor
As we have seen throughout the example, the list accessor does not access the combo box directly but through its gadget item holder. The same list accessor can therefore be reused to inspect a color string list. To access the gadget item holder of the inspected combo box, we just have to create a combined accessor, as shown in the following code sample. For a description of combined accessors, see the section Combined Accessors. This combined accessor will be provided as a parameter to the IlvColorItemsAccessor constructor.
class IlvColorGadgetItemHolderAccessor
: public IlvStICombinedAccessor
{
public:
IlvColorGadgetItemHolderAccessor(IlvStIPropertyAccessor* accessor = 0,
UpdateMode updateMode = NoUpdate,
BuildMode buildMode = None,
const char* name = 0);
// ----------------------------------------------------------------------
protected:
virtual IlvStIProperty* getOriginalValue();
};
 
IlvStIProperty*
IlvColorGadgetItemHolderAccessor::getOriginalValue()
{
IlvStIProperty* property =
(getObjectAccessor()? getObjectAccessor()->get() : 0);
if (!property)
return 0;
IlvColorComboBox* combo = (IlvColorComboBox*)property->getPointer();
if ((!combo) || (!combo->getStringList()))
return 0;
return new IlvStIValueProperty((IlvListGadgetItemHolder*)combo,
"ColorHolder");
}
The class IlvColorItemsAccessor is used in the inspector panel in the following way:
IlvColorItemsAccessor* lstAccessor =
new IlvColorItemsAccessor(
new IlvColorGadgetItemHolderAccessor(getInspectedGraphicAccessor()));
Modifying Colors in the List
In the previous section, we explained how to access a list of colors. We are now going to modify a color selected in the list. To do so, we define a class that lets us inspect the color of an IlvColorGadgetItem gadget item. Since the color is defined by the gadget item label, changing the label implies changing the color.
class IlvGadgetItemColorAccessor
: public IlvStICombinedAccessor
{
public:
...
// ----------------------------------------------------------------------
protected:
IlvGadgetItem* getGadgetItem() const;
virtual IlvStIProperty* getOriginalValue();
virtual void applyValue(IlvStIProperty*);
};
 
IlvGadgetItem*
IlvGadgetItemColorAccessor::getGadgetItem() const
{
IlvStIProperty* property =
(getObjectAccessor()? getObjectAccessor()->get() : 0);
return (property? (IlvGadgetItem*)property->getPointer() : 0);
}
 
IlvStIProperty*
IlvGadgetItemColorAccessor::getOriginalValue()
{
IlvGadgetItem* gadgetItem = getGadgetItem();
if (!gadgetItem
return 0;
return new IlvStIValueProperty(gadgetItem->getLabel(), "Color");
}
 
void
IlvGadgetItemColorAccessor::applyValue(IlvStIProperty* property)
{
IlvGadgetItem* gadgetItem = getGadgetItem();
if (!gadgetItem)
return;
IlvValue value;
gadgetItem->setLabel((const char*)property->getValue(value));
}
This class is used in the inspector panel code as follows:
editor = new IlvStIPropertyColorEditor("EditColorItem",
new IlvGadgetItemColorAccessor(lstAccessor->getSelectionAccessor()));
addEditor(editor);
The class IlvStIPropertyColorEditor interfaces with a selection field to make it possible to select a color. The label that appears in the selection field represents the name of the selected color.
Creating the Color List Editor
To display a list of items, it is common practice to use an IlvStringList, which is handled by an IlvStIPropertyListEditor. However in the case of our example, we want the list to display color gadget items instead of character strings. We have implemented such list using the class IlvColorStringList, a subclass of IlvStringList. To interface this new class, we have defined the following editor class:
class IlvColorListEditor
: public IlvStIPropertyListEditor {
public:
// ----------------------------------------------------------------------
// Constructor / destructor
...
// ----------------------------------------------------------------------
// Overridables.
virtual IlBoolean connectHolder(IlvGraphicHolder* holder);
protected:
virtual IlvGadgetItem* createGadgetItem(
const IlvStIProperty* property) const;
};
 
IlBoolean
IlvColorListEditor::connectHolder(IlvGraphicHolder* holder)
{
// Replaces string list of colors by an IlvColorStringList.
IlvGraphicHolder* subHolder;
IlvGadget* oldList =
(IlvGadget*)IlvStIFindGraphic(holder, getName(), &subHolder);
if (!oldList)
return IlvStIPropertyListEditor::connectHolder(holder);
IlvRect bbox;
oldList->boundingBox(bbox);
IlvColorStringList* colorList =
new IlvColorStringList(oldList->getDisplay(),
bbox,
oldList->getThickness(),
oldList->getPalette());
colorList->useFullSelection(IlTrue, IlFalse);
colorList->setSelectionMode(IlvStringListSingleSelection);
colorList->setExclusive(IlTrue);
colorList->scrollBarShowAsNeeded(IlTrue, IlTrue, IlFalse);
subHolder->getContainer()->replace(oldList, colorList, IlTrue);
 
return IlvStIPropertyListEditor::connectHolder(holder);
}
 
IlvGadgetItem*
IlvColorListEditor::createGadgetItem(const IlvStIProperty* property) const
{
IlvGadgetItem* gadgetItem = (IlvGadgetItem*)property->getPointer();
if (!gadgetItem)
return 0;
IlvValue valueInfo(IlvColorDrawInfo::_ColorInfosValue->name());
IlvColorDrawInfo* colorInfo =
(IlvColorDrawInfo*)(IlvAny)getListGadget()->queryValue(valueInfo);
IlvGadgetItem* newGadgetItem =
new IlvColorGadgetItem(getDisplay()->getColor(gadgetItem->getLabel()),
colorInfo);
newGadgetItem->setEditable(IlFalse);
return newGadgetItem;
}
Declaring Accessors and Editors for Inspecting Color Items to the Inspector Panel
Accessors and editors for inspecting color items are declared in the initializeEditors method as follows:
IlvColorItemsAccessor* lstAccessor =
new IlvColorItemsAccessor(
new IlvColorGadgetItemHolderAccessor(getInspectedGraphicAccessor()));
addEditor(new IlvColorListEditor(lstAccessor, "ColorItemsList"));
IlvStIEditor* editor =
new IlvStIPropertyColorEditor("EditColorItem",
new IlvGadgetItemColorAccessor(lstAccessor->getSelectionAccessor()));
addEditor(editor);
Published date: 05/24/2022
Last modified date: 02/24/2022