Watch, Follow, &
Connect with Us

The official blog of Sergey Roschin

MultiResBitmap Editor usage

The small filmloop TELLING about the MultiResBitmap Editor usage. Storyteller is Vsevolod Leonov

То же но с субтитрами на великом и могучем:

Posted by roschinspb on February 3rd, 2014 under Image | 3 Comments »


Всплывающие формы в XE5

TCommonCustomForm.FormStyle

В XE5, вместо свойств StaysOpen, ShowActivated и TopMost появилось свойство FormStyle. Это свойство управляет поведением формы как и аналогичное свойство в VCL (не путайте со StyleBook, которое управляет визуальными стилями формы). Может принимать одно из трех значений:

TFormStyle = (fsNormal, fsPopup, fsStayOnTop);

Смысл fsNormal и fsStayOnTop довольно очевиден. Это обычная форма и форма которая находится всегда поверх обычных форм. Если раньше было установлено свойство TopMost, то FormStyle получит значение TFormStyle.fsStayOnTop.

Два значения fsMDIForm и fsMDIChild отсутствуют, т. к. эти значения могли бы использоваться только в Windows.

Интерес я думаю представляет значение fsPopup. Это особая форма которая используется в комбинированных списках и меню. Если раньше одно из свойств StaysOpen, или ShowActivated имело значение False, то FormStyle получит значение TFormStyle.fsPopup.

Всплывающая форма имеет отличное от других форм поведение:

  • Не может быть активной. В классе TScreen, всплывающие формы находятся в отдельном списке, см. TScreen.PopupForms и TScreen.PopupFormCount.
  • На мобильных платформах обычные формы всегда находятся в полноэкранном режиме, но к всплывающим формам это не относится.
  • Не остаётся видимой длительное время. Если кликнуть мышью (или пальцем на тачпаде) вне границ всплывающей формы, то она закроется. На экране может быть несколько всплывающих форм, связанных (или не связанных) как родительская-дочерняя. Если кликнуть на одну из всплывающих форм, то закроются все всплывающие формы кроме этой формы и всех её родителей.

Для всплывающих форм, также характерны следующие значения свойств:

BorderStyle := TFmxFormBorderStyle.bsNone; // Отсутствует рамка окна
Popup.Transparency := True;  // Форма имеет прозрачный фон

TCommonCustomForm.ParentForm

Для определения "родственных связей" форм, добавлено свойство ParentForm. Значение этого свойства устанавливается, когда Вы меняете свойство Parent. Если объект Parent является формой, он же будет использован в качестве ParentForm, иначе будет определена форма на которой лежит объект Parent.
После изменения ParentForm выполняется виртуальный метод DoParentFormChanged.

Надо отметить, что изменение таких свойств как FormStyle, BorderStyleParentForm, приводит к пересозданию формы и всех контролов на ней и всех дочерних форм. Поэтому я не рекомендую менять эти свойства в Run-time, после того как форма уже была отображена на экране.

TCustomPopupForm

Для упрощения создания всплывающих форм, создан специальный класс форм TCustomPopupForm, который используется в TPopup, TComboEdit, TPopupBox, TMenuBar и т.п. У форм данного класса по умолчанию нет рамки и фона. После закрытия происходит автоматическое разрушение. При создании не производится поиск fmx-файла формы, т. е. этот класс ориентирован только на работу в Run-time.

Поскольку у форм данного класса не видны ни рамка ни фон и они не должны выходить за границы экрана, физические координаты окна не имеют большого практического значения. Управление расположением формы осуществляется с помощью других свойств: PlacementPlacementTargetPlacementRectangle, Size. Самостоятельно менять Position, Height, Width не надо.

Экземпляры таких форм создаются с использованием конструктора:

constructor Create(AOwner: TComponent; AStyleBook: TStyleBook = nil; APlacementTarget: TControl = nil); reintroduce;

Здесь AStyleBook указывает стили используемые формой, а APlacementTarget указывает контрол рядом с которым должна появиться форма.

PlacementTarget — некоторый контрол в окрестностях которого, определенным образом располагается форма (здесь и далее для обозначения такого размещения позвольте использовать слово "прилипать"). Если он задан, то расчет экранных координат формы осуществляется относительно данного контрола, иначе относительно левого верхнего угла экрана.

PlacementRectangle — координаты прямоугольника к которому осуществляется "прилипание" формы. Расчет экранных координат PlacementRectangle, осуществляется относительно PlacementTarget если он задан, иначе относительно левого верхнего угла экрана.

  • Если PlacementRectangle не задан (ширина, или высота равны 0), но задан PlacementTarget, то используются его координаты и размеры.
  • Если не задан ни PlacementRectangle, ни PlacementTarget то "прилипание" левого верхнего угла формы осуществляется к курсору мыши.

ScreenPlacementRect — экранные координаты прямоугольника к которому осуществляется "прилипание" с учетом PlacementTarget и PlacementRectangle. На рисунке обозначен малиновым цветом.

Placement — вариант размещения формы. В большинстве случаев для определения координат формы также используется прямоугольник ScreenPlacementRect.

  • plBottom — форма снизу, если выходит за границы экрана, то сверху. Этот вид расположения обычно используется в комбобоксах.
  • plTop — форма сверху (см. картинку), если выходит за границы экрана, то снизу.
  • plLeft — форма слева, если выходит за границу экрана, то справа.
  • plRight — форма справа, если выходит за границу экрана, то слева. Этот вид расположения обычно используется в меню.
  • plCenter — форма по центру.
  • plBottomCenter — форма снизу и посередине.
  • plTopCenter — форма сверху и посередине.
  • plLeftCenter — форма слева и посередине.
  • plRightCenter — форма справа и посередине.
  • plAbsolute — для определения координат формы используется PlacementRectangle, при этом PlacementTarget игнорируется (используются координаты относительно левого верхнего угла экрана). Если ширина, или высота PlacementRectangle равны 0, то используются свойство Size.
  • plMouse — левый верхний угол прилипает к курсору мыши. PlacementRectangle и PlacementTarget игнорируется. Для определения размера используется свойство Size.
  • plMouseCenter — центр прилипает к курсору мыши. PlacementRectangle и PlacementTarget игнорируется. Для определения размера используется свойство Size.

На этом рисунке изображена всплывающая форма в которую помещен прямоугольник TRectangle с эффектом тени TShadowEffect. Прямоугольник выравнивается по всей клиентской области alClient. Различными цветами представлены некоторые важные свойства. Проект Вы можете загрузить здесь.

Padding — это свойство как и в обычной форме задает отступы от краёв клиентской области формы. По этим отступам будут выравниваться все контролы на форме. На рисунке это серый квадрат (с зеленой рамкой). По умолчанию используются значение 8, чтобы эффекты (например тень) не обрезались физическими границами окна.

