Jump to content

Yaroslav Brovin

Administrators
  • Posts

    2,568
  • Joined

  • Last visited

  • Days Won

    647

Blog Entries posted by Yaroslav Brovin

  1. Yaroslav Brovin

    Общая
    Добрый день,
    В ближайшее время выйдет релиз FGX Native 1.13.0.0 с полноценной поддержкой Delphi 11. Обо всех нововведениях по порядку.
    Delphi 11
    Начиная с версии 1.13.0.0 мы включили поддержку Delphi 11. В то же время, мы исключили поддержку 10.3 из инсталлятора на основании результатов голосования:
    Мы переработали все формы дизайнера и добавили полноценную поддержку HiDPI.
    Дизайнер форм
    Добавлен новый режим позволяющий отключать пунктирную рамку компонентов.

    Так же несколько улучшили функцию визуального отображения областей компонентов, добавив отображение областей внутренних отступов бледно зеленым цветов. Это позволяет наглядно и быстро понять, где используются внутренние отступы (TfgControl.Padding).

    Обновления TfgDatePicker и TfgTimePicker
    В этом релизе мы добавили несколько небольших улучшений этих компонентов. Теперь вы можете указать формат ввода времени: 12 или 24 часовой формат. За это отвечает новое свойство TfgTimePicker.Is24HoursMode = (LocaleDependent, True, False). Теперь при старте компонента на платформе Android он по умолчанию выбирает часовой формат на основании текущей локали устройства.
     
    Помимо этого мы добавили режим автоматического расчета размера для этих компонентов AutoSize, который включен по умолчанию. Поэтому, если вам необходимо, чтобы компоненты растягивались по ширине, нужно исключить значение AutoSize.Width.
    Так же, теперь вы можете отдельно указывать задний фон для этих компонентов при помощи свойства BackgroundName.
     
  2. Yaroslav Brovin
    Рады поделиться новинками будущего релиза 1.12.0.0. 
    Очень часто при разработке мобильных приложений разработчики сталкиваются с одними и теми же задачами. Большинство решений, которые есть в интернете, ориентированы под FMX. Однако, зачастую из-за зависимостей в RTL на FMX Java код, эти решения нельзя просто добавить в FGX Native как есть и использовать.
    Поэтому мы решили по мере возможностей предлагать вам решения этих задач в виде расширений для FGX Native. Расширение будет включать необходимую обвязку/компоненты для FGX Native для сторонних OpenSource проектов. Первым таким расширением будет реализация нового компонента генерации штрихкода TfgBarcode на основе библиотеки Zint (https://www.zint.org.uk/).
    Отображение штрихкодов
    Новый пакет расширения FMXNative.Extension.Zint включен в поставку 1.11.8.0. Пакет содержит новый компонент TfgBarcode, поддерживающий отображение огромного числа типов штрихкодов. 

    Свойство Symbology позволяет выбрать тип отображаемого штрихкода. Через свойство Data указываются кодируемые данные. А через группу свойств Appearance вы можете настроить визуальное отображение штрихкода.
    Новое правило именования пакетов FGX Native
    Мы пересмотрели правила именований пакетов библиотеки FGX Native. Поэтому, если вы создаете свои пакеты расширений на основе FGX Native, вам необходимо переименовать зависимости на пакеты.
    FGXNative.Core <- fgx FGXNative.Design <- fgx_design FGXNative.Registration <-fgx_reg FGXNative.Extension.Translator <- FGXTranslatorD FGXNative.Externals <- fgx_externals Так же, если вы используется наш компонент локализации, необходимо:
    После установки новой версии библиотеки запустить среду Среда отобразит ошибку при загрузке пакета FGXTranslatorD. Необходимо отвечать Yes во всех диалогах про этот пакет. Затем открыть список компонентов среды: "Components" -> "Install Packages..." В списке найти строчку, соответствующую FGXTranslatorD и удалить ее при помощи кнопки "Remove". Данный компонент мы теперь регистрируем автоматически при установке FGX Native. Календарь под iOS
    В новой версии так же появится реализация компонента TfgCalendar для iOS. iOS не имеет родной реализации календаря. Поэтому мы с нуля реализуем данный компонент.
    Заключение
    Если у вас есть потребность в миграции некоторых невизуальных компонентов из FMX, пожалуйста, отпишитесь здесь в комментариях:
    Ссылку на стороннюю библиотеку с наличием исходных кодов/OpenSource. Без доступа к исходным кодам мы не сможем выполнить адаптацию под FGX Native. Описание для чего данный компонент нужен. Если кто-то из участников уже озвучил в комментариях нужный вам компонент, просьба отметить такое сообщение реакцией (лайком).
  3. Yaroslav Brovin
    В эту среду совместно с компанией Embarcadero проводим вебинар посвященный разработке мобильного приложения с использованием FGX Native. На вебинаре разберем одну из возможных архитектур мобильного приложения, применим шаблон MVVM для построения экранов. И познакомимся с приемами создания мобильных интерфейсов с FGX Native. 
    Когда: 23 июня 2021 в 12:00 МСК Язык: русский Заголовок: Примеры использования библиотеки FGX Native для создания макетов реальных мобильных приложений. Ссылка на регистрацию: https://lp.embarcadero.com/fgx-native Анонс: 
  4. Yaroslav Brovin
    Доброго дня!
    В ближайшем релизе 1.11.2.0 всех нас ждет появление поддержки выпадающих окон TfgPopup. Если вам необходимо отобразить содержимое в виде выпадающего окна, то эта возможность непременно вам пригодится.
    Создание
    В качестве содержимого выпадающего окна можно использовать как любой визуальный компонент так и форму. Удобнее всего использовать форму, поскольку она позволяет создать содержимое выпадающего окна прямо в дизайнере. При создании формы важно указать:
    Отключить полноэкранный режим формы TfgForm.FullScreen = False. Опционально сделать фон прозрачным через TfgForm.Transparent = True . В качестве начинки окна, я сделал форму с TfgCollectionView, используемым для отображения содержимого 

    Чтобы создать выпадающее окно нужно обязательно иметь содержимое, которое вы планируете показать в этом выпадающем окне. Создание выполняется через фабрику FGX.Popup.TfgPopupFactory, как и тосты, пикеры, диалоги и тд.
    var FPopup: TfgPopup; FPopupContent: TFrameList; FPopupContent := TFrameList.Create(nil); FPopup := TfgPopupFactory.CreatePopup(FPopupContent); После создания TfgPopup становится владельцем вашего содержимого. Это значит, что содержимое будет уничтожено, как только TfgPopup будет удален. Если вы хотите сами контролировать время жизни содержимого, вы можете передать вторым параметром значение False. В этом случае, после уничтожения TfgPopup, ваше содержимое останется жить.
    FPopup := TfgPopupFactory.CreatePopup(FPopupContent, False); После создания необходимо указать размер выпадающего окна при помощи свойства TfgPopup.Size. Например, если выпадающее окно прикреплено к кнопке. то имеет смысл в качестве ширины брать ширину кнопки:
    FPopup.Size := TSizeF.Create(fgButton1.Width, 200); Отображение
    Для отображения выпадающего окна существует два одноименных метода TfgPopup.DropDown, оба которых привязывают отображение окна к указанному компоненту.
    /// <summary> /// Открывает выпадающее окно, прикрепленное к указанному компоненту <c>AAnchor</c> со смещением <c>AOffset</c>. /// </summary> procedure DropDown(const AAnchor: TfgControl; const AOffset: TPointF); overload; virtual; abstract; /// <summary>Открывает выпадающее окно, прикрепленное к указанному компоненту <c>AAnchor</c>.</summary> procedure DropDown(const AAnchor: TfgControl); overload; FPopup.DropDown(fgButton1); Если вам необходимо выполнить отображение выпадающего окна со смещением, то вы можете передать это смещение вторым параметром:
    FPopup.DropDown(fgButton1, TPointF.Create(0, 8)); Эта версия метода удобна в случаях, когда вы самостоятельно делаете внешний вид выпадающего окна и хотите добавить отступы между выпадающим окном и компонентом, вызывающим это окно.
    Для закрытия окна используйте метод Close.
    /// <summary>Закрывает выпадающее окно.</summary> procedure Close; virtual; abstract; Настройка внешнего вида
    По умолчанию TfgPopup выглядит, как TfgCardPanel с тенью и рамкой. Однако, если вы хотите сделать свой внешний вид окна, то вы можете отключить  отображение по умолчанию через свойство TfgPopup.IsTransparent. В этом случае содержимое будет отображено прямо под привязанным компонентом.
    /// <summary>Прозрачное выпадающее окно или нет?</summary> property IsTransparent: Boolean read FIsTransparent write SetIsTransparent; Если вы используете в своих приложениях темы, то вы можете использовать темы и для содержимого выпадающего окна. Для этого необходимо указать название темы в свойстве TfgPopup.ThemeName. Таким образом можно добавить поддержку темной темы и детальнее настроить внешний вид попапов.
    /// <summary>Название темы, используемой для содержимого выпадающего окна.</summary> property ThemeName: TfgThemeName read FThemeName write SetThemeName; ios.mp4 android.mp4  
    События
    В TfgPopup поддерживается два типа событий, OnOpened и OnClosed, вызываемые при открытии и закрытии выпадающего окна соответственно. Так же мы предлагаем две версии каждого события для использования совместно с анонимными функциями и событиями.
    /// <summary>Вызывается, когда выпадающее окно отображается на экране.</summary> property OnOpened: TNotifyEvent read FOnOpened write FOnOpened; /// <summary>Вызывается, когда выпадающее окно отображается на экране.</summary> property OnOpenedCallback: TfgCallback read FOnOpenedCallback write FOnOpenedCallback; /// <summary>Вызывается, когда выпадающее окно скрывается с экрана.</summary> property OnClosed: TNotifyEvent read FOnClosed write FOnClosed; /// <summary>Вызывается, когда выпадающее окно скрывается с экрана.</summary> property OnClosedCallback: TfgCallback read FOnClosedCallback write FOnClosedCallback;  
  5. Yaroslav Brovin
    Нам очень приятно поделиться с вами этой новостью. Одно из приложений, написанных на FGX Native, победило в ежемесячном конкурсе Delphi приложений от Embarcadero. Это приложение -  аудио-гид по достопримечательностям разных городов с поддержкой нескольких языков.
    Поздравляем Романа с успехом и желаем ему не останавливаться на достигнутом!
    Приложение в Play Market: https://play.google.com/store/apps/details?id=ru.wc2.welcome&hl=ru&gl=US Ссылка на конкурс Embarcadero: https://delphi.embarcadero.com/delphi26th-welcome-a-spectacular-mobile-app-for-travelers-made-in-delphi/ Автор: @Roman
  6. Yaroslav Brovin
    Продолжаем серию статей, посвященных новинкам релиза FGX Native 1.11.0.0. И в этой статье поговорим о самой главной и ожидаемой новинке - поддержка полноценных анимаций 🔥🔥🔥.
     
    TfgAnimationManager - центр управления анимациями
    Главным центром управления анимации любого компонента является менеджер анимаций, доступ к которому можно получить через свойство TfgControl.AnimationManager. Именно он отвечает за создание, добавление и удаление аниматоров.
    Создание аниматора
    Чтобы создать нужный аниматор нужно воспользоваться одним из следующих методов TfgAnimationManager:
    function AddOpacityAnimation(const AStartOpacity, AFinishOpacity: Single; const ADuration: Integer = TfgAnimation.DurationPlatformValue): TfgAnimation; function AddBoundsAnimation(const AStartBounds, AFinishBounds: TRectF; const ADuration: Integer = TfgAnimation.DurationPlatformValue): TfgAnimation; function AddScaleAnimation(const AStartScaleX, AFinishScaleX, AStartScaleY, AFinishScaleY: Single; const ADuration: Integer = TfgAnimation.DurationPlatformValue): TfgAnimation; function AddRotationAnimation(const AStartAngle, ASweepAngle: Single; const ADuration: Integer = TfgAnimation.DurationPlatformValue): TfgAnimation; function AddTranslationAnimation(const AStartPoint, AFinishPoint: TPointF; const ADuration: Integer = TfgAnimation.DurationPlatformValue): TfgAnimation; function AddGroupAnimation: TfgAnimationGroup; Каждый метод создает соответствующий своему названию тип аниматора с указанными стартовыми и конечными значениями. Например, если вы хотите плавно показать кнопку в течении 1 секунды, достаточно выполнить следующий код.
    uses FGX.Animation; var Animation := Button.AnimationManager.AddOpacityAnimation(0 {start opacity}, 1 {finish opacity}, 1000 {msec}); Animation.Start; Обратите внимание, что в данном случае, созданный аниматор "Animation" останется у компонента и не будет удален, пока вы не сделаете это сами или компонент не будет уничтожен. Если вы планируете часто использовать один и тот же вид анимации на конкретном компоненте, то предпочтительным способом будет являться именование анимации. Например:
    uses FGX.Animaton.Helpers; // Создаем аниматор один раз Button.AnimationManager.AddOpacityAnimation(0 {start opacity}, 1 {finish opacity}, 1000 {msec}) .SetName('fade-in'); // Будущие запуски анимации Button.AnimationManager['fade-in'].Start; Если же вам достаточно выполнить анимацию всего лишь один раз, то имеет смысл пометить ее для автоматического удаления опцией TfgAnimationOption.ReleaseOnFinish: 
    uses FGX.Animation.Types, FGX.Animation.Helpers; Button.AnimationManager.AddOpacityAnimation(0 {start opacity}, 1 {finish opacity}, 1000 {msec}) .AddOption(TfgAnimationOption.ReleaseAnimationOnFinish) .Start; Хелпер анимации
    Для удобного создания аниматоров мы предлагаем вам готовый хелпер FGX.Animation.Helpers, который позволяет использовать цепочку вызовов методов аниматора и облегчить визуальное восприятие готового кода.
    Без хелпера:
    uses FGX.Animation; var OpacityAnimation: TfgAnimation; OpacityAnimation := Button.AnimationManager.AddOpacityAnimation(0 {start opacity}, 1 {finish opacity}); OpacityAnimation.Duration := 1000 {msec}; OpacityAnimation.AutoReverse := True; OpacityAnimation.Delay := 500 {msec}; OpacityAnimation.Options := OpacityAnimation.Options + [TfgAnimationOption.ReleaseAnimationOnFinish]; OpacityAnimation.Start; С хелпером:
    uses FGX.Animation.Types, FGX.Animation.Helpers; Button.AnimationManager.AddOpacityAnimation(0 {start opacity}) .SetDuration(1000 {msec}) .SetDelay(500 {msec}) .SetAutoReverse .SetReleaseAnimationOnFinish .Start; Чтобы воспользоваться хелперами, необходимо подключить модуль FGX.Animation.Helpers.
    Обзор базовых аниматоров
    Поддерживается 5 базовых типов анимаций:
    Opacity. Изменение прозрачности (TfgControl.Opacity). Bounds. Изменение положения и размера (TfgControl.Position + TfgControl.Size).  Scale. Изменение масштаба отображения компонента. Rotation. Изменение угла поворота компонента. Translate. Выполнение смещения компонента относительно его текущей позиции (TfgControl.Position). Анимация прозрачности (TfgAnimationManager.AddOpacityAnimation)
    Чтобы выполнить анимацию прозрачности нужно создать аниматор через метод TfgAnimationManager.AddOpacityAnimation и указать стартовое и конечное значение свойства TfgControl.Opacity. 
    Image.AnimationManager.AddOpacityAnimation(0 {start opacity}, 1 {finish opacity}, 2000 {msec}) .Start; opacity.mp4
    Анимация перемещения и изменения размера (TfgAnimationManager.AddBoundsAnimation)
    Чтобы выполнить анимацию изменения размера и позиции нужно создать аниматор через метод TfgAnimationManager.AddBoundsAnimation и указать стартовый и конечный прямоугольник. Пример ниже демонстрирует интересный прием акцентирования внимания на компоненте через визуальное расширение и сжатие компонента.
    var StartRect: TRectF; StopRect: TRectF; begin StopRect := imgPhoto.Bounds; StartRect := imgPhoto.Bounds; StartRect.Inflate(16, 16); Image.AnimationManager.AddBoundsAnimation(StartRect, StopRect) .Start; bounds.mp4
    Анимация изменения масштаба (TfgAnimationManager.AddScaleAnimation)
    Чтобы выполнить анимацию изменения масштаба нужно создать аниматор через метод TfgAnimationManager.AddScaleAnimation и указать стартовые и конечные значения коэффициентов масштабирования по горизонтали и вертикали.
    Image.AnimationManager.AddScaleAnimation(0.5, 1, 0.5, 1, 1000) .Start; scale.mp4
    Анимация поворота компонента (TfgAnimationManager.AddRotationAnimation)
    Чтобы выполнить анимацию поворота компонента нужно создать аниматор через метод TfgAnimationManager.AddRotationAnimation и указать стартовое значение угла и на сколько градусов нужно совершить поворот (в градусах). При этом, если угол поворота положительный, то поворот осуществляется по часовой стрелки, а если отрицательный, то против часовой стрелки.
    Image.AnimationManager.AddRotationAnimation(0 {start}, 360 {Sweep}, 1000) .Start; rotate.mp4
    Анимация смещения (TfgAnimationManager.AddTranslationAnimation)
    Чтобы выполнить анимацию смещения компонента нужно создать аниматор через метод TfgAnimationManager.AddTranslationAnimation и указать стартовое и конечное смещения значения позиции компонента.
    Image.AnimationManager.AddTranslationAnimation(TPointF.Create(-16, 0), TPointF.Create(16, 0), 1000) .Start; translate.mp4
    TfgAnimation - основа анимации
    После того, как мы посмотрели несколько примеров создания аниматоров вживую, пришло время рассмотреть их настройки детальнее.
    Длительность анимации (TfgAnimation.Duration)
    Общая длительность выполнения текущей анимации в миллисекундах в одну сторону (от стартового значения до конечного).
    Задержка перед запуском (TfgAnimation.Delay)
    Если вам необходимо выполнить анимацию с задержкой, то вы можете это сделать указав значение задержки в миллисекундах в свойстве TfgAnimation.Delay.
    Количество повторений (TfgAnimation.RepeatCount)
    Если вам необходимо повторить анимацию несколько раз или сделать ее бесконечной, то вы можете это сделать при помощи этого свойства, где
    RepeatCount = 0 - повторение анимации бесконечное число раз. RepeatCount > 0 - повторение анимации ровно "RepeatCount" раз. Например при помощи этого свойства легко сделать анимацию тряски: повторим 4 раза движение компонента по горизонтальной оси.
    shake+repeatCount.mp4
    Интерполяция (TfgAnimation.CurveKind)
    Это свойство отвечает за формулу интерполяции значений анимируемых свойств. Пока поддерживается 4 самых распространенных типов интерполяции.
    TfgAnimationCurveKind = (Linear, EaseIn, EaseOut, EaseInOut);
    Краткое описание стратегии изменения анимируемого значения на протяжении всей длительности анимации в зависимости от типа интерполяции:
    Linear - равномерное изменение. Варианты типичного применения: короткие анимации, изменение цвета. EaseIn - медленное начало с постепенным нарастанием скорости к концу анимации. Варианты типичного применения: исчезновения объекта. EaseOut - быстрое начало с постепенным замедлением скорости к концу анимации. Варианты типичного применения: появления объекта. EaseInOut - медленное начало с нарастанием скорости посередине и постепенным замедлением скорости к концу анимации. Варианты типичного применения: перемещение объекта, изменение масштаба. Порядок запуска (TfgAnimation.RunOrder)
    Это свойство актуально только в контексте групповых аниматоров и позволяет указывать порядок запуска текущей анимации в группе. Подробнее это будет рассмотрено в разделе "Групповые анимации".
    TfgAnimationRunOrder.Immediately - запуск анимации в момент старта родительского группового аниматора, либо вместо с предыдущим одноуровневым аниматором. TfgAnimationRunOrder.AfterPrevious - запуск анимации после окончания предыдущей анимации в рамках группового аниматора. Дополнительные настройки (TfgAnimation.Options)
    TfgAnimationOption.StartFromCurrent - Начинать анимацию с текущего значения свойства компонента, а не указанного стартового значения. TfgAnimationOption.AlwaysSetFinalValue - При остановке анимации, эта опция позволяет указать сразу конечное значение свойства компоненту, иначе конечное значение останется таким, какое оно было на момент остановки. TfgAnimationOption.AutoReverse - Нужно ли автоматически выполнить анимацию в обратном порядке после окончания прямой анимации. Актуально для RepeatCount > 0. TfgAnimationOption.ReleaseControlOnFinish - позволяет автоматически удалить компонент по окончании анимации. TfgAnimationOption.ReleaseAnimationOnFinish - позволяет автоматически удалить аниматор по окончании анимации. Название (TfgAnimation.Name)
    Вы можете присвоить уникальное название аниматору, чтобы в последствии обращаться к нему напрямую по его имени.
    Например:
    var FadeAnimation: TfgAnimation; FadeInAnimation := Button.AnimationManager['fade-in']; Групповые анимации
    Для создания сложных анимаций мы предлагаем использовать групповые аниматоры, задача которых сгруппировать несколько анимаций и задать правила их запуска. По умолчанию групповой аниматор запускает все вложенные анимации одновременно. Например, такой аниматор ниже позволяет реализовать анимацию модального открытия формы на Android:
    var AnimationGroup: TfgAnimationGroup; AnimationGroup := LForm.AnimationManager.AddGroupAnimation .Add(LForm.AnimationManager.CreateScaleAnimation(1.125, 1, 1.125, 1)) .Add(LForm.AnimationManager.CreateOpacityAnimation(0, 1)); Мы создаем два аниматора, объединенные в группу, один из которых масштабирует форму, а второй меняет ее прозрачность.
    Групповой аниматор TfgAnimationGroup по сути так же является аниматором TfgAnimation. А это значит, что вы можете их вкладывать друг в друга добиваясь анимации любой сложности.
    Пример ниже показывает последовательно выполнение анимаций: вначале смещение компонента, а затем поворот:
    Image.AnimationManager.AddGroupAnimation .Add(Image.AnimationManager.AddTranslationAnimation(TPointF.Create(-16, 0), TPointF.Create(16, 0), 1000)) .Add(Image.AnimationManager.AddRotationAnimation(0, 360, 1000) .SetRunOrder(TfgAnimationRunOrder.AfterPrevious)) .Start; group-animation-1.mp4
    Вы можете выделить создание подобной анимации в отдельный метод и затем применять к любому компоненту. 
    Шаблоны анимаций
    Это приятный бонус для наших пользователей. Мы предлагаем базовый набор уже готовых анимаций, которые вы можете использовать в своих проектах всего лишь одной строчкой кода. Для того, чтобы воспользоваться шаблонами, нужно подключить модуль FGX.Animation.Templates.
    Чтобы просто потрясти компонент, достаточно просто написать:
    Image.Shake; А если требуется настроить параметры на свой вкус и цвет, можно воспользоваться перегруженной версией:
    Image.Shake(TfgShakeAnimationParams.Default .SetDuration(2000) .SetRepeatCount(10)); Видео ниже демонстрирует все текущие доступные для использования шаблоны:
    templates.mp4
    Среди шаблонов так же доступны различные варианты появления и скрытия компонентов с переносами и без. Вы можете ознакомиться с текущим набором в демо проекте: "Анимация" -> "Шаблоны анимаций".
    Ограничения
    Несмотря на то, что анимации уже работают, у них есть ряд ограничений, часть из которых мы будем постепенно убирать в будущих версиях.
    Нельзя менять стартовые и конечные значения уже созданных анимаций. Это можно делать только путем удаление старого и создания нового аниматора. Изменение свойств анимации во время ее выполнения не приведет их к применению. Все свойства применяются в момент старта анимации. Изменение размера компонента-контейнера через анимацию не приводит к выравниванию дочерних компонентов. Если вам нужно выполнить выравнивание содержимого, то надо добавлять дополнительные аниматоры для перемещения и изменения размеров вложенных компонентов отдельно.  Устаревшее API
    Из-за создания полноценной анимации и выделения старых хелперов анимации TfgAnimationHelper в шаблоны анимации FGX.Animation.Templates, мы помечаем существующие методы анимации FadeIn, FadeOut, как устаревшие. Через несколько релизов мы удалим эти методы из TfgAnimationHelper, чтобы вы пользовались более удобными средствами анимации.
    На текущий момент методы анимации формы остаются как есть. В ближайших релизах эту анимацию мы встроим прямо в TfgForm, в результате чего анимация открытия/закрытия форм будет осуществляться автоматически и не будет требовать от вас лишних строчек кода.
    Итог
    Мы продолжим развивать и совершенствовать реализацию анимаций. Поэтому нам очень важно получить от вам обратную связь о том, что удобно, что нет и чего не хватает. Эта информация поможет нам сделать анимацию лучше и удобнее для всех.
  7. Yaroslav Brovin
    Мы постоянно работаем над расширением возможностей библиотеки FGX Native. Чтобы разнообразие деталей в конструкторе росло, а создание приложений становилось все проще и быстрее. 
    В новом релизе 1.9.2.0 мы добавили два новых компонента: TfgVirtualListPicker и TfgNumberListPicker. Эти компоненты позволяют выбрать одно значение из списка при помощи крутящегося барабана. В основном такие компоненты использовались при выборе даты и времени:
     
    TfgVirtualListPicker
    Этот компонент не хранит у себя элементы списка и работает подобно TfgCollectionView. А именно запрашивает все необходимые данные у разработчика через специальные события: OnGetItemsCount и OnGetItemText.
    Допустим у нас есть список городов. Для упрощения названия городов мы поместим в константный массив. У вас он может находится в базе данных или в любой другой модели данных:
    const Titles: array [0..6] of string = ('Saint-Petersburg', 'Moscow', 'Chelyabinsk', 'Sochi', 'Krasnodar', 'Voronej', 'Rostov-on-don'); Для полноценной работы компонента ему необходимо знать только:
    Количество элементов в списке. Оно указывается в событии OnGetItemsCount. procedure TFormMain.fgVirtualListPicker1GetItemCount(Sender: TObject; var ACount: Integer); begin ACount := Length(Titles); end; Текстовое название элемента, отображаемое в компоненте. Оно указывается в событии OnGetItemText. Если вы не указываете обработчик для этого события, то компонент по умолчанию использует надпись следующего формата "Item %d". Каждый элемент списка имеет свой индекс, по которому компонент получает текст элемента. procedure TFormMain.fgVirtualListPicker1GetItemText(Sender: TObject; const AItemIndex: Integer; var AText: string); begin AText := Titles[AItemIndex]; end; Это минимально необходимые действия для отображения списка:

    У компонента нет ограничения на максимально допустимое количество элементов в списке. Оно может быть абсолютно любым. Значит его можно использовать для списков любого размера.
    Когда пользователь выбирает элемент, срабатывают события OnChanged, OnItemSelected, через которые вы можете узнать индекс выделенного элемента.
    Внешний вид
    На текущий момент у компонента есть только одна настройка - это цвет текста элементов TextColor / TextColorName, которая по умолчанию завязана на цвет темы "Text\Text".
    Расширяемость
    Компонент TfgVirtualListPicker разработан для возможности создания своих расширений на его базе. Это значит, что вам не нужно реализовывать этот компонент для IDE, Android и iOS. Именно на его основе сделан следующий компонент TfgNumberListPicker.
    TfgNumberListPicker
    Этот компонент является кроссплатформенным расширением TfgVirtualListPicker и предлагает возможность выбрать вещественное число из указанного диапазона.
    Диапазон задается при помощи трех свойств: границы диапазона Min, Max и шага изменения сетки чисел Step.

    По умолчанию каждый элемент отображается в виде вещественного числа с двумя знаками после запятой. Однако, вы можете это поменять одним из любых способов:
    Указать стандартный формат через FormatKind = Integer. Указать свой произвольный форма через FormatKind = Custom и Format = 'Item %f' Указать свой обработчик события OnGetItemText. В остальном компонент позволяет использовать все возможности TfgVirtualListPicker.
  8. Yaroslav Brovin
    Всем доброго дня,
    При разработке кросс-платформенного приложения важной базовой составляющей является определение размеров компонентов. С одной стороны нет ничего проще, чем задать желаемый размер любому компоненту библиотеки FGX Native или задать правило выравнивания компонентов при помощи FlexBox. Однако, кросс-платформенная разработка накладывает определенные трудности в этом подходе. А именно зачастую размер компонентов зависит не только от других компонентов, но и от содержимого. И если с первым отлично справляется FlexBox, то со вторым в FGX Native нужно использовать метод для расчета размеров компонентов TfgControl.MeasureSize, и будем честны, это было временное решение.
    Мы всегда стараемся сделать библиотеку FGX Native удобной для использования, чтобы разработчик мог концентрироваться в коде на бизнес логике своего приложения, а не программной "настройке" UI. Одним из грядущих улучшений будет поддержка автоматического расчета размеров компонентов. Мы внедрили на нижнем уровне поддержку Autosize. Теперь на уровне появится новое свойство TfgControl.Autosize, которое отвечает за то, что именно нужно автоматически посчитать: ширину, высоту или обе величины. Если в ходе выравнивания компонента система понимает, что компонент имеет фиксированный размер, то в этом случае компонент может автоматически его рассчитать. Так например задание Autosize = [Height] для TfgTraсkBar автоматически посчитает нужную высоту компонента, а вот указание Autosize = [Width] для этого компонента ни на что не повлияет. 

    Не смотря на то, что сам механизм внедрен на нижнем уровне, реально это свойство в ближайшем релизе будет доступно только для нескольких компонентов: TfgSwitch, TfgTrackBar, TfgNavigationBar и возможно TfgLabel. Если с TfgSwitch и TfgTrackBar в целом понятно,  то вот на счет TfgNavigationBar  стоит отдельно отметить, что теперь этот компонент умеет в автоматическом режиме расчета высоты учитывать отступы у формы SafeArea и наличие заголовка и подзаголовка. И если раньше необходимо было программно отслеживать изменения отступов области SafeArea в TfgForm.OnSafeAreaChanged и на основании значений отступов вычислять руками высоту панели навигации, то сейчас все это будет происходить автоматически.



    Данное нововведение особенно актуально в свете предстоящего появления iOS. Так как в iOS используются другие шрифты, размеры текста и размеры компонентов. И чтобы сделать действительно универсальное приложение без этой функциональности будет очень сложно.
    Всем хорошей рабочей недели!
  9. Yaroslav Brovin
    Добрый день,
    Мы выложили запись прошедшего 18 февраля вебинара по теме "Пробная сессия вопросов и ответов по FGX Native". Видео доступно на нашем YouTube канале.
    На вебинаре обсуждались следующие темы:
     Android SDK/NDK; Сервисы локации; Асинхронная загрузка изображений в списках; Планы на ближайшие релизы.  
     
  10. Yaroslav Brovin
    Теперь в FGX Native появится новый компонент для отображения рекламы в вашем приложении TfgBannerAd. Компонент позволяет монетизировать ваше приложение и получать пассивный доход.
    Компонент поддерживает несколько видов баннера, поэтому вы всегда сможете подобрать подходящий размер.
    В качестве рекламной площадки используется Google AdMob.
      
    Компонент будет доступен в 1.1.6.0.
  11. Yaroslav Brovin
    Сложно представить мобильное приложение без графических ресурсов. Поиск иконок зачастую становится довольно сложной и не тривиальной задачей, особенно с условием необходимости найти иконки в разных масштабах, чтобы они четко выглядели на любых устройствах клиентов. 
    Мы подумали, что можем помочь вам с этим и сэкономить время, которое вы можете потратить на что-то более важное. Теперь вы сможете в пару кликов добавить современные иконки в ваше приложение через дизайнер ресурсов FGX Native.


    Около 1000 вариантов уникальных иконок доступно вам в 4 различных размерах (18х18, 24х24, 36х36 и 48х48). Каждая иконка поддерживает 5 варианта скейлов (1.0, 1.5, 2.0, 3.0 и 4.0) для каждого базового размера и специально разработана с учетом Материал дизайна для Андроид приложений.
    В будущем наборы иконок будут расширяться и появляться новые.
    Возможность появится в 1.1.6.0. Не пропусти!

  12. Yaroslav Brovin
    Мы стараемся делать так, чтобы FGX Native стала эффективным инструментом ? для разработчиков, приносила результаты и доставляла удовольствие от работы ?.
    Мы постоянно работаем над расширением возможностей и предоставляем новый функционал. Однако, с учетом молодости проекта FGX Native по нему не так много информации.
    Эффективность использования зависит от ваших умений и навыков. А для развития этих умений и навыков нужны обучающие материалы ?‍?, примеры правильного использования.
    Мы решили провести небольшой пробный эксперимент и для начала записать пару обучающих видео уроков по использованию FGX Native.
    Рад представить вам первый, самый базовый урок для начинающих о начале разработки мобильных приложений с FGX Native и Delphi. В уроке рассматривается:
    Настройка рабочего окружения; Создание Hello World мобильного приложения; Запись и чтение логов в FGX Native. Следующий урок будет о системе выравнивания Flex в FGX Native. Рассмотрим типовые задачи и их решения. Сверстаем сложный макет приложения. Чтобы не пропустить, подписывайся на новый официальный канал FGX Native: https://www.youtube.com/channel/UCd818Et5Fi0Iy53YouBce3w 
    Приятного обучения:
     
  13. Yaroslav Brovin
    Всем доброго дня!
    У нас есть много хороших новостей на конец уходящего лета ?.
    Во-первых. Мы практически полностью разработали новые компоненты под iOS TfgNavigationBar, TfgListMenu, TfgDatePicker, TfgTimePicker, TfgTimeEdit, TfgDateEdit, TfgCheckBox, TfgRadioButton, TfgPageControl, TfgTrackBar, TfgRectangle, TfgLine, TfgSvgPath и тд. Закончили с TfgCollectionView и реализовали полноценную поддержку стилей, "Drag & Drop" и "Pull To Refresh".
    reordering.mp4.1e0e3a9268a4c8a4cb40e3a8b75d6b03.mp4 pull-to-refresh.mp4.87c902179beda7dacf55c9f028c06423.mp4
    Во-вторых. Мы реализовали полноценную TfgCanvas для iOS с поддержкой градиентов, разных кистей и отрисовкой на битмапах.
    В-третьих. Мы улучшили поддержку TfgPath. И теперь мы полностью поддерживаем весь стандарт доступных path команд w3c.
    В-четвертых. Реализовали диалоги и пикеры для выбора даты и времени.
    В-пятых. Реализовали TfgForm.OnSafeAreaChanged и добавили возможность получать состояние приложение напрямую у TfgApplication.State.
    В-шестых. Запустили FGX Native Global Demo и большая часть экранов уже открывается и успешно работает.
     
    Всем хорошего окончания этих выходных!
  14. Yaroslav Brovin

    Общая
    В ближайшем релизе 1.5.0.0 мы добавили пару небольших улучшений, которые немного помогут вам проще разрабатывать ваши мобильные приложения.
    1. Отступы для TfgLabel
    В разработке пользовательского интерфейса довольно часто встречается задача визуального выделения текстовых меток/тегов. Обычно для визуального выделения используется фон в виде скругленного прямоугольника.
     
    Раньше такая задача решалась при помощи двух компонентов:
    Контейнер TfgLayout с требуемыми отступами для текста и с фоном BackgroundName в виде 9-path изображения. Метка TfgLabel, куда непосредственно выводится текст. Теперь же у TfgLabel есть специальное свойство ContentPadding, позволяющее добавить внутренние отступы, используемые при отображении текста. В результате метка легко получается на базе одного компонента TfgLabel с фоном BackgroundName  и требуемыми отступами.

    2. Оттенок для кнопки TfgButton
    Теперь для кнопки TfgButton добавлены новые свойства TintColor и TintColorName, позволяющие перекрасить системный цвет кнопки.

    3. Android AlarmManager
    Мы добавили небольшой пример по использованию Java кода из  FGX Native приложения. Новый демонстрационный пример показывает, как сделать на языке Java свой BroadcastReceiver и использовать его в связке с FGX Native приложением. Данный пример пригодится разработчикам, которым необходимо более тесная интеграция с Android API.
    4. Автосайз
    iOS
    Так же мы с нуля реализовали TfgDrawerLayout для iOS
    drawer-iOS.mp4.648b868510783b05479fa65efce46878.mp4
  15. Yaroslav Brovin
    На этой неделе всех нас ждет большой релиз библиотеки FGX Native 1.6.0.0, в который войдет много новых вещей и самое главное - Альфа версия iOS! 
    Вкратце обо всех нововведениях по порядку:
    FGX Native for iOS (Alpha)
    Это свершилось! Релиз 1.6.0.0 будет содержать Альфа версию FGX Native for iOS.
    Важно. Поскольку это альфа версия, то не стоит ожидать от нее полноценной работоспособности. Данный релиз содержит частично реализованный функционал: часть компонентов пока не реализованы, часть функционала компонентов может не работать. Однако, при этом, часть компонентов уже полностью готова.
    Теперь все проекты автоматически получают новый таргет iOS Device 64-bit. При открытии старого проекта, происходит автоматическая миграция проекта, в ходе которой:
    Добавляется платформа iOS Device 64-bit для сборки Добавляется конфигурация для деплоя iOS приложения. Добавляются настройки проекта, связанные с iOS (иконки, название пакетов и тд) Добавляются ассеты для iOS.  
    В дизайнере пока нет возможности переключиться на стиль iOS. Это будет добавлено уже ближе к полноценному релизу iOS части. 
    На текущий момент:
    Минимальная поддерживая версия iOS 11.  Не реализованы следующие компоненты : TfgCalendar, TfgAutoCompleteEdit, TfgSearchBox, TfgWebBrowser, TfgVideoControl, TfgCamera, TfgCameraPreview, TfgBarcodeScanner. Не реализована анимация. Не реализованы жесты. и тд Важно. Для сборки проекта необходимо использовать SDK не выше 13.5. С более старшими версиями SDK вы получите ошибку при линковке приложения. Мы уже занимаемся этим вопросом.
    За время разработки iOS версии у нас накопилось большое количество изменений, которые затрагивают не только iOS реализацию, но и некоторые аспекты работы библиотеки в целом.

    В процессе приходят новые идеи по улучшению уже существующего API компонентов.  Чтобы не копить все изменения отдельно от текущей версии библиотеки, мы решили соединить все изменения по iOS с текущим релизом. Так что теперь вы всегда будете в курсе текущего состояния iOS части.
    Мы ценим терпение и поддержку наших клиентов. Поэтому, поскольку релиз FGX Native for iOS немного задерживается, мы приняли решения, что не будем увеличивать цену за продление подписки в момент релиза полноценной iOS для клиентов, которые на момент релиза будут иметь активную подписку.  
    Т.е. если на момент полноценного релиза iOS у вас есть активная подписка, то стоимость продления для вас останется прежней. Для всех остальных стоимость первоначальной подписки и продления будет увеличена.
    Начиная с 1.6.0.0 мы будем включать в каждый релиз список доработок по iOS, чтобы вы всегда были в курсе.
    Обо всех найденных ошибках вы сможете сообщить нам в новой ветке форума https://forum.fgx-native.com/forum/102-ios-alpha-тестирование/. Так же в ней вы можете высказать свои пожелания по приоритету разработки того или иного функционала. Это поможет нам составить список первоочередных задач и сфокусироваться на действительно важных для вас задачах.
    Полностью переработанная кнопка TfgButton
    В дополнение к статье необходимо упомянуть, что у кнопки есть еще один важный стиль, о котором не говорилось ранее - Default. В этом стиле кнопка выглядит так, как это принято на целевой платформе. На Android - это закрашенная кнопка, в iOS - это текст без фона. Используйте этот стиль, если хотите придерживаться системного стиля отображения кнопки.  
      
    Ранее у кнопки вы могли наблюдать внутренние отступы между ее границей и фоном. Это в свою очередь немного усложняло позиционирование кнопки по отношению к другим компонентам. Поэтому в этом релизе мы убрали у Android кнопки все отступы между границей компонента и фоном. Если вы использовали эти отступы при выравнивании компонентов вашей формы, вам следует задать эти отступы напрямую через TfgButton.Margins.
    Небольшие улучшения в дизайнере
    В дизайнер добавлен ряд косметических улучшений, чтобы нашим пользователям было приятнее работать и ничто не отвлекало их от решения задач. Среди улучшений темная тема для дизайнера форм.

    А так же вспомогательная подсказка, отображающая имя выделенного компонента. Подсказка появляется при нажатии на компонент.

    Правила обрезки текста (TfgTextTrimming)
    В первоначальной версии библиотеки мы закладывали несколько способов обрезки текста: по символам, по словам и без обрезания. Однако, в результате реализации iOS и Android оказалось, что обрезка текста по словам не используется и не поддерживается ни на одной из платформ. Поэтому в данном релизе мы решили убрать значение TfgTextTrimming.Word, так как оно не работало и не имеет смысла. Если вы использовали в своих проектах TfgTextTrimming.Word, то вам необходимо переоткрыть формы, проигнорировав ошибку, и сохранить формы заново. 
    Канва TfgCanvas
    Мы добавили два важных метода, которые теперь НЕОБХОДИМО использовать при выполнении любой отрисовки на TfgBitmap - это TfgCanvas.BeginPaint и TfgCanvas.EndPaint. При вызове этих методов происходят определенные действия по переносу данных битмапа между буферами для ускорения работы с изображениями в целом. Если в уже существующем коде вы не расставите эти методы, то на iOS платформе вы не увидите результат отрисовки.
    Небольшой пример по использованию новых методов BeginPaint/EndPaint для отрисовки иконки: 
    Scale := TfgScreenManager.Main.Scale; IconSize := Ceil(DefaultIconSize * Scale); FMoreIcon := TfgBitmap.Create(IconSize, IconSize); FMoreIcon.Scale := Scale; with FMoreIcon.Canvas do begin BeginPaint; try Fill.Kind := TfgBrushKind.Solid; Fill.Color := TAlphaColorRec.Black; FillCircle(TPointF.Create(6, 12), 2); FillCircle(TPointF.Create(12, 12), 2); FillCircle(TPointF.Create(18, 12), 2); finally EndPaint; end; end; Помимо этого, добавлены упрощенные методы для отрисовки скругленных прямоугольников:  TfgCanvas.DrawRoundRect/FillRoundRect.
    Basic Аутентификация в TfgWebBrowser
    Для браузера по запросу добавлена поддержка Basic аутентификация. Чтобы выполнить аутентификация, достаточно задать свой обработчик на новое событие OnBasicAuthentificationRequest, в которое передается специальный AHandler, отвечающий за процесс аутентификации. Процесс аутентификация может выглядеть так:
    procedure TFormMain.fgWebBrowser1BasicAuthentificationRequest(Sender: TObject; const AUrl: string; const AHandler: IFGXBasicAuthentificationHandler); begin TfgDialogs.InputQuery('Input credentional data', ['User name', 'Password'], ['', ''], procedure (const AResult: TModalResult; const AValues: TArray<string>) begin if AResult = mrOk then AHandler.Proceed(AValues[0], AValues[1]) else AHandler.Cancel; end); end; Если аутентификация не прошла, то браузер будет пытаться пройти ее повторно, повторно вызывая OnBasicAuthentificationRequest. 
    Новые параметры экрана TfgScreen
    Для TfgScreen добавлен новый параметр SafeAreaPadding, который позволяет узнать, какие области на экране заняты системными элементами. Если раньше эти отступы можно было получить только в событии формы TfgForm.OnSafeAreaChanged, то теперь их можно получить в любой момент с помощью TfgScreenManager.Main.SafeAreaPadding.
    Tip: Не забывайте, что коэффициент масштабирования экрана всегда можно получить кроссплатформенным способом через TfgScreenManager.Main.Scale.
    Другие улучшения
    В этом релизе также содержится большое количество исправлений ошибок. 
    Всем спасибо за внимание!
  16. Yaroslav Brovin
    В процессе реализации уже существующих компонентов библиотеки FGX Native для iOS мы иногда сталкиваемся с тем, что для полноценной кроссплатформенной разработки приложений текущего функционала компонентов уже не хватает. Например, в панели TfgNavigationBar (iOS) для кнопки навигации часто иконку дополняют текстом, в то время, как в андроиде текст никто не добавляет. Однако, речь в этой новости пойдет не об этом компоненте, а об обычной кнопке TfgButton.
    С виду кнопка - один из самых простых компонентов. Однако, на практике, это довольно сложный компонент, если брать во внимание большое разнообразие в мире кнопок разных стилей и видов. Было много причин, почему кнопка TfgButton в библиотеке довольно ограничена в своих возможностях. Главная из них - это как сделать действительно удобный набор настроек, который угодил бы большинству и при этом был бы прост и гибок в настройке. 
    Рад поделиться, что в процессе реализации iOS и изучения Material Design,  мы пришли к удобному на наш взгляд набору настроек кнопки. 
    Стили
    Теперь кнопка может иметь один из трёх базовых стилей:

    Text - обычная текстовая кнопка, без рамки, с возможностью привязать иконку. Этот тип предназначен для третьестепенных действий. Outlined - это плоская Text кнопка с окантовкой. Этот же тип используется для второстепенных действий. Contained - это Outlined кнопка + заливка области. Естественно, каждый вид кнопки должен иметь свой индивидуальный набор настроек. И желательно, чтобы инспектор объектов отображал только актуальные для данного стиля настройки. Так, например, если используется Text кнопка, то для нее должны быть доступны настройки рамки и заполнения.
    Поэтому теперь каждый стиль кнопки динамически подгружает свой набор настроек. Выбор стиля выполняется в инспекторе объектов в новом свойстве Appearance:

    При изменении стиля будут доступны разные наборы настроек внешнего вида:
      
    Как вы могли уже заметить, список настроек, отвечающих за внешний вид, довольно сильно расширился, что позволяет легко делать такие разные по виду кнопки: круглые, плоские, разноцветные, контрастные и тд

    Настройки элементов
    Стоит отметить, что теперь можно отдельно управлять отображением каждого элемента кнопки:
    Текст Иконка Рамка Наполнение Таким образом, теперь для иконки можно отдельно указать оттенок прямо на уровне компонента. Это особенно удобно в случаях, когда вы используете одну и ту же иконку в разных местах с разными оттенками. Если ранее для решения подобной задачи было необходимо делать копии одной и той же иконки и менять ей оттенок в дизайнере ресурсов, то сейчас достаточно установить свойство Appearance.Icon.TintColorName равным "Theme\Text\Icon" (к примеру).

    Так же теперь можно указать желаемый размер области вывода иконки. В автоматическом режиме, иконка старается стать как можно больше, занимая все доступное пространство кнопки. При указании фиксированного размера, иконка не сможет превысить указанное значение:

    При этом, кнопка с Contained стилем умеет автоматически подбирать цвета текста и иконки на основании цвета фона (если вы не указали свои цветовые предпочтения явно?

    Помимо этого, если вы хотите отобразить цветную иконку, вы можете отключить автоматическую перекраску через свойство Appearance.Icon.RenderMode.

    Для рамки кнопки мы предусмотрели возможность изменить значение радиуса скругления и толщину рамки.

    Изменения API
    Переименованы свойства ImageName -> IconName, ImageLocation -> Appearnace.Icon.Location, так как на наш взгляд иконка - это небольшой графический элемент, который преимущественно отображается на кнопке. При этом мы оставили обратную совместимость, так что при запуске старого проекта, старое значение из свойства ImageName и ImageLocation будет автоматически прочитано. Свойства TextSettings и TextShadow теперь находятся в группе настроек Appearance.Text. Они так же будут успешно восстановлены для старых проектов. Старые типы кнопок TfgButonKind.Raised и Flat теперь не будут поддерживаться и при открытии проекта автоматически будут сконвертированы в Contained и Text стили. P.S. Всем хороших выходных и успешного кодирования ?
  17. Yaroslav Brovin
    В ближайшее время выйдет новый релиз 1.7.0.0, главной новинкой которого станет новый компонент TfgBottomSheetLayout. Это специальный компонент для организации отображения дочернего содержимого через выдвигаемую панель с нижней части экрана. 
    Обо всех деталях использования компонента ниже.
    Структура
    Новый компонент доступен на вкладке "FGX: Layouts" -> "TfgBottomSheetLayout" и представляет собой композицию из трех частей, аналогичную структуре компонента TfgDrawerLayout:

    TfgBottomSheet - выдвигаемая снизу страница. TfgBottomSheetContent - контейнер для основного содержимого экрана.  TfgBottomSheetLayout - координатор, отвечающий за управление отображением страницы. Состояния и управление TfgBottomSheet
    Страница может находиться в одном из трех конечных состояний:
    Страница полностью открыта - TfgBottomSheetState.Expanded; Страница свернута, но видна ее часть - TfgBottomSheetState.Collapsed;  Страница полностью скрыта - TfgBottomSheetState.Hidden.    
    В любой момент времени текущее состояние страницы можно получить через TfgBottomSheet.State. А чтобы программно управлять страницей, можно воспользоваться следующими методами TfgBottomSheet:
    /// <summary> /// Полностью модально разворачивает панель с анимацией. Основное содержимое <c>TfgBottomSheetLayout.Content</c> /// недоступно.</summary> /// <remarks>Если панель открыта, то ничего не делает.</remarks> procedure ShowModal; /// <summary>Полностью разворачивает панель с анимацией.</summary> /// <remarks>Если панель открыта, то ничего не делает.</remarks> procedure Expand; /// <summary>Сворачивает панель до заголовка с анимацией. </summary> /// <remarks> /// Если у панели нет заголовка, то полностью скрывает панель с экрана. Если панель закрыта, то ничего не делает. /// </remarks> procedure Collapse; /// <summary>Полностью скрывает панель с экрана с анимацией.</summary> /// <remarks>Если панель уже полностью скрыта, то ничего не делает.</remarks> procedure Hide; Настройка скрытия
    Если вы хотите запретить полное скрытие страницы с экрана, вы можете это сделать при помощи свойства TfgBottomSheet.IsHideable. 
    /// <summary>Может ли пользователь полностью скрыть панель?</summary> property IsHideable: Boolean read FIsHideable write SetIsHideable default DefaultIsHideable; Настройка внешнего вида
    За высоту видимой части страницы в свернутом режиме отвечает свойство TfgBottomSheet.PeekHeight:
    /// <summary>Высота части панели, которая не задвигается целиком.</summary> /// <remarks>Работает в связке со свойством<c>Hideable</c>.</remarks> property PeekHeight: Single read FPeekHeight write SetPeekHeight stored IsPeekHeightStored nodefault; По умолчанию страница имеет непрозрачный фон. Однако, в определенных случаях, удобно использовать прозрачный фон. Таким образом можно добиться любой разметки вашего содержимого и добавить любые вложенные контейнеры. За прозрачный режим отвечает свойство TfgBottomSheet.IsTransparent.

    Модальный режим
    По умолчанию панель открывается и не блокирует основное содержимое. Вы можете продолжать взаимодействовать с контентом TfgBottomSheetContent. Таким способом обычно делают панели для отображения сопутствующей детальной информации https://material.io/components/sheets-bottom. Например:
        
    Однако, гораздо чаще используется модальный режим для организации контекстного меню или же открытия нового экрана:

    В этом случае, вам необходимо открыть страницу используя метод TfgBottomSheet.ShowModal.
    Демонстрационные проекты
    В 1.7.0.0 включены два демо-проекты, которые показывают использование модального и обычного режимов использования. Их вы можете найти в ветке "Компоненты" -> "TfgBottomSheetLayout".
  18. Yaroslav Brovin

    Общая
    В ближайшие дни мы выпустим новый релиз FGX Native 1.9.0.0, в который будет включено большое количество разнообразных улучшений, новых возможностей и исправлений ошибок.
    TfgBottomSheetLayout
    Новый компонент, добавленный в 1.8.0.0, имел среди своих возможностей модальный режим отображения страницы.
    У текущей реализации модального режима есть одно ограничение, которое делает его не очень удобным для использования, а именно: у модального режима нет промежуточной стадии Collapsed (когда панель свернута в корешок, но при этом еще не блокирует основное содержимое).
    Мы решили разбить модальный режим на группу новых настроек:
    Настройки затемнения основной области содержимого TfgBottomSheetContent (TfgBottomSheetLayout.ContentShadingSettings). Теперь вы можете включать или отключать затемнение в любой момент времени, а также указать цвет, используемый для затемнения. Эта настройка особенно нужна при поддержке темной темы в вашем приложении.
    Настройка блокирования взаимодействия с основным содержимым компонента TfgBottomSheetLayout.BlockContentMode. /// <summary> /// <para> /// Режим блокирования получения любых событий основного содержимого <с>TfgBottomSheetContent</c>: /// </para> /// <list> /// <item><b>Never</b> - Никогда.</item> /// <item><b>WhenCollapsedOrExpanded</b> - Когда страница свернута или развернута.</item> /// <item><b>WhenExpanded</b> - Только когда страница разворачивается или развернута.</item> /// </list> /// </summary> TfgBlockContentMode = (Never, WhenCollapsedOrExpanded, WhenExpanded); Теперь при помощи этих двух настроек вы сможете гибко настроить модальный режим. Мы удалили старый метод ShowModal. Чтобы сделать его в 1.9.0.0 достаточно в дизайнере указать две настройки TfgBottomSheetLayout:
    BlockContentMode = WhenCollapsedOrExpanded ContentShadingSettings.Enabled = True. Буфер обмена
    Реализован новый кроссплатформенный сервис по работе с системным буфером обмена FGX.Clipboard.TfgClipboardService для Android и iOS. На текущий момент сервис позволяет работать только с текстом. Для ознакомления с работой сервиса доступен пример "Системные сервисы" -> "Текстовый буфер обмена".
    Темы
    Несмотря на то, что темы поддерживаются уже давно, с ними был ряд сложностей, связанных с использованием своих названий ресурсов. Смена темы автоматически работала отлично для всех компонентов, у которых разработчик не указывал свой ресурс. Однако, как только указывался любой ресурс (не по умолчанию), то такой ресурс считался независимым от темы и при переключении темы не менялся. Мы исправили эту ситуацию, и теперь ресурс привязывается к текущей теме формы, если ресурс указывается из текущей формы. Это позволяет сделать полноценное переключение темы для всех свойств. Если же ресурс не привязан к теме, то такой ресурс не будет меняться при смене темы у формы.
    Например, мы хотим кастомизировать оттенок панели навигации и хотим использовать "Dark Primary" цвет вместо "Light Primary". На скриншоте снизу мы указываем ресурс из текущей темы "Theme Light":

    Если же мы переключаем тему у формы со светлой на темную, наш вручную установленный ресурс оттенка панели теперь уже берет одноименный ресурс из темной темы.

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

    TfgListMenu
    Это один из самых старых компонентов и в связи с разными идеями по его улучшению и развитию мы его не трогали. С одной стороны, это довольно удобный компонент для быстрого прототипирования меню, однако, с другой, он был ограничен в ряде настроек, которые позволили его бы слегка подстроить. Поэтому разработчики часто использовали TfgCollectionView вместо TfgListMenu. Мы решили ввести ряд базовых настроек, которые позволяют изменить базовую цветовую схему компонента, для полной совместимости с темами библиотеки.
    Добавлено новое свойство TfgListMenu.Appearance, которое предназначено для настройки цветовой схемы элементов пунктов меню.

    Данная группа настроек не позволяет раскрасить в разные цвета все пункты меню. Это связано с тем, что компонент следует концепции Material Design, где используется общая цветовая схема. Однако теперь, вы можете указать базовые цвета схемы и цвета для разделителя для обычного режима отображения пункта меню и выделенного, чего нельзя было делать ранее.
    Помимо этого, довольно часто, используемые иконки в пунктах меню, необходимо перекрашивать. Это можно было решить на уровне дизайнера ресурсов, просто указав для иконки нужный оттенок. Однако, используемые в меню иконки могут быть использованы в других местах на практике. В такой ситуации приходилось иметь два дубликата одной и той же иконки, но с разными оттенками, что безусловно увеличивает размер приложения и усложняет дальнейшую правку ресурсов. Ситуация осложняется, когда цвет иконки при выделении отличается от цвета иконки без выделения.
    Решение данной проблемы теперь лаконично сделано через новую группу настроек Appearance.Icon, работающей по такому же принципу, как и аналогичное свойство у TfgButton. Здесь вы можете указать цвет иконки без и с выделением. В результате вам достаточно иметь всего лишь одну иконку в ресурсах данного базового размера для всех остальных мест.

    Замер размера текста
    Еще одной из самых часто запрашиваемых возможностей с вашей стороны был функционал по программному замеру размера текста. В 1.9.0.0 появится набор методов у TfgCanvas предназначенных для получения размера текста:
    function MeasureText(const AText: string; const AMaxWidth: Single; const AIsWordWrap: Boolean): TSizeF; И многое другое...
    В релиз 1.9.0.0 включено большое количество правок iOS части в части управления формами, выравниванием и тд. 
  19. Yaroslav Brovin
    Всем хорошей пятницы,
    Немного новостей с полей разработки iOS ?. Мы продолжаем активно работать над реализацией iOS части библиотеки FGX Native и хотим поделиться с вами текущим статусом ?.
    1. Полностью реализованы новые компоненты
    TfgScrollBox, TfgVerticalScrollBox, TfgHorizontalScrollBox, TfgCardPanel, TfgSwitch, TfgTimer
    CardPanel-Demo.mp4.c88e1292626fcdf90ba849929b1bc238.mp4
    2. Частично реализована поддержка TfgBitmap
    Реализованы базовые операции с TfgBitmap: 
    Создание. Работа со скейлом Чтение из разных источников. Сохранение. 3. Добавлена поддержка ресурсов
    Научили iOS приложение работать с нашими ресурсами. Теперь app пакет содержит ресурсы FGX Native приложения.
    4. Реализованы вспомогательные сервисы
    Реализована часть служебных сервисов (IFGXLocaleService, IFGXApplicationInfoService, IFGXScreenService) используемых, в том или ином виде в существующих компонентах и вспомогательных классах.
    5. Частично реализован TfgCollectionView
    Реализована базовая функциональность списка. Создание элементов. Поддержка стилей. Связывание данных. 
    collectionView-3.mp4.3594030bf632722305b29ae89b970b55.mp4 CollectionView.mp4.83702aa8066d5e7d28cb2594fa9c56a9.mp4
    6. Частичная реализация TfgImage
    Реализованы все методы отображения изображений, кроме маски.
    7. Реализация диалогов
    Реализованы диалоговые окна TfgDialogs для отображения сообщений и диалогов с кнопками.
    8. Добавлены новые хедеры для iOS 13.
    Транслированы и добавлены свои собственные хедеры для iOS API.
  20. Yaroslav Brovin
    Всем доброго дня,
    Немного полезной технической информации о следующем релизе 1.4.0.0:
    Поддержка RAD Studio 10.4
    Новый релиз будет посвящен поддержке RAD Studio 10.4 с одной стороны и прекращению поддержки RAD Studio 10.2 с другой стороны. Основные причины:
    Отсутствие жизненно важной поддержки Android 64-bit Нет поддержки push-уведомлений на уровне IDE Новый Java-Delphi мост
    В версии 1.4.0.0 будет полностью обновленный Android-Delphi мост. Он будет основан на нашей текущей реализации моста. Однако он не будет совместимость со старыми заголовочными файлами.
    Это значит, что если вы используете нативное Android API в ваших приложениях, то в версии 1.4.0.0 нужно будет выполнить миграцию. Миграция будет простой. Инструкция будет детально дана ближе к релизу.
    Причина обновления моста связана с удалением поддержки ARC в 10.4. Это приводит к нерациональному и неоправданному использованию делфи классов, как обертки над Java классами. Так как, используя такой подход, необходимо удалять руками все объекты моста. При этом код становится очень тяжелым для восприятия и неудобным для использования. 
    Обновленная версия моста будет улучшенным синтезом нашей текущей реализации и подхода с использованием делфи интерфейсов. Он сохранит все принципы работы с классовыми членами (поля, методы) и способом создания Java объектов. Однако теперь работа с созданным объектом будет осуществлять через интерфейс, а не класс, как было ранее.
    Всем спасибо за внимание и хорошего рабочего дня!
  21. Yaroslav Brovin
    В ближайшем релизе FGX Native 1.1.4.0 появится расширение возможностей TfgCollectionView. Речь идет о перетаскивании элементов списка для ручного упорядочивания элементов.
    video_2020-03-27_04-16-58.mp4.01ba77268ea2bcd5c7b56ad7cf398dcc.mp4
    Для того, чтобы воспользоваться новым функционалом нужно:
    1. Определить, за какой компонент элемента можно будет выполнять перетаскивание элемента.
    Например, можно использовать TfgImage с общепринятой иконкой перетаскивания элементов.
    2. Указать для такого компонента стиля имя через LookupName.

    3. Указать в настройках TfgCollectionView имя компонента из пункта (3).

    4. После перетаскивания элементов в списке, отразить изменение последовательности элементов в вашей модели данных в событии OnMovingItem. 
  22. Yaroslav Brovin
    Hello dear Delphi developers,
    We are happy to share with you two new FGX Native courses in Italian, which Claudio Piffer @claudio.piffer designed and prepared for you. Claudio Piffer is strong Delphi Developer with wide knowledge of different technologies. He often speaks at various Delphi conferences and shares his knowledge with other developers. For us, he is known for two speeches at the DelphiDays conference in Italy (2020, 2022), on which he clearly showed and told the possibilities of FGX Native in the shortest possible time. Claudio has prepared two courses that can help you go into the world of mobile development with Delphi and FGX Native:
    Basic. Mobile developement with FGX Native. Advanced. Advanced concepts in FGX Native. You can find the course description, topics and lessons covered by clicking on the links above.
    Thank you,
    Yaroslav Brovin
  23. Yaroslav Brovin
    Продолжаем освещать новинки обновления 1.15.0.0. И в этот раз речь пойдет про оптимизации старта приложения и новые возможности нашей утилиты Java2Delphi.
    Ускорение запуска FGX Native приложения на Android
    Одним из важных изменений в области работы Java-Delphi мосту - является ускорение запуска FGX Native приложения на Android. До 1.15.0.0 холодный старт пустого приложения мог занимать пару секунд. В 1.15.0.0 мы реализовали отложенную инициализацию Java оберток, в результате чего это позволило нам ускорить старт пустого приложения до ~2-х раз.
    Улучшения в Java2Delphi
    Поддержка AAR
    В новой версии Java2Delphi теперь можно использовать AAR библиотеки. Для этого их нужно указать в конфигурационном файле в ветке "aars".
    "aars": [ "$(FGX)\\Libs\\Android\\fgx.admob.aar" ], Deprecated/Introduced для полей
    Android API меняется от версии к версии. Какие-то типы объявляются устаревшими, какие-то удаленными, а какие-то новыми. Глядя на заголовочный файл тяжело понять, какой метод в какой версии Android доступен. Ранее мы вносили специальные пометки в заголовочные файлы для методов. В этом релизе мы  генерируем аналогичные пометки их и для полей. Так что, теперь можно открыв заголовочный файл, сразу понять в какой версии был добавлен тот или иной элемент, а когда он помечен, как устаревший.
    function isConvex: Boolean; deprecated 'Deprecated in 30'; function addWhitelistedRestrictedPermission(const AArg0: JString; const AArg1: JString; const AArg2: Integer): Boolean; // Introduced in 29'; { constants } property colorMode: Integer read _GetColorMode write _SetColorMode; // Introduced in 26'; Умная генерация параметров при зависимостях
    Одним из главных отличий Java от Delphi является разная реализация пространств имен и доступов к типам. В Delphi по умолчанию два модуля не могут использовать друг друга в интерфейсной части. Появляется так называется циклическая зависимость. В то же время в Java в рамках одного пакета все классы могут использовать друг друга. Получается, что заголовочные обертки для всех классов одного пакета в Java должны были быть объявлены в одном Delphi модуле. Это в свою очередь приводило к значительному росту заголовочного файла. Так как нельзя размещать взаимно используемые классы в разных модулях.
    В этом релизе мы так же улучшили это. Теперь вы можете раскидывать классы по разным модулям, даже если они взаимно используют друг друга. Чтобы избежать циклической зависимости, класс в одном из модулей заменяется на общий JObject. 
    Например:
    Мы выделяем все типы, связанные с анимацией в модуль Android.Api.Animations. Эти типы используют JView, который объявлен в  "Android.Api.ActivityAndView". Часть типов анимации используются в классе Android.Api.ActivityAndView.JView. Так геттер getAnimation должен вернуть объект JAnimation. Однако, данный тип, объявлен в Android.Api.Animations.
    JView = interface(JObject) // function getAnimation: JAnimation; // end; Получается циклическая зависимость. И раньше такой код не мог быть скомпилирован. Сейчас же такая зависимость заменяется генератором на такой код с указанием оригинального класса в фигурных скобках:
    JView = interface(JObject) // function getAnimation: JObject {JAnimation}; // end; Чтобы при использовании получить объект JAnimation, достаточно написать такой код:
    var Animation: JAnimation; Animation := TJAnimation.Wrap(View.getAnimation);
  24. Yaroslav Brovin
    Добрый день!
    Новый релиз 1.14.5.0 посвящен полноценной поддержке RAD Studio 11.2 и новой платформе iOS Simulator ARM 64-bit. Помимо этого, мы немного улучшили средства просмотра Андроид логов и компонент TfgButton.
    iOS Simulator ARM 64-bit
    В этой версии добавлена поддержка iOS Simulator ARM 64-bit. Теперь вы можете запускать ваши FGX Native приложения на симуляторе. Однако, помните, что данный симулятор работает только на процессорах Apple. Так же компоненты авторизации через Facebook Login не поддерживаются в данный момент на симуляторе.
    Улучшения Android Log Viewer
    В этой версии, мы почерпнули несколько интересных идей у Android Studio и реализовали продвинутую раскраску сообщений. Теперь сообщения одного одного процесса визуально выделяются одним и тем же цветом. Это улучшает визуальное разделение сообщений разных процессов.

    Внутренние отступы TfgButton
    Помимо поддержки 11.2 добавлена возможность менять стандартные внутренние отступы у кнопки TfgButton. Иногда требуется убрать отступы, чтобы расширить область отображения надписи и иконки. Теперь это можно сделать при помощи свойства TfgButton.Appearance.ContentPadding.

    RAD Studio 11.2 
    Новая версия RAD Studio 11.2 сломала обратную совместимость некоторых пакетов дизайнера с 11.0 и 11.1. В результате чего версия 1.14.4.0 не работает на 11.2, а 1.14.4.1 не работает на 11.1. В этом релизе мы поставляем две версии дизайнера: отдельно для 11.0-11.1 и 11.2. При установке необходимо выбрать интересующую вас версию.
    Спасибо за внимание, 
    Ваша команда FGX Native
×
×
  • Create New...