Для UniLines-а уже разработаны и предусмотрены различные варианты кастомизации его работы.
В целом, их можно разделить на следующие группы:
UniLines позволяет отобразить элементы в виде галочек. Например, как это сделано в модуле DiscExt.pas (внешняя дисконтная схема), для отображения таблицы со скидками на каждую группу слуг.
Включение галочного представления осуществляется за счёт опции ShowCheckBoxes (по умолчанию False).
Включение этой опции, по сути, для каждой ноды VST выставляет свойство CheckType := ctCheckBox.
Опция IsTriStateCheckBoxes отвечает за возможность отображать «смешанное» состояние чекбокса (когда у дочерних элементов как стоят галочки, так и не стоят):
В коде обработка происходит следующим образом:
procedure TUniLinesFrame.SetShowCheckBoxes(const Value: boolean); var Node: PVirtualNode; begin FShowCheckBoxes := Value; //присвоение опции Node:=VST.GetFirst; //получаем указатель на первую ноду while Node<>nil do //в цикле по всем нодам begin if FShowCheckBoxes then //для каждой выставляем CheckType либо ctNone (без чекбокса), либо ctCheckBox (два состояния), либо ctTriStateCheckBox (три состояния). if FIsTriStateCheckBoxes then VST.CheckType[Node]:=ctTriStateCheckBox else VST.CheckType[Node] := ctCheckBox else VST.CheckType[Node]:=ctNone; Node:=VST.GetNext(Node); end; end; //для новых нод тоже анализируется эта опция, чтобы сразу им выставить CheckType. function TUniLinesFrame.AddData(ANode: PVirtualNode = nil): PLinesData; var Node: PVirtualNode; i: integer; begin if ANode=nil then begin Node:=VST.AddChild(nil); if FIsMultiline then Node.States:=Node.States+[vsMultiline]; end else Node:=ANode; if FShowCheckBoxes then if FIsTriStateCheckBoxes then VST.CheckType[Node]:=ctTriStateCheckBox else VST.CheckType[Node] := ctCheckBox; //... и т.д. end;
Опция ShowCustomCheckBoxes позволяет подгрузить специальные иконки для чекбоксов. У нас они берутся из ImgDMForm.ilChecksTree32:
begin FShowCustomCheckBoxes := Value; if FShowCustomCheckBoxes then begin vst.CustomCheckImages:=ImgDMForm.ilChecksTree32; vst.CheckImageKind:=ckCustom; vst.DefaultNodeHeight:=Max(vst.DefaultNodeHeight, ScaleMeasure(40)); end else begin vst.CheckImageKind:=ckXP; vst.CustomCheckImages:=nil; end; end;
Для работы с чекбоксами в рамках UniLines реализованы на текущий момент следующие функции/процедуры:
Изменение галочек осуществляется через свойство ноды CheckState, например:
procedure TUniLinesFrame.CheckAll; var Node: PVirtualNode; begin if not FShowCheckBoxes then Exit; Node:=VST.GetFirst; while Node<>nil do begin if Node.CheckState<>csCheckedNormal then Node.CheckState:=csCheckedNormal; Node:=VST.GetNext(Node); end; end;
Выбранной нодой, если по-простому, можно считать ту ноду, по которой случился клик. Через ctrl выбранных нод может оказаться несколько:
Основное управление выбранными нодами осуществляется через VST, например
VST.Selected[LastNode] := True;
У нас реализованы функции и процедуры:
Для UniLines-а предусмотрено несколько методов, позволяющих добавить кастомные кнопки и элементы меню, чтобы можно было сделать уникальное поведение этого фрейма на разных формах, без необходимости изменения в дизайн-тайме.
Имеется в виду меню, возникающее по правому клику на заголовке:
Реализовано с помощью функции
function AddHeaderMenuItem(const ACaption: string; AAutoCheck, AChecked: boolean; AOnClick: TNotifyEvent; InMenu: TMenuItem; DoHookPopup: boolean = True): TMenuItem;
* ACaption - Название меню; * AAutoCheck - позволяет автоматически менять свойство Checked при клике; * AChecked - позволяет работать с меню, как с чекбоксом; * AOnClick - событие, которое должно сработать при нажатии на кнопку; * InMenu - ссылка на объект меню, внутри которого должен создаться новый объект; * DoHookPopup - позволяет отрисовывать меню в скине.
Пример:
it:=UDL.ULF.AddHeaderMenuItem('Показывать только с остатками', True, False, OnShowOnlyRestClick, nil); procedure TTovarsModalForm.OnShowOnlyRestClick(Sender: TObject); var st: TSetting; begin //st := DMForm.SettingList.GetSetting(dkObject,MetaObject_Tag,'SHOW_ONLY_AT_CUR_SCLAD',dtBoolean); st := DMForm.SettingList.GetSetting(dkObject,MetaObject_Tag,'SHOW_ONLY_REST',dtBoolean); if st<>nil then begin if Sender<>nil then begin st.AsBoolean := TMenuItem(Sender).Checked; st.Save(RdTr, UpTr); end; ShowOnlyRest := st.AsBoolean; end; RefreshAll; end;
Имеется в виду окно, возникающее при правом клике на элементе UniLines
Реализация выполнена с помощью
function AddPopupMenuItem(const ACaption: string; AOnClick: TNotifyEvent; AImageIndex: integer; AVisible: boolean = True; DoHookPopup: boolean = True): TMenuItem;
Из интересного тут появляется возможность рулить видимостью пункта меню.
Пример:
ULF.AddPopupMenuItem('Переотправить сообщение', ResendSMS, -1); //процедура срабатывает при получении состояний дерева, находит нужный элемент меню и меняет его видимостью procedure TSMSLogForm.ULFVSTStateChange(Sender: TBaseVirtualTree; Enter, Leave: TVirtualTreeStates); var it: TMenuItem; i: integer; begin if ULF.Value['ID'] <> Null then begin for i := ULF.VST.PopupMenu.Items.Count - 1 downto 0 do begin it := TMenuItem(ULF.VST.PopupMenu.Items[i]); if it.Caption = Translat('Переотправить сообщение') then begin it.Visible := ((ULF.Value['oper_status'] = 'СМС заблокировано химчисткой') or (ULF.Value['oper_status'] = 'Не доставлено')); break; end; end; end; end;
Имеется в виду вот эта область:
Реализовано с помощью
function AddToolbarButton(const ACaption: string; AAfterPosition: integer; AImageIndex: integer; AOnClick: TNotifyEvent; AIsCheck: boolean = False): TsSpeedButton;
Пример:
AddToolbarButton('Отправка документов', tpsEndCheckbox, 47, btEmailClick); procedure TInvoicesForm.btEmailClick(Sender: TObject); var frm: TInvoicesSendEmailForm; begin Application.CreateForm(TInvoicesSendEmailForm, frm); try if frm.ShowModal in [mrOK, mrCancel] then begin if frm.IsSendMail then acRefreshExecute(self); end; finally frm.Free; end; end;
Под стандартными подразумеваются кнопки «Создать», «Изменить», «Редактировать», «Печать» и прочие подобные, а также соответствующие им элементы выпадающего меню.
В UniLines-е предусмотрено множество вариаций по их отображению, также как и отображение целых панелей. Подробно рассматривать не будем, названия должны понятно отражать их суть.
property ShowPopupMenu: boolean read FShowPopupMenu write SetShowPopupMenu; property ShowToolbar: boolean read FShowToolbar write SetShowToolbar; property ShowToolbarAndPopup: boolean read FShowToolbarAndPopup write SetShowToolbarAndPopup; property ShowToolbarOnlyLoadSave: boolean read FShowToolbarOnlyLoadSave write SetShowToolbarOnlyLoadSave; property ShowToolbarHorizontalSelectUnselect: boolean read FShowToolbarHorizontalSelectUnselect write SetShowToolbarHorizontalSelectUnselect; property ShowOnlyAddButtons: Boolean read GetShowAddButton write SetShowAddButton; property ShowOnlyParentButtons: Boolean read GetShowParentButton write SetShowParentButton; property ShowOnlyEditButtons: Boolean read GetShowCorrButton write SetShowCorrButton; property ShowOnlyDelButton: Boolean read GetShowDelButton write SetShowDelButton; property ShowAddEditButtons: Boolean read GetShowAddCorrButtons write SetShowAddCorrButtons; property ShowAddDelButtons: Boolean read GetShowAddDelButtons write SetShowAddDelButtons; property ShowEditButtons: Boolean read GetShowAllEditButtons write SetShowAllEditButtons;
Также, в UniLines-е возможно настраивать ячейки с информацией, правила её отображения и возможность изменения.
property IsMultiline: boolean - добавляет всем нодам настройку vsMultiline (Node.States:=Node.States+[vsMultiline]), поддерживающую многострочность текста в соответствии с шириной колонки; property IsHtml: boolean - при True позволяет обрабатывать html-теги, а также позволяет подключить ряд опций по обработке текста; property FullText: boolean - при True предотвращает обрезание текста, в противном случае весь невлезший текст будет заменён многоточием (только для IsHtml = True); property FullTextIsCenter: boolean - при True центрирует текст по высоте (только для IsHtml = True); property SmallNodeHeight: boolean - нода имеет фиксированную высоту (25 пикселей), иначе 37; её включение блокирует опцию AutoCalcHodeHeight; property AutoCalcHodeHeight: boolean - автоматический расчёт требуемой высоты ноды (только для IsHtml = True); property MinNodeHeight: integer - если не равен 0, то выступает в качестве значения высоты ноды при включённой SmallNodeHeight (только для IsHtml = True);
Таким образом, в стандартном ULF разрешается только многострочность и ручная регулировка высоты ноды. Но при включении IsHtml становится возможным серьёзно управлять отображением текста.
property AutoEdit: boolean - включает возможность редактирования колонок (при клике на ней можно вписать своё значение). Вызывает процедуру VST.EditNode
При редактировании появляется возможность использовать несколько полезных обработчиков:
procedure VSTEditing(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; var Allowed: Boolean); - перед редактированием колонки Column можно изменить её Allowed, чтобы запретить/разрешить редактирование; procedure VSTNewText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; NewText: String); - срабатывает, когда в колонке Column появляется NewText, который можно получить для какой-либо обработки. В этой процедуре у ноды можно изменить её текст.