Инспектор объектов и метаданные

·Поле Name содержит имя published-свойства в инспектируемом объекте или в его заместителе. Доступ к свойствам основан на RTTI и требует, чтобы инспектируемые объекты (или их заместители) компилировались с созданием RTTI, ·Поле Caption содержит имя свойства, под которым оно будет отображаться в инспекторе, ·Kind. Это поле декларирует особенности отображения значения свойства в инспекторе, например, значение может быть текстом, списком, множеством, сложным объектом, который редактируется специальным редактором и так далее, ·Tag используется для задания специфических данных свойства. В текущей версии инспектора он использует только для описания свойств-множеств, ·NestedType и NestedClass. Два этих поля предоставляют альтернативные возможности указания типа вложенного свойства. Здесь целесообразно отметить, что вложенные свойства рассматриваются и описываются как самостоятельные - это позволяет описать их один раз и использовать в других классах метаданных. Забегая вперед, скажу что NestedType используется в том случае, если класс метаданных регистрируется в реестре метаданных, а NestedClass - если вложенный объект описывается в известном программном модуле и доступен при компиляции. Вложенное свойство трактуется весьма широко и, в общем случае, служит для ссылки на другой класс метаданных, который может быть действительно сложным объектом, или предоставлять метаданные об одном-единственном простом свойстве. Важным здесь является то, что классы метаданных могут ссылаться на другие метаклассы и создавать внутреннюю иерархическую структуру свойств инспектируемого объекта, ·Поля Help и Hint в особых комментариях не нуждаются. Поле Kind может принимать (в данной версии инспектора) следующие значения: ·pkText - значение свойства отображается как текст, доступный для редактирования, ·pkDropDownList - значение свойства доступно для выбора из списка возможных значений, ·pkDialog - значения свойства редактируются специализированным диалогом-мастером, ·pkFolder - фиктивное свойство, не имеющее значения, но позволяющее выстроить иерархический список дочерних подсвойств, ·pkReadOnlyText - аналогично pkText, но доступно только для чтения, ·pkImmediateText - аналогично pkText, но изменение значения свойства фиксируются немедленно при любом изменении текста, ·pkBoolean - свойство отображается как CheckBox, ·pkTextList - подобно pkDropDownList, но значение свойства можно редактировать, то есть, диапазон значений не ограничен списком, ·pkSet - свойство-множество, отображается как родительское для вложенного списка элементов множества, каждый из которых представляется как логическое значение, ·pkColor - свойство для выбора цвета из заданного списка, ·pkColorRGB - подобно предыдущему, но цвет задается и редактируется в виде R.G.B и имеется возможность выбора цвета с помощью стандартного Windows-диалога. Для иллюстрации всего сказанного приведем конкретный пример. Для простоты предположим, что мы будем инспектировать объекты всем известного типа TLabel. Причем, будем считать, что пользователю доступны для инспекции только свойства Caption, Font, Color, а также координаты и размеры. Класс метаданных для TLabel будет, в данном случае, таким:

type
 TLabel_INFO = class(TGsvObjectInspectorTypeInfo)
 public
  class function ChildrenInfo(Index: Integer):
  PGsvObjectInspectorPropertyInfo; override;
 end;
 class function TLabel_INFO.ChildrenInfo(Index: Integer):
  PGsvObjectInspectorPropertyInfo;
 const
  DSK: array[0..3] of TGsvObjectInspectorPropertyInfo = (
  ( Name: 'Caption'; Caption: 'Надпись'; Kind: pkImmediateText ),
  ( NestedClass: TGsvBounds_INFO ),
  ( Name: 'Font'; NestedType: 'TFont' ),
  ( Name: 'Color'; Caption: 'Цвет фона'; NestedType: 'TGsvColorRGB' )
  );
 begin
  if Index <= High(DSK) then Result := @DSK[Index]
  else  Result := nil;
 end;
