Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation since 05/20/21 in all areas

  1. Нам очень приятно поделиться с вами этой новостью. Одно из приложений, написанных на 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
    13 points
  2. Здравствуйте. Еще одним нововведением в релизе 1.11.2.0, помимо TfgPopup, является работа с пикселями ("сырыми данными") TfgBitmap. Доступ к пикселям открывает практически неограниченные возможности для обработки и анализа изображений. Так же в новом релизе будет добавлена возможность поворота изображения. Воможность работы с пикселями TfgBitmap. Общие сведения. Обращение к сырым данным возможно только между парными вызовами TfgBitmap.MapData и TfgBitmap.UnmapData, которые могут быть знакомы пользователям FMX. Однако, важным отличием от FMX, является отсутствие уровня доступа (только чтение/только запись/чтение и запись). Это сделано с целью ускорения доступа, т. к. работа осуществляется непосредственно с данными нативного изображения без создания промежуточного буфера. В результате вызова TfgBitmap.MapData вы получаете интерфейс IFGXBitmapData (более подробно рассмотрен ниже), который предоставляет доступ к пикселям изображения. Важно! Актуальность объекта IFGXBitmapData гарантирована только между вызовами TfgBitmap.MapData и TfgBitmap.UnmapData, т.к. используется "натуральный" интерфейс без подсчета ссылок. Важно! Во время доступа к сырым данным операции по изменению TfgBitmap запрещены (например загрузка из различных источников, изменение размера, масштаба, поворота и тд). Типичный пример работы с сырыми данными изображения: var LBitmapData: IFGXBitmapData; begin if LBitmap.MapData(LBitmapData) then try // Работа с пикселями изображения. finally LBitmap.UnmapData; end; end; Важно! Всегда проверяйте результат выполнения TfgBitmap.MapData во избежание непредвиденных последствий. Повторный вызов TfgBitmap.MapData для уже спроецированных данных вернет ложь. Интерфейс IFGXBitmapData. Интерфейс IFGXBitmapData предоставляет информацию об изображении (Info, Width, Height), а так же позволяет манипулировать пикселями изображения (RawData, Scanlines, Pixels, Colors). Информация о битмапе TfgBitmapInfo: BitsPerPixel — количество бит на один пиксель изображения. К примеру, для одного из самых распространенных вариантов ARGB, этот параметр будет равен 32-ум битам. BytesPerRow — количество байт на одну строку изображения. Обычно это Width * BitsPerPixel, но, в случае применения выравнивания для ускорения доступа к данным, значение может быть иным. PixelFormat — формат пикселя изображения. В отличии от фиксированного формата ARGB присущего стандартному типу TAlphaColor, нативные изображения могут иметь различный состав и порядок следования цветовых компонентов. Возможные комбинации этих параметров отражает тип TfgBitmapPixelFormat. TfgBitmapPixelFormat = (Unknown, Alpha, Gray, ARGB, RGBA, RGB, RGB24); IsAlphaPremultiplied — флаг, показывающий являются ли компоненты пикселя предварительно помноженными на компоненту прозрачности. Интерфейс IFGXBitmapData содержит несколько вариантов доступа к самим данным, которые отличаются по степени абстракции: RawData — самый низкий уровень. Возвращает указатель на начало данных. Размер данных можно узнать из свойства RawDataSize. Scanlines — указатель на переданную в аргументе строку. Размер данных строки в байтах можно получить из Info.BytesPerRow, количество пикселей в строке — Width. Pixels — указатель на пиксель. В аргументах передаются координаты пикселя. Размер пикселя в битах можно получить из Info.BitsPerPixel. Colors — цвет пикселя в стандартном формате TAlphaColor. В аргументах передаются координаты пикселя. Как правило, для достижения максимальной скорости при последовательном сканировании пикселей изображения, вместо индексного доступа (Pixels, Colors) используют инкрементный перебор начиная с некой точки отсчёта (начало изображения RawData, начало определенной строки Scanlines[Y], определенный пиксель Pixelsх[X, Y]) . В этом случае вы получаете указатель, вместо привычного TAlphaColor. Для преобразования данных по указателю в тип TAlphaColor вам могут пригодиться готовые варианты для конвератции, которые находятся в хэлпере TAlphaColorHelper из модуля FGX.Types.Color. Для формирования TAlphaColor из сырых данных используйте перегруженный конструктор: constructor Create(const APixel: PByte; const APixelFormat: TfgBitmapPixelFormat; const AIsAlphaPremultiplied: Boolean); overload; Для обратной операции подойдет метод: /// <summary>Записывает текущий цвет по адресу <c>APixel</c> с учетом опций <c>APixelFormat</c> и <c>AIsAlphaPremultiplied</c>.</summary> procedure ToPixel(const APixel: PByte; const APixelFormat: TfgBitmapPixelFormat; const AIsAlphaPremultiplied: Boolean); Реальный пример работы с сырыми данными. Ниже приведен кусок кода из нового демонстрационного примера "Графика" -> "TfgBitmap - работа с "сырыми" данными" в котором изображение преобразуется из цветного в оттенки серого. uses FGX.Types.Color, FGX.Canvas.Types, FGX.Canvas.Types, FGX.Assets, FGX.Assets.BitmapSet; procedure TFormMain.fgButton1Tap(Sender: TObject); var LBitmapSet: TfgAssetBitmapSet; LBitmap: TfgBitmap; LBitmapData: IFGXBitmapData; I, J: Integer; begin if not TfgAssetsManager.Current.Find<TfgAssetBitmapSet>('Image', LBitmapSet) then Exit; LBitmap := LBitmapSet.GetBitmap; if LBitmap.MapData(TfgBitmapDataAccessMode.ReadWrite, LBitmapData) then try for J := 0 to LBitmap.Height - 1 do for I := 0 to LBitmap.Width - 1 do LBitmapData.Colors[I, J] := LBitmapData.Colors[I, J].ToGrayscale; finally LBitmap.UnmapData; end; fgPaintBox1.Invalidate; end; Повороты изображения. Благодаря добавлению работы с сырыми данными появилась возможность с легкостью вращать изображения. Поворот осуществляется с помощью метода TfgBitmap.Rotate: /// <summary>Поворачивает изображение на указанный угол.</summary> procedure Rotate(const AAngle: TfgRotation); В качестве аргумента передается одно из предустановленных значений угла поворота. TfgRotation = (Rotation0 = 0, Rotation90 = 90, Rotation180 = 180, Rotation270 = 270); Поворот осуществляется по часовой стрелке. Благодарим за внимание и приятного коддинга 🙂.
    10 points
  3. Доброго дня! В ближайшем релизе 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;
    10 points
  4. Название приложения: Калькулятор электропривода Платформа: Android 32 bit, Android 64 bit Поддерживаемые версии ОС: Android 5.0 и новее Необходимое свободное место: до 80 Мб Ссылка на приложение: https://play.google.com/store/apps/details?id=ru.atpdevelop.aepcalculater Описание: Калькулятор электропривода - приложение, созданное в помощь студентам для расчета и выбора электропривода. Базовая Lite версия приложения позволяет произвести расчет нескольких параметров двигателя: номинальную мощность, номинальный ток, эквивалентную мощность и эквивалентный момент инерции. Исходя из рассчитанных параметров можно выбрать двигатель, если он есть в базе данных. Содержит небольшой ликбез по основам асинхронных двигателей. Разработчики: Ильяшевич Дмитрий, Супрунчук Павел. Скриншоты окон приложения в спойлере:
    10 points
  5. Скачать: setup_1.11.1.0_release.rus.zip Дата релиза: 26 мая 2021 Улучшения 🙌 TfgBottomSheetLayout Добавлена группа настроек TfgBottomSheetLayout.BlockContentSettings позволяющая автоматически свернуть/закрыть страницу в модальном режиме при касании заблокированной области основного содержимого. В эту группу перемещено свойство BlockContentMode -> BlockContentSettings.Mode. Теперь вы можете выбрать, какое действие нужно совершить автоматически при нажатии на заблокированную область основного содержимого через свойство BlockContentSettings.AutoCloseAction. Так же вы можете теперь поймать событие касания этой области через новое событие TfgBottomSheetLayout.OnBlockedContentTap для ручных манипуляций со страницей. FGX-60 Hide/Close TfgBottomSheetLayout. FGX-61 TfgBottomSheetLayout AutoHide. Менеджер ресурсов Добавлен новый метод TfgAssetsFactory.SaveConfigToFile, который позволяет сохранить информацию об отфильтрованных ресурсов в любой файл. Пример сохранения всех ресурсов, у которых имя начинается с префикса 'Cache': const CachePrefix = 'Cache'; TfgAssetsFactory.SaveConfigToFile(TfgAssetsManager.Current, ConfigFileName, function (const AAsset: TfgAsset): Boolean begin Result := string(AAsset.Name).StartsWith(CachePrefix); end, [TfgWritingOption.EmitEmptyAssets]); FGX-35 Assets Добавить возможность сохранять информацию об ассетах в файл. Прочее Теперь TfgWebBrowser может открывать https страницы, которые имеют проблемы с сертификатом (Android). Добавлены хелперы ToString и ToARGBHex для TAlphaColor. Добавлен заголовочный файл Android.Api.Accessibility для возможности использования Android Accessibility. Исправление ошибок 🐛 FGX-62 TfgAnimationHelper Access Violation (iOS). FGX-63 Некорректная работа fgNavigationBar (iOS). FGX-64 TfgBottomSheet не сохраняет AlignmentChildren.Direction. FGX-66 TfgCardPanel Магические способности(iOS). FGX-67 TfgAnimationHelper.ShowForm(FrameName) падает (iOS). FGX-68 Новая анимация - крашится приложение при вызове HideForm. FGX-69 Исключение при загрузке изображений (Android). Свойство TfgBottomSheetLayout.BlockContentMode не работало, если ContentShadingSettings.Enabled = False (Android).
    10 points
  6. 0) Свершилось, сразу прошу прощения, доступно только для Украины, потому большинству скачать не удастся (там и смотреть нечего) https://apps.apple.com/ua/app/лувис/id1561453338?l=ru 1) Предполагаем, что у нас есть платный аккаунт разработчика а) На сайте appstoreconnect.apple.com создаем приложение б)Создаем скриншоты, отвечаем на вопросы, я отвечал максимально честно, но учитывая то что мое приложение было бесплатным и не содержало рекламы, наверное что-то я выпустил из виду в)Самое сложное было не лукавя сказать про определение местоположение и идентификатор устройства. 2) Подготовка к публикации а) По прежнему предполагаем что у нас есть платный аккаунт разработчика, и вы сделали все, чтобы создать файл .ipa с Конфигурацией AppStore б) Далее предполагаем, что программа Transporter на Apple Mac или его заменителе (в моем случае), успешно установлена в) Загружаете созданный .ipa в траспортер и с помощью боковой клавиши ..., проверяете его перед загрузкой в AppStore г) С помощью appstoreconnect.apple.com пытаетесь опубликовать приложение . 3) Хатико а) По сравнению с Гугл ревизия происходит очень быстро, первый мой reject произошел в течении часа с вердиктом Метаданные отклонены. Они были отклонены по двум причинам а1) Отсутствие дополнительной информации (об этом позже) а2) Отсутствие аккаунта для тестирования Я понял, что самое интересное впереди, причем пункт а2 был у меня не готов полностью, учитывая замороченную процедуру регистрации, я взял таймаут для обдумывания 4) Возвращение Мухтара а) Исправив ошибку с аккаунтом для тестирования (к слову, если смотреть по логам, тестировал живой человек, причем ленивый, зашел в три формы, и устал), отправил повторно на ревизию б) Ревизия продолжалась два часа с вердиктом метаданные отклонены. И со следующим комментарием От: Apple 2. 1 Performance: App Completeness Guideline 2.1 - Information Needed We’re looking forward to continuing our review, but we need more information about your business model and your users to help you find the best distribution option for your app. Our preliminary review of your app suggests that your app may be a good fit for our Apple Business Manager program, which is designed specifically for business apps. Next Steps Please review the following questions and provide as much detailed information as you can for each question. 1. Is your app restricted to users who are part of a single company? This may include users of the company's partners, employees, and contractors. 2. Is your app designed for use by a limited or specific group of companies? - If yes, which companies use this app? - If not, can any company become a client and utilize this app? 3. What features in the app, if any, are intended for use by the general public? 4. Identify the specific countries or regions where you plan to distribute your app. 5. How do users obtain an account? 6. Is there are any paid content in the app? For example, do users pay for opening an account or using certain features in the app? 7. Who pays for the paid content and how do users access it? Since your App Store Connect status is Metadata Rejected, we do NOT require a new binary. To revise the metadata, visit App Store Connect to select your app and revise the desired metadata values. Once you’ve completed all changes, reply to this message in Resolution Center and we will continue the review. в) Я написал в ответ слезное, вежливое письмо с подробными ответами на вопросы. Учитывая возможно скудное владение русским языком моего визави, языком письма был выбран язык вероятного противника (английский) г) В течении нескольких минут я получил ответ После этого на протяжении небольшого времени (пару часов), я имел возможность наблюдать свою поделку на App Store Чего и вам всем желаю. З.Ы. Простите за сумбурность изложения, я надеюсь, что некоторые моменты публикации я прояснил. Всем спасибо.
    9 points
  7. Скачать: setup_1.11.2.0_release.rus.zip Дата релиза: 19 июня 2021 Новое ✨ Выпадающие окна TfgPopup В этом релизе добавлена возможность отображать любое содержимое в виде выпадающего окна, прикрепленного к указанному компоненту. Чтобы создать выпадающее окно TfgPopup необходимо воспользоваться фабрикой TfgPopupFactory и передать туда отображаемый компонент. В качестве компонента можно указывать любой визуальный компонент, в том числе и форму. FPopup := TfgPopupFactory.CreatePopup(FPopupContent); FPopup.Size := TSizeF.Create(200, 300); Чтобы отобразить попап необходимо указать компонент, относительно которого должно отобразиться выпадающее окно. Дополнительным параметром можно указать смещение. FPopup.DropDown(fgButton1); Если вы используете темы в вашем приложении, то вы можете указать название темы через свойство ThemeName. По умолчанию выпадающее окно отбрасывает тень. Однако, вы можете использовать прозрачный стиль выпадающего окна. Это управляется через свойство IsTransparent. Добавлен новый демонстрационный проект: "Компоненты" -> "TfgPopup" -> "Базовый пример". Детали: Улучшения 🙌 TfgBitmap Добавлена возможность работы с "сырыми" данными TfgBitmap с помощью IFGXBitmapData. Для начала работы вызовите TfgBitmap.MapData и TfgBitmap.UnmapData по окончанию. Добавлена возможность поворота TfgBitmap на фиксированный угол. Доступны повороты на 90, 180 и 270 градусов. Добавлен новый демонстрационный проект: "Графика" -> "TfgBitmap - работа с "сырыми" данными". Подробнее: TfgWebBrowser Пересмотрена обработка открытия ресурсов с проблемными сертификатами. Теперь по умолчанию, такие сайты не открываются. Если вы хотите допустить их отображение, необходимо использовать новое событие TfgWebBrowser.OnSSLError и через параметр AHandler запретить или разрешить загрузку таких ресурсов. Добавлен новый демонстрационный проект: "Компоненты" -> "TfgWebBrowser" -> "Обработка ошибок сертификатов". TfgCamera Для камеры добавлена возможность указывать режим работы вспышки в момент снятия фотографии. Это поведение управляется новым свойством TfgCamera.FlashMode. Дополнительно можно использовать вспышку в качестве фонарики в процессе работы предпросмотра (Preview). Это задается через новое свойство TfgCamera.TorchMode. Обратите внимание, что фонарик работает только в режиме превью и игнорируется в момент съемки фотографии. FGX-75 TfgCamera добавить функционал включения вспышки. Обновлен демонстрационный пример: "Компоненты" -> "TfgCamera" -> "Фотокамера". Добавлены элементы управления для включения вспышки и режима фонарика. Исправление ошибок 🐛 Динамическое изменение размера TfgBitmap могло приводить к исключению (Android). Методы TfgCanvas.DrawBitmap и TfgCanvas.DrawBitmapWithMask отрисовывали изображение со скейлом TfgBitmap вместо скейла TfgCanvas, что приводило к неверному размеру изображения (Android). FGX-77 TfgAnimationHelper Access Violation (iOS). FGX-78 TfgEdit нет фокуса после enabled-false/true (Android). FGX-79 Вызов событий TfgCollectionView после TfgForm.OnDestroy. FGX-80 SSL Error Handler (Android). Исправлен демонстрационный проект: "Android Api" -> "AlarmManager". Добавлен проект для сборки Java части в Android Studio.
    7 points
  8. Download: setup_1.11.2.0_release.eng.zip Release date: 19 June 2021 New ✨ Drop down window TfgPopup This release adds the ability to display any content as a drop-down window attached to the specified component. To create the TfgPopup drop-down window you need to use the TfgPopupFactory factory and pass the displayed component there. As a component, you can specify any visual component, including a form. FPopup := TfgPopupFactory.CreatePopup(FPopupContent); FPopup.Size := TSizeF.Create(200, 300); You must specify the component that the drop-down window should be displayed relative to. An additional parameter can be used to specify the popup offset. FPopup.DropDown(fgButton1); If you use themes in your application, then you can specify theme name via property ThemeName. By default, the drop-down window displays a shadow. However, you can use the transparent style of the drop-down window. This is managed via the Transparent property. New demo sample was added: "Components" -> "TfgPopup" -> "Basic sample". Details: https://translate.yandex.ru/translate?lang=ru-en&url=https%3A%2F%2Fforum.fgx-native.com%2Fblogs%2Fentry%2F29-выпадающие-окна-tfgpopup%2F Improvements 🙌 TfgBitmap Added the ability to work with raw data TfgBitmap using IFGXBitmapData. To get started, call TfgBitmap.MapData and TfgBitmap.UnmapData when finished. Added the ability to rotate TfgBitmap by a fixed angle. Turns are available 90, 180 and 270 degrees. New demo sample was added: "Canvas" -> "TfgBitmap - working with raw data". Details: https://translate.yandex.ru/translate?lang=ru-en&url=https%3A%2F%2Fforum.fgx-native.com%2Fblogs%2Fentry%2F30-новые-возможности-tfgbitmap%2F TfgWebBrowser Revised the handling of opening sites with problematic certificates. Now, by default, such sites are not opened. If you want to allow them to be displayed, you need to use the new event TfgWebBrowser.OnSSLError and use the AHandler parameter to prohibit or allow loading of such resources. New demo sample was added: "Components" -> "TfgWebBrowser" -> "Handling certificate errors". TfgCamera We added possibility to setup flash mode in the moment of taking photo. You can set this mode via the new property TfgCamera.FlashMode. Also you can use flash as a torch, while camera works only in preview mode. You can do it via the new property TfgCamera.TorchMode. Pay attention, it works only in preview and doesn't work in moment of taking photo. FGX-75 TfgCamera Add functionality for enabling flash. The demo sample was updated: "Components" -> "TfgCamera" -> "Camera". New controls were added for switching flash and torch modes. Bug Fixes 🐛 Dynamical changes of TfgBitmap size could lead to raising exception (Android). TfgCanvas.DrawBitmap and TfgCanvas.DrawBitmapWithMask methods rendered an image with the TfgBitmap scale instead of the TfgCanvas scale, which resulted in an incorrect image size (Android). FGX-77 TfgAnimationHelper Access Violation (iOS).setup_1.11.2.0_release.eng.zip FGX-78 TfgEdit has no focus after enabled-false/true (Android). FGX-79 Raising TfgCollectionView events after TfgForm.OnDestroy. FGX-80 SSL Error Handler (Android). The demo sample was fixed: "Android Api" -> "AlarmManager". The additional Android Studio project was added for building Java part. setup_1.11.2.0_release.eng.zip
    2 points
  9. Download: setup_1.11.1.0_release.eng.zip Release date: 26 May 2021 Improvements 🙌 TfgBottomSheetLayout The new group settings property were added TfgBottomSheetLayout.BlockContentSettings. It allows to specify default action, when user taps blocked content area. The old property BlockContentMode was moved to BlockContentSettings.Mode. Now you can choose which action to perform automatically when clicking on the blocked area of the main content via the BlockContentSettings.AutoCloseAction. You can also now catch the touch event of this area via the new TfgBottomSheetLayoutOnBlockedContentTap event for manual page manipulation. FGX-60 Hide/Close TfgBottomSheetLayout. FGX-61 TfgBottomSheetLayout AutoHide. Assets manager The new method TfgAssetsFactory.SaveConfigToFile was added, which allows to save information about filtered assets in file. Example of saving all resources whose name starts with the Cache prefix: const CachePrefix = 'Cache'; TfgAssetsFactory.SaveConfigToFile(TfgAssetsManager.Current, ConfigFileName, function (const AAsset: TfgAsset): Boolean begin Result := string(AAsset.Name).StartsWith(CachePrefix); end, [TfgWritingOption.EmitEmptyAssets]); FGX-35 Add a possibility to save filtered assets to config file. Other TfgWebBrowser can open https pages with certificate issues (Android). The new helpers methods ToString and ToARGBHex were added for TAlphaColor. The new header file Android.Api.Accessibility was added for using Android Accessibility. Bug Fixes 🐛 FGX-62 TfgAnimationHelper Access Violation (iOS). FGX-63 Incorect rendering background of fgNavigationBar (iOS). FGX-64 TfgBottomSheet doesn't store AlignmentChildren.Direction value. FGX-66 TfgCardPanel wrong rendering background color (iOS). FGX-67 TfgAnimationHelper.ShowForm(FrameName) is crashed (iOS). FGX-68 Application was crashed, when the HideForm was invoked. FGX-69 AddBitmapFromUrlAsync could led to exception sometimes (Android). The TfgBottomSheetLayout.BlockContentMode property didn't work, if ContentShadingSettings.Enabled = False (Android). The transation of TfgTranslation designer was fixed.
    2 points
  10. Продолжаем серию статей, посвященных новинкам релиза 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, в результате чего анимация открытия/закрытия форм будет осуществляться автоматически и не будет требовать от вас лишних строчек кода. Итог Мы продолжим развивать и совершенствовать реализацию анимаций. Поэтому нам очень важно получить от вам обратную связь о том, что удобно, что нет и чего не хватает. Эта информация поможет нам сделать анимацию лучше и удобнее для всех.
    2 points
  11. Hello. We are sorry. We have some technical problems. We try to solve them as quickly as possible. Thank you.
    1 point
  12. Hello , A wonderful feature , But what about the Drop-Down Directions ( From Top to Bottom or Bottom To Top ) it gonna be a real feature . Thank you .
    1 point
  13. Здравствуйте. Ошибка подтверждена. Ваша сообщение переведено в баг трекер.
    1 point
  14. Давайте предметные вопросы задавать в соответствующих ветках форума с деталями, что делается и как. Желательно с кусками кода или демо проектом. А то такие вопросы легко теряются именно здесь среди других комментариев. Спасибо
    1 point
  15. Здравствуйте. Проблема в iOS мосте (RTL) на Rio. В настоящий момент мы ищем решение.
    1 point
  16. В следующем релизе FGX Native 1.11.0.0 будет много новых интересных возможностей, которые безусловно найдут свое место в ваших приложениях. В этой статье поговорим о первой новинке: получение фотографии с камеры или из системной галереи изображений. До версии 1.11.0.0 получение фотографии с камеры, было не самой тривиальной задачей. Было два решения, которым обычно пользовались разработчики: Использование напрямую камеры и разработка своего решение на базе демонстрационного проекта "Компоненты" -> "TfgCamer" -> "Фотокамера". Несмотря на то, что этот способ рабочий и он дает возможности по кастомизации внешнего вида видеоискателя, зачастую требуется просто получить фотографию от пользователя. Использование нативного API каждой платформы для отправки запроса на получение фотографии системным приложениям. TfgPhotoPicker В этом релизе мы предлагаем кроссплатформенное решение в виде специального типа пикера, используемого для выбора фотографии из системной галереи изображений или снятия фотографии с системной камеры. video_2021-05-12_01-16-46.mp4 Чтобы отправить запрос на получение фотографии с камеры достаточно написать всего три строчки кода: uses FGX.Assets, FGX.Assets.Helpers, FGX.Pickers.Photo; procedure TFormMain.btnTakePhotoFromCameraTap(Sender: TObject); begin TfgPickerPhotoFactory.PickPhotoFromCamera(btnTakePhotoFromCamera, procedure(const AFileName: TFileName) begin TfgAssetsManager.Current.AddBitmapFromFile('Photo', AFileName, True); end); end; Для получения фотографии из галереи: procedure TFormMain.btnTakePhotoFromLibraryTap(Sender: TObject); begin TfgPickerPhotoFactory.PickPhotoFromLibrary(btnTakePhotoFromLibrary, procedure(const AFileName: TFileName) begin TfgAssetsManager.Current.AddBitmapFromFile('Photo', AFileName, True); end); end; Запрос отправляет через специальную фабрику FGX.Pickers.TfgPickerPhotoFactory, которая предлагает три метода: TfgPickerPhotoFactory = class public /// <summary>Создает и возвращает платформенный пикер получения фотографии для ручной работы.</summary> /// <remarks>Удаление пикера лежит на плечах вызываемого кода.</remarks> class function CreatePicker(const AOwner: TObject): TfgPickerPhoto; /// <summary> /// Иницирует получение фотографии с системного приложения камеры. Фотография возвращается в переданную /// анонимную процедуру <c>AOnDidFinishPickingCallback</c>. /// </summary> /// <remarks> /// Вам не требуется следить за временем жизни возвращаемого пикера. Пикер автоматически удалится после того, /// как он будет закрыт пользователем. /// </remarks> class function PickPhotoFromCamera(const AOwner: TObject; const AOnDidFinishPickingCallback: TfgDidFinishPickingCallback): TfgPickerPhoto; /// <summary> /// Иницирует получение фотографии с системного приложения галереи изображений. Фотография возвращается в /// переданную анонимную процедуру <c>AOnDidFinishPickingCallback</c>. /// </summary> /// <remarks> /// Вам не требуется следить за временем жизни возвращаемого пикера. Пикер автоматически удалится после того, /// как он будет закрыт пользователем. /// </remarks> class function PickPhotoFromLibrary(const AOwner: TObject; const AOnDidFinishPickingCallback: TfgDidFinishPickingCallback): TfgPickerPhoto; end; Второй и третий метод предназначены для быстрого получения фотографии с камеры или из галереи. Первый же метод предназначен для ручной настройки пикера и отлова всех событий (открытие, закрытие, отмена и тд.). Внимание! Для корректной работы пикера на платформе Android необходимо в настройках проекта включить опцию: Project -> Options... -> Application -> Entitlement List -> Security File Sharing = True. Также мы подготовили демонстрационный проект, который позволит вам попробовать эту возможность самостоятельно: "Компоненты" -> "Пикеры" -> "Получение фотографии". Всем хорошей рабочей недели. Следите за будущими анонсами FGX Native 1.11.0.0.
    1 point
  17. Мы постоянно работаем над расширением возможностей библиотеки 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.
    1 point
  18. В данном проекте самостоятельно формировал запросы и отправлял их. После разбирал ответы... Использовал для этого доку по REST API - https://firebase.google.com/docs/database/rest/start?authuser=0 В последнее время стал пользоваться FB4D - https://github.com/SchneiderInfosystems/FB4D Довольно удобная либа. В ней есть и авторизация по email, и работа с RelatimeDB, Firestore, Storage
    1 point
  19. Добрый день, Мы выложили запись прошедшего 18 февраля вебинара по теме "Пробная сессия вопросов и ответов по FGX Native". Видео доступно на нашем YouTube канале. На вебинаре обсуждались следующие темы: Android SDK/NDK; Сервисы локации; Асинхронная загрузка изображений в списках; Планы на ближайшие релизы.
    1 point
  20. Мы стараемся делать так, чтобы FGX Native стала эффективным инструментом ? для разработчиков, приносила результаты и доставляла удовольствие от работы ?. Мы постоянно работаем над расширением возможностей и предоставляем новый функционал. Однако, с учетом молодости проекта FGX Native по нему не так много информации. Эффективность использования зависит от ваших умений и навыков. А для развития этих умений и навыков нужны обучающие материалы ?‍?, примеры правильного использования. Мы решили провести небольшой пробный эксперимент и для начала записать пару обучающих видео уроков по использованию FGX Native. Рад представить вам первый, самый базовый урок для начинающих о начале разработки мобильных приложений с FGX Native и Delphi. В уроке рассматривается: Настройка рабочего окружения; Создание Hello World мобильного приложения; Запись и чтение логов в FGX Native. Следующий урок будет о системе выравнивания Flex в FGX Native. Рассмотрим типовые задачи и их решения. Сверстаем сложный макет приложения. Чтобы не пропустить, подписывайся на новый официальный канал FGX Native: https://www.youtube.com/channel/UCd818Et5Fi0Iy53YouBce3w Приятного обучения:
    1 point
  21. Здравствуйте. Можно ли добавить компонент для создания своих звуков и каналов для push уведомлений пожалуйста. Что бы это из коробки решалось.
    1 point
×
×
  • Create New...