Size — размер рабочей области формы. Как видно на рисунке физические размеры окна (красный пунктир) представляют малый интерес. Данное свойство (зеленый пунктир) задает те размеры по которым будут выравниваться все контролы. Размеры формы ClientWidth, ClientHeight устанавливаются автоматически с учетом Size и Padding. Если задано свойство PlacementRectangle и Placement имеет значение plAbsolute, то Size игнорируется.

ContentPadding — задает отступы от рабочей области формы, к которым осуществляется "прилипание".

ScreenContentRect — экранные координаты прямоугольника, к которому осуществляется "прилипание". Это прямоугольник внутри которого расположено полезное содержимое формы. Некоторые декоративные элементы (например треугольничек в CalloutPanel) могут вылезать за границы формы, или на кнопку.

Offset — смещение всплывающей формы. Это свойство указывает на сколько пикселей надо сместить форму относительно того расположения, которое было получено с учетом рассмотренных ранее свойств. В зависимости от Placement меняется направление смещения. Это свойство используется к примеру в многоуровневых меню, когда новые формы располагаются внахлест.

DragWithParent — это свойство указывает, надо ли перемещать форму после того как она была показана. Например: если Placement имеет значение plMouse или plMouseCenter то форма будет перемещаться вслед за курсором мыши. На мобильных устройствах, после смены ориентации (портрет/ландшафт) форма будет менять расположение чтобы не оказаться частично за пределами экрана.

Извините получилось довольно много букв, надеюсь что хоть часть текста оказалась понятной.

Posted by roschinspb on September 3rd, 2013 under Forms | 13 Comments »


Каретка в Fire Monkey

 В Fire Monkey новой версии XE4, в редакторах TEdit и TMemo появилось новое свойство Caret.

Это наследник TCustomCaret и TPersistent (располагается в FMX.Types) и имеет следующие свойства:

  • Color - цвет каретки. Если Null то используется цвет DefaultColor. Если и DefaultColor имеет значение Null, то используется цвет текста.
  • DefaultColor - умолчательный цвет каретки. Это значение берется из элемента стиля caretcolor. Если этот элемент стиля отсутствует то свойство получает значение Null.
  • Interval - время (мс) в по истечении которого исчезает и появляется Flasher (тот самый мигающий прямоугольничек). Если 0, то используется умолчательное значение 500, если -1, то Flasher не мигает и виден постоянно.
  • Width - ширина Flasher`а. Если 0, то используется умолчательное значение которое получается при помощи специального платформенного сервиса IFMXSystemInformationService (например для Windows это будет 1, для iOS - 5).

Полагаю для большинства случаев этой информации будет достаточно.

Дополнительная информация

В редакторах TEdit и TMemo для создания каретки используется виртуальный метод CreateCaret, который вы можете перекрыть для того, чтобы использовать свой собственный класс кареток. Можно также создать свой собственный Flasher, но это несколько сложнее. Eсли кто-то проявит интерес, то я напишу об этом как-нибудь в другой статье.

Если Вы хотите создать свой собственный контрол использующий каретку но не являющийся наследником (TCustomEdit и TMemo), то для правильной работы он должен поддерживать интерфейс ICaret.

Рассмотрим другие свойства и методы каретки.

  • Owner - владелец каретки. Это свойство получает значение параметра AOwner в конструкторе. Это должен быть редактор которому принадлежит каретка и обязательно поддерживать интерфейс IControl.
  • Control - контрол которому принадлежит каретка. См. Owner.
  • Pos - положение каретки (координаты левого верхнего угла).
  • Size - размеры каретки.
  • Visible - видимость каретки. Установка этого свойства не означает что сразу же в текущем контроле замигает Flasher, это всего лишь установка признака говорящего о том, что в данном контроле он может замигать при подходящих условиях.
  • CanShow - это виртуальный метод в дополнение к Visible, который возвращает True, если контрол виден, доступен, в нем фокус ввода и он располагается на активной форме.
  • Displayed - это свойство говорит о том, что данная каретка находится в фокусном контроле и в него может осуществляться ввод с клавиатуры. Это свойство только для чтения, но оно меняется при выполнении методов Show и Hide.
  • Show - если Visible = True и CanShow возвращает True, то Flasher перемещается в контрол и свойство Displayed принимает значение True. Этот метод вызывается когда контрол получает фокус ввода.
  • Hide - делает Flasher невидимым, и свойство Displayed равным False.
  • UpdateFlasher - обновление всех свойств Flasher`а. Выполняется при изменении свойств. Этот метод запускает виртуальный метод DoUpdateFlasher который вы можете перекрыть. Традиционно если вы хотите временно отменить обновление то можно воспользоваться методами BeginUpdate и EndUpdate.
  • Flasher - мигающий прямоугольничек, ну или синее ведерко если использовать аналогию из автомобилизма. А на самом деле это интерфейс IFlasher, который отвечает за графическое отображение каретки. Сам по себе класс TCustomCaret ни чего не отображает, а только содержит данные которые используются Flasher’ом. Строго говоря, Flasher может представлять из себя что угодно, но по умолчанию используется наследник TRectangle, который объявлен в FMX.Objects (см. TCaretRectangle).

Вы можете обращаться к Flasher для того, например, чтобы узнать реальный цвет, или координаты каретки. Но будьте внимательны, в отличие от проблесковых маячков, существует только один экземпляр этого объекта и располагается на том редакторе, в котором находится фокус ввода. IFlasher имеет свойство Caret которое указывает на каретку контрола в котором располагается Flasher.

Каретка и клавиатура

Надо отметить, что каретка занимается не только перемещением Flasher`а, но и тесным образом связана с виртуальной клавиатурой. Когда меняется фокусный контрол, или свойство Displayed, то должна появиться или исчезнуть виртуальная (экранная) клавиатура. На мобильных устройствах с сенсорным экраном клавиатура обычно (но не всегда) видна, тогда когда отображается каретка. При этом учитываются еще пара свойств:

  • ReadOnly - если это свойство True, то виртуальная клавиатура не показывается, даже если каретка видна.
  • TemporarilyHidden - каретка временно скрывается хотя клавиатура видна и допускается ввод в фокусный контрол, при этом Displayed остаётся равным True.

Виртуальная клавиатура атоматически появляется при подходящих условиях, на платформе iOS, а в Windows Вы можете добиться подобной работы, если установите глобальную отладочную переменную VKAutoShowMode равной vkasAlways.

Чтобы отловить момент появления и сокрытия клавиатуры используйте события формы OnVirtualKeyboardShown и OnVirtualKeyboardHidden это может быть полезно для того, чтобы осуществить смещение рабочей области окна. Более подробно про скроллинг было написано в статье Платформонезависимый скроллинг

См. примеры samples\ScrollableFormDemo и samplesmobile\ScrollableForm. Если на рабочем компьютере нет примеров, то можно посмотреть здесь: ScrollableFormDemo.

Posted by roschinspb on April 15th, 2013 under Caret, Text, on-Screen Keyboard | 2 Comments »


Платформонезависимый скроллинг в Fire Monkey

Одно из нововведений в XE4 это платформонезависимый скроллинг.
С самого начала в Fire Monkey был компонент TScrollBox, который является предком для многих других компонентов (TListBox, TTreeView, TMemo и т.п.). Это контейнер который может содержать различные контролы, при этом они могут выходить далеко за границы видимой области TScrollBox.

На картинке изображается TScrollBox в RunTime и в DesignTime. Если упрощенно рассмотреть его структуру, то данный компонент (стилизованный контрол), содержит в себе полосы прокрутки и контрол ContentLayout обозначающий видимую область (на нижней картинке выделен темно-серым прямоугольником). Размеры ContentLayout соответствуют свойству ViewportSize для полос прокрутки.

На ContentLayout располагается контрол Content (содержимое ScrollBox`а). Когда мы бросаем какую-нибудь кнопку в TScrollBox, то она в реальности попадает в Content и когда мы перемещаем изображение внутри TScrollBox, на самом деле изменяются координаты Content.