Первый элемент массива метаданных описывает свойство Caption, для него задается вид pkImmediateText, чтобы любое изменение названия метки сразу же отображалось на форме. Второй элемент очень короток - это ссылка на другой метакласс, описывающий положение и размеры метки. В данном случае мы предполагаем, что метакласс TGsvBounds_INFO описан либо в текущем программном модуле, либо в другом модуле, указанном оператором uses. Отметим, что мы не задаем здесь никаких других аттрибутов, полагая, что они будут взяты из класса TGsvBounds_INFO, хотя можно было бы их явно указать - в этом случае инспектор использовал бы явно указанные аттрибуты, а не аттрибуты вложенного свойства. Следующий элемент подобен предыдущему, но для него мы указываем имя published-свойства, а имя метакласса передаем через поле NestedType, предполагая, что этот тип зарегистрирован в реестре метаданных. И, наконец, последний элемент - цвет, для которого мы указываем имя свойства, название и имя класса, который реализует функциональность по представлению значения цвета в виде RGB. Последнее, что мы должны сделать, чтобы объекты типа TLabel были доступны для инспекции,- это зарегистрировать класс TLabel_INFO в реестре метаданных. Удобнее всего это можно сделать так:
initialization
 GsvRegisterTypeInfo(TLabel_INFO);

Поскольку в предложенном описании даны ссылки на другие метаклассы, то продолжим пример и предоставим их реализацию.

type

 TGsvBounds_INFO = class(TGsvObjectInspectorTypeInfo)

  public

  class function TypeInfo: PGsvObjectInspectorPropertyInfo; override;

  class function ChildrenInfo(Index: Integer):

  PGsvObjectInspectorPropertyInfo; override;

  end;

 class function TGsvBounds_INFO.TypeInfo: PGsvObjectInspectorPropertyInfo;

 const

  DSK: TGsvObjectInspectorPropertyInfo = (

  Caption: 'Положение и размер'; Kind: pkFolder;

  Help: 1234; Hint: 'Координаты верхнего левого угла и размеры'

  );

 begin

  Result := @DSK;

 end;

 class function TGsvBounds_INFO.ChildrenInfo(Index: Integer):

  PGsvObjectInspectorPropertyInfo;

 const

  DSK: array[0..3] of TGsvObjectInspectorPropertyInfo = (

  ( Name: 'Left'; Caption: 'Левый край'; Kind: pkText ),

  ( Name: ''; Caption: 'Верхний край'; Kind: pkText ),

  ( Name: 'Width'; Caption: 'Ширина'; Kind: pkText ),

  ( Name: 'Height'; Caption: 'Высота'; Kind: pkText )

  );

 begin

  if Index <= High(DSK) then Result := @DSK[Index]

  else  Result := nil;

 end;

Метакласс TGsvBounds_INFO перегружает два метода базового класса. Метод TypeInfo возвращает указатель на метаданные всего класса в целом. Это позволяет задать аттрибуты свойства в одном метаклассе и ссылаться на них из множества других метаклассов. Метод возвращает указатель на константную запись, в которой мы задаем название, вид поля и справочную информацию о свойстве. Метод ChildrenInfo описывает координаты верхнего левого угла прямоугольника и его размеры, ссылаясь на соответствующие published-свойства компонента. Метакласс для шрифта будет задавать имя шрифта, его размер, стиль и цвет:

type

 TFont_INFO = class(TGsvObjectInspectorTypeFontInfo)

 public

  class function TypeInfo: PGsvObjectInspectorPropertyInfo; override;

  class function ChildrenInfo(Index: Integer):

  PGsvObjectInspectorPropertyInfo; override;

 end;

 class function TFont_INFO.TypeInfo: PGsvObjectInspectorPropertyInfo;

 const

  DSK: TGsvObjectInspectorPropertyInfo = (

  Caption: 'Шрифт'; Kind: pkDialog

  );

 begin

  Result := @DSK;

 end;

 class function TFont_INFO.ChildrenInfo(Index: Integer):

  PGsvObjectInspectorPropertyInfo;

 const

  DSK: array[0..3] of TGsvObjectInspectorPropertyInfo = (

  ( Name: 'Name'; Caption: 'Имя'; Kind: pkText;

  Hint: 'Имя шрифта' ),

  ( Name: 'Size'; Caption: 'Размер'; Kind: pkText;

  Hint: 'Размер в пунктах' ),

  ( Name: 'Style'; Caption: 'Стиль'; Kind: pkSet;

  NestedClass: TFontStyles_INFO ),

  ( Name: 'Color'; Caption: 'Цвет'; Kind: pkColor;

  NestedClass: TGsvColor16_INFO )

  );

 begin

  if Index <= High(DSK) then Result := @DSK[Index]

  else  Result := nil;

 end;

Отправить комментарий

Проверка
Антиспам проверка
Image CAPTCHA
...