Настройка внешнего вида и поведения UniLines

Для 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 реализованы на текущий момент следующие функции/процедуры:

  • function GetCheckedValues(const ValueName: string; GetSQLStr: boolean = True; Delimiter: string = ','): string; - через указанный разделитель собирает все значения ValueName, у которых отмечены галочки;
  • procedure SetCheckedValues(ValueName, Checked: string; Delimiter: string = ','); - всем значениям, которые соответствуют указанным через Delimiter ValueName, выставить значение Checked;
  • procedure CheckAll; - проставить галочки у всех нод;
  • procedure UnCheckAll; - убрать галочки у всех нод;
  • procedure Inversion; - инвертировать галочки у всех нод.

Изменение галочек осуществляется через свойство ноды 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;

У нас реализованы функции и процедуры:

  • function SelectedCount: int64; - возвращает количество выбранных нод;
  • function TUniLinesFrame.GetIDsFromSel: string; - получает список значений PrimaryValue выбранных нод через запятую;
  • procedure TUniLinesFrame.SelectAll; - выбрать все ноды;
  • procedure TUniLinesFrame.SelectLastNode; - выбрать последнюю ноду;
  • procedure LastLine(FirstVisible: boolean = True); - выбрать последнюю строку;
  • procedure PrevLine(PrevVisible: boolean = 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;

  • ACaption - Название пункта меню;
  • AOnClick - событие при клике;
  • AImageIndex - номер иконки (берётся из ImgDMForm.ilAll);
  • AVisible - видимость пункта меню;
  • DoHookPopup - позволяет отрисовывать меню в скине.

Из интересного тут появляется возможность рулить видимостью пункта меню.

Пример:

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;

  • ACaption - название кнопки;
  • AAfterPosition - позиция кнопки (есть значения tpsEndButtons = 0 - после всех основных кнопок и tpsEndCheckbox = 1 - после всех чекбоксов);
  • AImageIndex - индекс картинки, берётся из ImgDMForm.ilAll;
  • AOnClick - событие нажатия;
  • AIsCheck - должна ли кнопка быть чекбоксом.

Пример:

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, который можно получить для какой-либо обработки. В этой процедуре у ноды можно изменить её текст.

Пройти тест

Назад