Рассмотрим некоторые свойства:

  • ViewportPosition - если говорить о физическом смысле, то это координаты левого верхнего угла видимой области на Content (см. зеленый текст). Эти координаты соответствую свойству Position для полос прокрутки. Сами полосы прокрутки VScrollBar и HScrollBar перенесены в раздел protected, поскольку это элементы стиля (строго говоря могут отсутствовать) и обращаться к ним надо осторожно.
  • ContentBounds - границы, внутри которых располагаются все контролы (см. красный прямоугольник и текст). Эти координаты соответствуют свойствам Min и Max для полос прокрутки.
  • OnViewportPositionChange - событие вызывается из виртуального метода ViewportPositionChange, после изменения координат, или размера видимой области.
  • OnVScrollChange, OnHScrollChange - события вызываются при непосредственном перемещении ползунков на полосах прокрутки. Т.е. если мы меняем ViewportPosition или перетаскиваем содержимое мышью или пальцем, или содержимое перемещается по инерции, то эти события не срабатывают.
  • OnCalcContentBounds - событие вызывается после рассчета нового значения ContentBounds, используя его мы можем изменить границы содержимого.
  • AutoHide - если это свойство имеет значение True, то соответствующая полоса прокрутки скрывается когда размер ContentBounds меньше размера ContentLayout. В противном случае она становится недоступной.
  • ShowScrollBars - если это свойство имеет значение False, то полосы прокрутки не видны ни когда, иначе они могут быть видны в зависимости от размеров, AutoHide, AutoShowing.
  • ShowSizeGrip - это свойство разрешает отображение декоративного элемента, который располагается в правом нижнем углу окнон в Win-приложениях. На самом деле он виден если существует соответсвтующий элемент стиля и видны обе полосы прокрутки.

Если создавать наследника TScrollBox, то можно перекрыть виртуальные методы: HScrollChange, VScrollChange, ViewportPositionChange, DoCalcContentBounds вместо использования событий.

За плавное перемещение отвечает свойство AniCalculations

Вся логика отвечающая за поведение контрола при перетаскивании содержимого, вынесена в класс TAniCalculations который находится в модуле FMX.InertialMovement.

Свойство TScrollBox.AniCalculations создаётся с использованием виртуального метода CreateAniCalculations, перекрыв этот метод можно использовать свои классы для управления перемещением.

Умолчательное поведение скроллинга отличается на разлных платформах, узнать его можно с помощью функции GetScrollingBehaviours. Внутри виртуального метода TScrollBox.DoUpdateAniCalculations устанавливаются некоторые свойства AniCalculations по умолчанию. Вы можете перекрыть этот метод чтобы изменить умолчательные значения. Например:

procedure TVertScrollBox.DoUpdateAniCalculations(const AAniCalculations: TScrollCalculations);
begin
  inherited DoUpdateAniCalculations(AAniCalculations);
  AAniCalculations.TouchTracking := AAniCalculations.TouchTracking - [ttHorizontal];
end;

Изменить текущие значения свойств можно во время работы приложения, таким образом, к примеру, в Windows, можно заставить перемещаться содержимое по инерции, как это делается в iOS.

  • Animation - разрешается перемещение по инерции.
  • AutoShowing - разрешается плавное скрытие и показ полос прокрутки. Если это свойство имеет значение True, то скроллбыры обычно полностью прозрачны и не видны. Когда начинается движение они появляются, а после остановки плавно меняют прозрачность до 0. Просьба не путать со свойствами AutoHide и ShowScrollBars
  • BoundsAnimation - разрешается перемещение содержимого за границы видимой обрасти, как на рисунке.
  • TouchTracking - разрешается перетаскивание рабочей области с помощью мыши, или пальца по вертикали и по горизонтали (см. ttVertical, ttHorizontal).
  • Averaging - это свойство несколько меняет логику работы. Когда происходит перемещение пальцем (ssTouch in Shift) это значение должно быть True.
  • DecelerationRate - степень замедления, кода содержимое перемещается по инерции. Умолчательное значение DecelerationRateNormal = 1.95 примерно соответствует замедлению на родных приложениях iOS.
  • Moved - это свойство указывает на то, что произошло перемещение, принимает значение False при выполнении метода MouseDown, и значение True в методе MouseMove, когда изменятся координаты. Если установлены свойства Averaging и Animation, то перемещение должно быть на расстояние больше DeadZone. Это на случай, если у пользователя с похмелья дрожат пальцы.
  • Opacity - текущее значение прозрачности, используемое полосам прокрутки. См. AutoShowing.
  • Down - это свойство указывает на то, что пользователь нажал кнопку мыши, или прикоснулся к сенсорному экрану.

Для начала пожалуй хватит…

Posted by roschinspb on April 8th, 2013 under Scrolling | 3 Comments »


Про категории в TActionList

Вот более развернутый ответ на а слабо Вальдемарурац. предложение касаемое подкатегоий.

Подкатегории

Теперь, если в названии категории используется ".", то в редакторе списка действий они изображаются в виде дерева. Число уровней вложенности ограничено, поэтому если раньше кто-то активно использовал точки в названиях категорий, то в новой версии не получится излишнего ветвления.

Добавлены также новые пункты меню (Change Multiple Actions), которые позволяют быстро изменить свойства Enabled и Visible.

  • Если вызвать контекстное меню в правой половине редактора, то будут изменены свойства у всех выделенных действий.
  • Если вызвать контекстное меню в левой половине редактора, то будут изменены свойства у всех действий данной категории и всех её подкатегорий.
  • Добавлен также метод TContainedActionList.EnumByCategory, который позволяет вызвать анонимный метод TEnumActionListRef для всех действий указанной категории (и всех подкатегорий).
    TEnumActionListRef = reference to procedure(const Action: TContainedAction; var Done: boolean);
    Если аргументу Done присвоить значение True, то перечисление действий прервется и EnumByCategory вернет True, во всех остальных случаях возвращается False.

    TEnumActionListRef выполняется для всех подходящих действий на момент вызова EnumByCategory. Т.е. если вы поменяете название категории внутри метода TEnumActionListRef это не повлияет на процесс перечисления.

    Для названий категорий могут использоваться национальные символы, регистр игнорируется. Всё выше указанное относится и к VCL и к FM.

    Posted by roschinspb on April 3rd, 2013 under Action | Comment now »


    Setting Text Parameters in FireMonkey

    One of small but rather useful new features of FireMonkey introduced in XE3 version is the FMX.Types.ITextSettings interface.
    Often we need to change some parameters of an output text for a component, which class is not known a priori. For example, a component can be of the TText or TTextControl classes. These classes have Color or FontColor properties respectively. In general case, to set color to one of these properties, one need first check the type of an object instance and then cast the type:

    if Obj is Ttext then
      TText(Obj).Color := MyColor
    else if Obj is TTextControl then
      TTextControl(Obj).FontColor := MyColor;

    Also you can access public properties using RTTI (Working with RTTI Index), but this looks not too fine especially taking into account that Color is not the only property of a text.

    ITextSettings Interface

    Usage of the ITextSettings interface makes such task much more simple and universal:
    var
      Settings: ITextSettings;
      Instance: TComponent;
    begin
    ...
      if IInterface(Instance).QueryInterface(ITextSettings, Settings) = S_OK then
      begin
        // Obtained ITextSettings interface for the component
      end;

    You can use numerous ways to obtain the value of the Settings interface variable. In case of success, Settings has not nil value. In this case, the particular type of Instance is not important. What is important is that the obtained IInterface(Instance) interface contains the following properties: DefaultTextSettings, TextSettings, and StyledSettings.

    These properties have the following meaning:

    DefaultTextSettings: TTextSettings — the default values of text properties. For styled controls, the DefaultTextSettings are set during the style loading in the FMX.Controls.TStyledControl.ApplyStyle method. For primitive controls (do not having styles), DefaultTextSettings are the same as TextSettings. In general case of a styled control, whether DefaultTextSettings are the same as TextSettings depends upon a particular realization of the control’s class. Notice that for the FMX.Objects.TText class, DefaultTextSettings and TextSettings are equal.

    TextSettings: TTextSettings — are customized text properties set manually.

    StyledSettings: TStyledSettings — This property defines, which text properties are taken from a style (see DefaultTextSettings) and which are set manually (see TextSettings) FMX.Types.TStyledSettings.

    You can also use the following constants:

    DefaultStyledSettings - specifies the set of styled text settings that are usually set by default.

    AllStyledSettings - specifies the full set of styled text settings.

    These constants have the following declarations:

    unit FMX.Types;
    ...
    type
      TStyledSetting = (ssFamily, ssSize, ssStyle, ssFontColor, ssOther);
      TStyledSettings = set of TStyledSetting;
    const
      AllStyledSettings: TStyledSettings = [TStyledSetting.ssFamily,
                                            TStyledSetting.ssSize,
                                            TStyledSetting.ssStyle,
                                            TStyledSetting.ssFontColor,
                                            TStyledSetting.ssOther];
      DefaultStyledSettings: TStyledSettings = [TStyledSetting.ssFamily,
                                                TStyledSetting.ssSize,
                                                TStyledSetting.ssStyle,
                                                TStyledSetting.ssFontColor];

    Keep in mind that, for example, when you are changing the value of the TextSettings.FontColor property, then the actual changing of the control’s view happens only if the StyledSettings property does not contain the TStyledSetting.ssFontColor property. Descendants of TTextControl, for example, TLabel provide possibility to edit the published StyledSetting property in the Object Inspector. When you change the color value, from the default value, the Object Inspector automatically sets ssFontColor = False. But such automatic changing of the ssFontColor property is made by the Object Inspector only at design time.


    This is the fragment of code executed when a property influencing onto a text view is changed:

    FTextObject.QueryInterface(ITextSettings, LISettings);
    LISettings.TextSettings.Assign(FDefaultTextSettings);
    LISettings.TextSettings.AssignNoStyled(TextSettings, FStyledSettings);

    You see that this code:
    1. First, set s all default values to the internal FTextObject text object and then
    2. Sets values of some properties that were specified manually. During this process, the code takes into account the StyledSettings property (FMX.Types.ITextSettings.StyledSettings).

    TTextSettings Class

    The main aim of the TTextSettings class is to manage appearance properties of text objects. TTextSettings is the descendant of TPersistent. Classes using text objects TTextControl (FMX.Controls.TTextControl), TMemo (FMX.Memo.TMemo), TCustomEdit (FMX.Edit.TCustomEdit) , and their descendants have the public TextSettings property. That is, if you know the component type a priory, for example TLabel (FMX.StdCtrls.TLabel), then you do not obliged to retrieve the ITextSettings interface; you can use the appropriate text property of the particular component, as follows:

    Label1.TextSettings.FontColor := claDarkkhaki;

    Actually, the public TLabel.FontColor property "is raised" from the corresponding property of TTextSettings class (FMX.Types.TTextSettings.FontColor).

    Notice that not all controls support all TTextSettings properties in the full extent. For example, TButton (FMX.StdCtrls.TButton) cannot change the text color correctly (because the color is changed when a button is pointed by the mouse cursor). Therefore, only fully supported properties are declared published. As the result, the TextSettings property is declared in the TTextControl (FMX.Controls.TTextControl) class as public, and the TextSettings property is kept public in standard controls. However, creating your own descendants of TTextControl, you can re-declare the TextSettings property as published. Then the Object Inspector provides possibility to edit values of sub-properties of the TextSettings property.

    Let Us Shortly Review What the TTextSettings Class Contains

    Equals—Checks whether all properties of the current TTextSettings instance and of the specified TObject object are equal. If values of all properties are equal, then Equals returns True.

    DoChanged—This virtual method is called from other methods when changes of some text object properties happen. In descendants, you can override the DoChanged method and execute appropriate update of the component view basing on results of analysis of the IsChanged and IsAdjustChanged properties. Do not call DoChanged explicitly–to enforce an explicit control updating, call the Change method.

    Change—This method is called when any of the styled properties of the current TTextSettings object is changed. Method Change sets IsChanged = True, then, if the object is not in an updating state (UpdateCount = 0), calls DoChanged and then clears IsChanged and IsAdjustChanged (sets to False).

    BeginUpdate and EndUpdate

    BeginUpdate increases by one the UpdateCount number of started and not accomplished updates of text properties of the current TTextSettings object. Till UpdateCount > 0, FireMonkey does no execute any update of the visual representation of the TTextSettings object.

    EndUpdate decreases UpdateCount. If UpdateCount becomes = 0 and any text property of the current TTextSettings object is changed (IsChanged or IsAdjustChanged is True), then EndUpdate calls DoChanged — to fire the OnChanged event. Then EndUpdate clears IsChanged and IsAdjustChanged (sets them to False).

    Therefore if you need to change several text properties at once and do not want to redraw the visual representation of the TTextSettings object after changing of each property, then you can use the code like this:

    TextSettings.BeginUpdate;
    try
      TextSettings.FontColor := MyColor;
      TextSettings.Trimming := True;
      ...
    finally
      TextSettings.EndUpdate;
    end;

    IsChanged — This property becomes True, when any styled text property (Font.Family, Font.Size, Font.Style, FontColor, HorzAlign, HorzAlign, Trimming or WordWrap) is changed.

    IsAdjustChanged — This property becomes True, when any styled text property that can modify geometry parameters of a text. For example, the font color cannot modify the text size, but the font size

    Assign — This method copies the parameters of the specified Source object to the current TTextSettings (FMX.Types.TTextSettings) object. The specified Source parameter should contain whether the TTextSettings type object or nil. If Source is nil, then all properties obtain the default values. The TTextSettings constructor calls Assign(nil), if your descendant class should be initiated with some parameters having not the default values, then you need to override the Assign method in your class.

    AssignNoStyled — This method is similar to Assign, but it copies, from the specified TextSettings object, values only of that styled text properties, which are not pointed in the StyledSettings parameter.

    Trimming — If the value of this property is not ttNone and the text does not fit to the drawing area, then it is trimmed to fit the area and ellipsis sign is printed after the trimmed text.

    HorzAlign, VertAlign — These properties define parameters of horizontal and vertical text alignment.

    WordWrap — If this property is True, then the text wraps when it longer than the the drawing area.

    FontColor — The color to draw a text.

    Font — The font to draw a text.

    OnChanged — This event is fired when any styled text property is changed.

    Posted by roschinspb on February 5th, 2013 under Text | Comment now »


    CustomText и Text.

    Вдогонку к статье TAction в XE3.
    У меня на днях поинтересовались, что за свойство CustomText. В статье упоминаний о нем нету, так что исправляюсь.

    И так, некоторые действия могут иметь умолчательный текст, который рекомендуется использовать, например "Quit Project1". Проблема в том, что при дизайне формы мы еще не знаем что приложение будет иметь именно это "креативное" название, поэтому просто установить свойство Text в Object Inspector`е будет бесполезно. Необходимо создать обработчик события OnUpdate и там подставлять правильное название. Чтобы освободить разработчика от однотипной работы в Fire Monkey, действие TFileExit обновляет свойство Text самостоятельно и его нет среди публичных свойств. Тем не менее на тот случай, если Вы всё-таки хотите использовать свой собственный текст введено свойство CustomText.

    Т.е. если установлено значение CustomText, то используется именно оно, иначе (при CustomText=”) используется умолчательный текст.

    Добавлю, что protected-свойство CustomText, объявлено в классе TCustomAction, но поддерживается только некоторыми действиями у которых оно "поднято" в раздел published. Если Вы хотите создать своё действие с поддержкой CustomText, вам нужно перекрыть виртуальный метод CustomTextChanged и изменять в нем свойство Text. В случае, если умолчательный текст не является константой и может меняться при работе приложения, перекройте метод Update и вызывайте в нем CustomTextChanged.


    function TCoolAction.Update: Boolean;
    begin
      Result := inherited Update;
      if not Result then
        CustomTextChanged;
    end;

    Posted by roschinspb on November 30th, 2012 under Action | Comment now »


    Установка параметров текста в Fire Monkey 2

    Среди незаметных, но полезных, на мой взгляд, нововведений в XE3 имеется интерфейс ITextSettings, который описан в модуле FMX.Types.

    Часто нам надо изменить некоторые параметры выводимого текста для компонента, класс которого нам заранее неизвестен, например это может быть  TText, или TTextControl у которых есть свойства Color и FontColor. Раньше пришлось бы проверять тип экземпляра и выполнять приведение типов:

    if Obj is Ttext then
      TText(Obj).Color := MyColor
    else if Obj is TTextControl then
      TTextControl(Obj).FontColor := MyColor;

    Можно еще обращаться к публичным свойствам через RTTI, но как-то это меня печалит учитывая, что кроме цвета есть и другие свойства текста…

    ITextSettings

    Использование интерфейса существенно упростит задачу и сделает решение более универсальным.

    var
      Settings: ITextSettings;
      Instance: TComponent;
    begin
    ...
      if IInterface(Instance).QueryInterface(ITextSettings, Settings) = S_OK then
      begin
        // Получен интерфейс ITextSettings для компонента
      end;

    Вы можете получить значение интерфейсной переменной Settings разными способами и в случае успеха она будет иметь отличное от nil значение. Что представляет собой Instance в данном случае не важно, главное, что полученный интерфейс содержит следующие свойства:

    DefaultTextSettings: TTextSettings — умолчательные настройки текста. Для стилизованных контролов это значение устанавливается при загрузке стиля в методе ApplyStyle. Для не стилизованных это тоже самое что и TextSettings (в общем случае всё зависит от реализации конкретного класса, но для TText это так) .

    TextSettings: TTextSettings — настройки текста установленные вручную.

    StyledSettings: TStyledSettings — это свойство указывает какие текстовые настройки берутся из стиля (см. DefaultTextSettings), а какие устанавливаются вручную (см. TextSettings). Вы можете использовать также две константы:

    AllStyledSettings — используются все настройки из стиля

    DefaultStyledSettings — используются некоторые настройки стиля. Это значение обычно задается по-умолчанию.

    unit FMX.Types;
    type
      TStyledSetting = (ssFamily, ssSize, ssStyle, ssFontColor, ssOther);
      TStyledSettings = set of TStyledSetting;
    
    const
      AllStyledSettings: TStyledSettings = [TStyledSetting.ssFamily,
                                            TStyledSetting.ssSize,
                                            TStyledSetting.ssStyle,
                                            TStyledSetting.ssFontColor,
                                            TStyledSetting.ssOther];
    
      DefaultStyledSettings: TStyledSettings = [TStyledSetting.ssFamily,
                                                TStyledSetting.ssSize,
                                                TStyledSetting.ssFontColor];
      Важно не забывать, что меняя, например, TextSettings.FontColor, фактическое изменение внешнего вида произойдет, если StyledSettings не содержит значения TStyledSetting.ssFontColor. Наследники TTextControl, такие как TLabel позволяют редактировать свойство StyledSettings в инспекторе объектов. При изменении цвета на значение отличное от умолчательного, свойство ssFontColor автоматически примет значение False. Но это происходит только в Design Time.



    Вот часть кода, которая выполняется при изменении свойства влияющего на внешний вид текста:

    FTextObject.QueryInterface(ITextSettings, LISettings);
    LISettings.TextSettings.Assign(FDefaultTextSettings);
    LISettings.TextSettings.AssignNoStyled(TextSettings, FStyledSettings);


    Как можно видеть, для внутреннего текстового объекта FTextObject сначала присваиваются все умолчательные значения, затем некоторые значения установленные вручную, при этом учитывается свойство StyledSettings.

    TTextSettings

    Для настройки внешнего вида текста создан класс TTextSettings, унаследованный от TPersistent. Наследники TTextControl имеют свойство TextSettings в секции public. Т.е. если заранее известен тип компонента, то получать интерфейс не обязательно:

    Label1.TextSettings.FontColor := MyColor;

    Публичное свойство TLabel.FontColor, на самом деле "поднимает" аналогичное свойство от TextSettings.

    Замечу, что не все контролы, в полной мере, поддерживают все свойства TTextSettings, например TButton не может правильно менять цвет текста (т.к. он меняется при наведении мыши), поэтому в секции published объявлены только поддерживаемые свойства, а TextSettings оставлено в public. Однако создавая своих наследников TTextControl вы можете поместить это свойство в секцию published и изменять его в инспекторе объектов.

    Рассмотрим кратко что содержит данный класс

    Equals — эта функция позволяет определить, различаются ли два экземпляра TTextSettings. Если значения всех свойств одинаковы, то возвращается True.

    DoChanged — этот виртуальный метод вызывается в случае, если произошли какие-то изменения свойств. Вы можете перекрыть этот метод в наследниках и выполнять некоторые действия по обновлению внешнего вида компонента, анализируя свойства IsChanged и IsAdjustChanged. Но не следует вызывать этот метод непосредственно. Для принудительного обновления контрола используйтем метод Change.

    Change — этот метод устанавливает свойство IsChanged в True, затем в случае, если экземпляр не находится в состоянии обновления вызывается метод DoChanged и сбрасываются свойства IsChanged и IsAdjustChanged.

    BeginUpdate и EndUpdate — если вам необходимо изменить сразу несколько свойств, то не смысла после каждого изменения перерисовывать компонент. Чтобы этого избежать используйте такой, примерно, код:

    TextSettings.BeginUpdate;
    try
      TextSettings.FontColor := MyColor;
      TextSettings.Trimming := True;
      ...
    finally
      TextSettings.EndUpdate;
    end;

    IsChanged — это свойство принимает значение True, если изменилось любое свойство

    IsAdjustChanged — это свойство принимает значение True, если изменилось свойство, которое может повлиять на геометрические размеры текста. Например изменения цвета ни как не может повлиять на размер текста, а размер шрифта — может.

    Assign — этот виртуальный метод присваивает значения всех свойств указанного в качестве параметра экземпляра. Единственный параметр Source должен быть либо экземпляром TTextSettings, либо nil. Если nil, то все свойства принимают умолчательные значения. В конструкторе вызывается Assign(nil), если в наследнике требуется изменить умолчательные значения, перекройте этот метод.

    AssignNoStyled — этот метод аналогичен Assign, но присваивает только некоторые свойства с учетом параметра StyledSettings.

    Trimming — если свойство отлично от ttNone и текст не помещается в область перерисовки, то он будет сокращен и в конец видимой части будет добавлено три точки.

    HorzAlign, VertAlign — выравнивание текста по горизонтали и вертикали.

    WordWrap — ели это свойство имеет значение True, то текст может автоматически разделяться на несколько строк.

    FontColor — цвет выводимого текста.

    Font — шрифт используемый при выводе текста.

    OnChanged — событие которое происходит при изменении свойств.

    Posted by roschinspb on October 9th, 2012 under Text | 6 Comments »


    Actions in XE3

    This post is published a bit late. Beginning of this September would be the better time, but better late than never…
    In XE3 release of our cross platform FireMonkey library, we, at last, have provided support for Actions. This support has enforced some changes in both the platform-independent Actions engine and in the VCL (platform-specific) implementation of Actions.

    What to be changed in legacy VCL projects

    Notice that in XE3 Help describing Actions was considerably changed, so it is reasonable to review at least the following sections: "FireMonkey Actions" and "Changes in Implementation of VCL Actions".

    Despite most actions components like TActionList, TAction, and others are pseudo-visual components, almost all actions functionality was implemented in VCL classes. From the other hand, only some actions functionality are tightly linked to VCL (Windows) features. (First of all, platform-dependant actions features are linked with managing of images in TBitmap, TImageList classes.) However, most of actions features are not strongly linked with a specific OS, so in XE3 many actions classes were moved from the high level of VCL library into the more basic level units of RTL library. In most cases, changes are implemented as simple moving of code from VCL units to RTL units:

    • Implementing this approach, we have created the System.Actions unit. Notice, that you have to add the System.Actions unit to the uses section of your VCL legacy projects using actions

    In addition, during compilation of legacy programs, some warnings can appear, indicating that some types are obsolete. For example, the TImageIndex type is now declared in the System.UITypes unit. The Vcl.ImgList unit also still contains the declaration of the same TImageIndex type (for compatibility), however, this declaration is treated obsolete and probably it will be deleted in one of the new coming releases. In order to decrease the number of warnings one needs to include System.UITypes right after Vcl.ImgList. If this is impossible, use the explicit reference to the unit, like:

    FImageIndex: System.UITypes.TImageIndex;

    The common ancestor classes in RTL to action engine classes in both VCL and FireMonkey frameworks (in RAD Studio we use the term frameworks to VCL and FireMonkey) are TBasicAction, TBasicActionLink, TContainedAction, TContainedActionLink, TContainedActionList, TCustomShortCutList, etc.

    The most interesting is TContainedAction. In the XE2 version, this class contains only the Category property. In XE3 it contains almost all framework-independent general properties of actions. Framework-specific general ancestor of actions classes is TCustomAction. It is declared in the Vcl.ActnList and FMX.ActnList units.

    Every registered action can be used only under the corresponding framework, otherwise VCL-application can link some FMX libraries and vice versa. While it is no problem to identify the framework corresponding to a form, for the TDataModule we introduce a “magic” property ClassGroup, which is written in pas-files, rather than in dfm files:

    implementation
    {%CLASSGROUP ‘FMX.Types.TControl’}
    {$R *.dfm}

    end.

    The value of this property is used only by IDE to filter icons in ToolPalette to make visible only components available in the current framework. The project framework is stored in the dproj file of a project, like:

    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
     <PropertyGroup>
        …
        <FrameworkType>FMX</FrameworkType> 

    • When editing legacy VCL or FireMonkey projects, one may need to add ClassGroup properties into the dproj files.

    What is new

    Into the TContainedAction class, we add the StatusAction property of the enumerated TStatusAction type. Creating new controls, you can use it like “validators” to indicate a state from possible variants. It can be considered as an advanced analog to the Enabled property.

    An exception class EActionError is added in the System.Actions unit. It is raised when different errors with actions happen.

    System.Classes, contains the following code:

    TBasicAction = class(TComponent)
    private
      FClients: TList<TBasicActionLink>;
      [Weak]FActionComponent: TComponent;

    This does not have the direct relation to the current implementation of actions, but one can notice the preparation to implementation of new compilers with reference counting. Where it is possible, we avoid usage of Pointer types and type conversions, so TList is replaced by TList<T>. The word [Weak] denotes that FActionComponent do not increase the reference counter for links.

    Managing actions in IDE

    The common functionality is implemented in the ActionEditors unit. This unit is not added to a customer project code, it is used only by IDE. The source code of the unit is presented only for acquaintance.

    Without going into details I can only recommend to read comments in the file, if you want to build up your own framework. Please, remember, the IDE still works only under Windows and VCL. In order to support the interaction with platform-independent part (rare case when VCL works together with FM) the class TIDEActions is added. Each framework must declare its own class descending to TIDEActions and register it using the RegisterActionsInFramework procedure. For additional information, see Help.

    In Fire Monkey

    Let us describe briefly describe some not obvious new features.

    The Action property was added to the base TfmxObject class, however it is not public in all the controls. Nevertheless all descendants of TCustomEdit support it, and you can assign to it at run time.

    Text — this property was added to class TAction, because all Fire Monkey controls have this property. Actually, it is the same as Caption.

    UnsupportedArchitectures and UnsupportedPlatforms. You can define architectures and OSs, which do not support particular actions; that is, an action is unavailable, invisible, and cannot be updated. In the first UnsupportedArchitectures property you can define unsupported architectures (32/64-bit), in the second UnsupportedPlatforms property one can set unsupported OS (Windows/Mac OS). By default these properties are empty, so an action is supported in all the cases.

    Virtual function IsSupportedInterface. Often an action can invoke some interface. The function returns False, if the interface is not implemented. For example, the on-screen keyboard is available only under Windows.

    HideIfUnsupportedInterface. This property indicates, whether the action should be hidden, if the interface is not implemented (see IsSupportedInterface). For example, it is possible, that the user does not need to know that some interfaces are not implemented, but in other times, it is possible, that a error should be generated to notify the user.

    Supported — the read-only property, it can be set in the UpdateSupported method according the values of the described above HideIfUnsupportedInterface, IsSupportedInterface, UnsupportedArchitectures, and UnsupportedPlatforms properties.

    ShortCutPressed — is the property, indicating whether the onExecute event was fired by pressing some combination of keys. Sometimes, it is handy to know the pressed key confirmation. For example, to check whether the user has accidently pressed an unknown key combination. If the user selects a menu item, he has definitely read the item text.

    ShortCut — the meaning of the property is the same as in VCL, however in FireMonkey you can change the list of possible key combination in IDE (see functions RegisterShortCut and UnrigesterShorCut). In addition, one can pass some number in brackets. For example, ‘(32787)’ for ‘Alt+Pause’. This is a two-byte value; the lower byte stores a virtual key (vkXXX constants defined in System.UITypes), and the higher byte stores a mask corresponding to key modifier key (scXXX constants defined in System.Classes). scXXX constants are:

    scCommand = $1000;
    scShift = $2000;
    scCtrl = $4000;
    scAlt = $8000;

    Virtual key constants vkXXX have different numeric values for Mac OS and Windows. For all platforms the virtual key numbers will be transformed to the corresponding constant value under Windows, it is possible.

    Planning shortcut key combinations one should note, that the exact mapping is not possible. For example, in Mac OS the combination Alt+<letter> means the input of special symbols. The same can happens under Windows, for example, for German keyboard layout if one press right ‘Alt+E’, the "Euro" symbol appears. In addition, some combinations are reserved by the system and are not sent to the application.

    Among standard actions let us describe TViewAction and TValueRangeAction. The others correspond to VCL analogs.

    TViewAction allows managing visibility of controls and forms, letting a developer to skip typing trivial code. The action has the FmxObject property. The method ExecuteTarget set the property FmxObject.Visible as True. If FmxObject is not defined, the event handler OnCreateComponent will be called, where one can create a new object. If one set the property Visible of FxmObject to False, this property of TViewAction doe not change in contract to other actions.

    TValueRangeAction allows to set some value in a specific range (see property ValueRange) and is used in TTrackBar, TProgressBar, TNumberBox, TComboTrackBar and so on. The ActionsDemo example is available.

    Posted by roschinspb on October 4th, 2012 under Action | 1 Comment »


    TAction в XE3

    Несколько запоздало выкладываю статью. Уместнее было бы её опубликовать в начале сентября…
    Как известно, в кроссплатформенной библиотеке Fire Monkey в XE3 появилась-таки поддержка Action.
    Это повлекло некоторую переделку системы действий и в части VCL.

    Что изменить в старых программах

    Для начала см. официальную информацию. Обращаю внимание, на то, что Help в части действий был существенно переписан, так что посмотреть стоит.

    Не смотря на то, что TActionList, TAction и т.п. — псевдовизуальные компоненты, некоторая часть функциональности была жестко привязана к VCL и Windows (в основном это касается работы с изображениями классов TBitmap, TImageList). Однако основная часть не имеет привязки к конкретной ОС, поэтому в XE3 её перенесли на более низкий уровень, в самый базовый пакет RTL. В основном изменения свелись к перетаскиванию кода по разным модулям.

    Так появился модуль System.Actions. Возможно, Вам потребуется добавить его в раздел uses для правильной работы старых приложений.

    Кроме того при компиляции старых программ скорее всего появится много предупреждений о том, что некоторые типы являются устаревшими. Например, тип TImageIndex теперь объявлен в модуле System.UITypes, а в модуле Vcl.ImgList оставлено объявление этого же типа (для совместимости), однако оно считается устаревшим и наверно в одной из следующих версий его удалят. Чтобы не было большого количества предупреждений следует объявить System.UITypes после Vcl.ImgList. Если по каким-то причинам он не может находиться после Vcl.ImgList, используйте явное указание модуля при описании:

    FImageIndex: System.UITypes.TImageIndex;

    Общими предками реализующими систему действий для VCL и Fire Monkey (в терминах Delphi это называется FrameworkType, или фреймворк) являются классы TContainedAction, TContainedActionLink, TContainedActionList, TCustomShortCutList.

    Основной интерес для нас представляет TContainedAction. Раньше этот класс почти ни чего не содержал кроме свойства Category, теперь в него переехали почти все свойства, а реализация специфического для фреймворка кода осталась в классах TCustomAction, которые располагаются в модулях Vcl.ActnList и FMX.ActnList.

    Любое зарегистрированное действие может быть использовано только в соответствующем ему фреймворке, иначе в VCL-ное приложение может случайно прикомпилироваться множество библиотек FMX и наоборот. Если для форм не возникает проблем с определением фреймворка, то для TDataModule введено «волшебное» свойство ClassGroup, которое записывается не в dfm, а в pas-файл:

    implementation
    
    {%CLASSGROUP 'FMX.Types.TControl'}
    {$R *.dfm}
         ...
    end.

    Значение этого свойства используется только IDE, для фильтрации иконок в Tool Palette, чтобы были видны компоненты доступные для текущего фреймворка, который записывается в dproj-файле

    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
     <PropertyGroup>
        …
        <FrameworkType>FMX</FrameworkType>

    При редактировании старых приложений, возможно потребуется установить свойство ClassGroup и отредактировать dproj-файл.

    Что нового

    В TContainedAction добавлено свойство перечислимого типа StatusAction. Оно может быть использовано при создании контролов на подобии валидаторов, для обозначения одного из нескольких состояний. Видимо его можно считать продвинутым аналогом Enabled.

    В модуль System.Actions, добавлен класс исключения EActionError. Оно возбуждается при различных ошибках связанных с действиями.

    Если посмотреть в System.Classes, можно увидеть такое описание

    TBasicAction = class(TComponent)
    private
      FClients: TList<TBasicActionLink>;
      [Weak] FActionComponent: TComponent;

    Это не имеет прямого отношения к действиям, но здесь видна подготовка к переходу на новые компиляторы c автоматическим подсчетом ссылок. Везде где возможно отказываются от Pointer и приведения типов, поэтому TList заменяется на TList<T>. Слово [Weak] означает, что в данном случае FActionComponent не увеличивает счетчик ссылок у линков.

    Управление действиями в IDE

    Общая часть реализована в модуле ActionEditors. Этот модуль не будет компилироваться, и добавляться в программу, он используется только в IDE, а исходник добавлен только для ознакомления.

    Не буду углубляться в подробности, если хотите создать свой собственный фреймворк читайте комментарии в этом файле. Отмечу только, что IDE по прежнему работает только в Windows и VCL. Для обеспечения взаимодействия с платформонезависимой частью (тот редкий случай когда совместно рабоают VCL и FM), добавлен класс TIDEActions. Каждый фреймворк должен реализовать своего наследника этого класса и зарегистрировать с помощью процедуры RegisterActionsInFramework. См. также Help

    В Fire Monkey

    Опишу кратко неочевидные, на мой взгляд, нововведения.

    Свойство Actionдобавлено в базовый класс TfmxObject, однако оно не является публичным во всех контролах, тем не менее все наследники TCustomEdit, вполне нормально его поддерживают и Вы можете присвоить его в Runtime.

    Text— это свойство добавлено в класс TAction «за компанию», раз уж во всех FM-контролах имеется такое свойство. На самом деле это тоже самое, что и Caption.

    UnsupportedArchitectures и UnsupportedPlatforms. В этих свойствах можно указать в каких случаях, действие не поддерживается, т.е. ни когда невидно, недоступно и не обновляется. В первом свойстве указываются неподдерживаемые архитектуры (32/64-бит), во втором операционные системы (Windows/Mac OS). По умолчанию оба свойства не заполнены, т.е. действие может поддерживаться во всех случаях.

    Виртуальная функция IsSupportedInterface. Часто действие может вызывать некоторый интерфейс. Данная функция возвращает False, если интерфейс не реализован. Например вызов экранной клавиатуры возможен пока только в Windows.

    HideIfUnsupportedInterfaceэто свойство указывает на то, нужно ли скрывать действие, если интерфейс не реализован (см. IsSupportedInterface). Возможно, что пользователю не нужно ни чего знать о том что некоторые интерфейсы не реализованы, а возможно наоборот требуется выдать некоторое сообщение об ошибке.

    Supported— свойство только для чтения, устанавливается в методе UpdateSupported, исходя из значений предыдущих свойств.

    ShortCutPressed— свойство указывает на то, что событие onExecute было вызвано путем нажатия сочетания клавиш. Предполагается, что пользователь может случайно нажать неизвестное ему сочетание и в некоторых случаях полезно запрашивать дополнительное подтверждение. Если же пользователь выбрал пункт меню, то он, скорее всего, прочитал что там написано и в этом случае подтверждение будет лишним.

    ShortCut — смысл свойства аналогичен VCL, однако в FMпоявилась возможность менять содержимое списка возможных сочетаний клавиш в IDE (см. функции RegisterShortCut и UnregisterShortCut). В дополнение к этому теперь можно указать некоторое число в скобках. Например ‘(32787)’ для Alt+Pause. Это двухбайтное число, младший байт хранит виртуальную клавишу Windows, а старший маску соответствующую клавишам модификаторам (см. System.Classes)

    scCommand = $1000;
    scShift = $2000;
    scCtrl = $4000;
    scAlt = $8000;

    Виртуальные клавиши имеют названия вида vkXXX (см. System.UITypes). Для всех платформ номер клавиши (в Mac OS, они отличаются от Windows), будет преобразован к соответствующему номеру для Windows, если это возможно.

    При выборе сочетаний следует учитывать, что полного соответствия быть не может. Например в Mac OS сочетания Alt+<буква> означают ввод специальных символов. Тоже самое наблюдается и в Windows, например в немецкой раскладке если нажать правый Alt+E, то будет введен символ евро. Кроме того некоторые сочетания зарезервированы системой и в приложение не попадают.

    Среди стандартных действий остановлюсь на TViewAction и TValueRangeAction, смысл остальных соответствует аналогам из VCL.

    TViewActionпозволяет легко управлять видимостью контролов и форм, избавляя от части тривиального кода. У данного действия есть свойство FxmObject. В методе ExecuteTarget, свойству FxmObject.Visible будет присвоено значение True. Если FmxObject не задан, то будет вызван обработчик события OnCreateComponent в котором можно создать новый объект. Если у FxmObject свойству Visible присвоить значение False, то у TViewAction оно не поменяется, в отличии от других действий.

    TValueRangeAction позволяет задавать некоторое значение в определенном диапазоне (см. свойство ValueRange) и используется в TTrackBar, TProgressBar, TNumberBox, TComboTrackBar и т.п. Посмотреть среди примеров можно проект ActionsDemo.

    Posted by roschinspb on October 2nd, 2012 under Action | 2 Comments »




    Server Response from: BLOGS2