Перейти к содержанию
Fire Monkey от А до Я

Error

Пользователи
  • Постов

    167
  • Зарегистрирован

  • Посещение

  • Победитель дней

    8

Сообщения, опубликованные Error

  1. 54 минуты назад, Steepe_Hare сказал:

    А как обстоит дело с матчастью? (литература для написания на FMX под iOS, форумы, готовые решения)

    Форумы - прежде всего этот.

    Готовые решения - периодически на http://www.fmxexpress.com/ проскакивает разное, на Google+ есть Delphi сообщество, https://www.beginend.net/ - агрегатор блогов, на https://habrahabr.ru/hub/delphi/ бывают полезные матерьялы.

  2. 8 часов назад, wamaco сказал:

    Мужики, очень хочу прийти, но обстоятельства...

     

    В ‎23‎.‎12‎.‎2016 в 00:12, Zawuza сказал:

    Ох, извините, резко планы поменялись, я не дойду, извиняюсь :( 

    Но зато это заставило меня зарегистрироваться на этом форуме, ахаха :))))

    Ну ёлы-палы... :(

  3. 4 часа назад, kami сказал:

    @Error нужен точный подсчет ! +- 1,5 землекопа.

    Коллеги, прошу отметиться здесь - кто будет.

    Известный мне список:

    @Error, @Brovin Yaroslav, @RoschinSpb , @kami , @wamaco (вроде как, не увидел явного согласия).

    Судя по всему это все.

    Но еще раз: Суббота, 17:30, "Чердак", кто еще решился прийти на сходку FMX/Delphi/C++Builder разработчиков?

  4. 10 минут назад, Kitty сказал:

    Просьба, если встреча состоиться, предоставить фотоотчет с участниками. Мне очень хочеться ники транслировать в реальные образы. :)

    Ярослава знаю в лицо, например, по семинарам эмбаркадеро...

    У меня в профиле мой вк есть, но фотоотчет постараюсь сделать :)

  5. Ссылка: https://habrahabr.ru/post/317814/

    Автор: Пётр (Error)

    Описание:

    За годы существования фреймворк Fire-Monkey(FMX) претерпел множество изменений, и если с самого начала он был очень сырым и ненадежным, то сейчас это намного более стабильная и надежная платформа.
    Данная заметка представляет из себя сборник из нескольких полезных советов для разработчиков использующих данный фреймворк...

  6. 1 час назад, Steepe_Hare сказал:

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

    Или много ресурсов будет отнимать?

    Да, намного дешевле отрисовывать в пейнтбоксе самому.

  7. 14.12.2016 19-26-7.png

    https://github.com/errorcalc/PackagesGenerator/
    PackagesGenerator для Delphi

    Если вы пишете компоненты для Delphi, то вы знаете, как трудно поддерживать несколько версий Delphi. Обычно вы получаете много почти одинаковых dpk, dproj, groupproj файлов для разных версий Delphi,

    Пример:

    MyComponents_XE2.groupproj
    MyComponents_XE2.dpk
    MyComponents_XE2.dproj
    MyComponentsDesign_XE2.dpk
    MyComponentsDesign_XE2.dproj
    MyComponents_XE3.groupproj
    MyComponents_XE3.dpk
    MyComponents_XE3.dproj
    MyComponentsDesign_XE3.dpk
    MyComponentsDesign_XE3.dproj
    ...
    MyComponentsDesign_RX10Berlin.dproj


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

    ErrorSoft PackagesGenerator может решить эту проблему!
    PackagesGenerator генерирует необходимые файлы, делая необходимые внутренние изменения (LIBSUFFUX, contains ...).

    Параметры генерации задаются в INI файле (пример):

    [Folders]
    Base=Source\ <- the path to the original files
    Gen=Packages\ <- the path to the generated files
    GroupAbove=True
    
    [Versions]
    RX10Godzilla=320
    RX10Berlin=310
    RX10Seattle=300
    XE8=290
    XE7=280
    XE6=270
    XE5=260
    XE4=250
    XE3=240
    XE2=230
    
    [Files]
    MyComponents.groupproj
    MyComponentsDesign.dpk
    MyComponents.dpk
    MyComponentsDesign.dproj
    MyComponents.dproj


    Данный INI и PackagesGenerator сгенерирует все необходимые файлы!

    Для примера смотрите: https://github.com/errorcalc/FreeEsVclComponents, папку "Packages".

    Лицензия:
    Доступны три лицензии:
    1) Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public License.
    Некоммерческая лицензия, для некоммерческого использования:
    (exaple: Personal use, Study, Open Source,...)

    2) GNU GPL v3: https://www.gnu.org/licenses/gpl.html (ТОЛЬКО для открытых OpenSource проектов)

    3) ErrorSoft PackagesGenerator Commercial license.(see LICENSE.TXT)
    Полноценная коммерческая лицензия.
    $10 для индивидуальных разработчиков, $50 для компаний.

  8. 22 минуты назад, Brovin Yaroslav сказал:

    Костыль: Self.Children[0] - Объект в стиле, использующий стиль может его и не загрузить, но при этом иметь вложенные контролы. Поэтому физически у него еще нет стиля, но один контрол внутри есть. (Подсказка, смотреть ResourceLink)

    Согласен, однако вызывать EsFindStyleResource я собираюсь только в ApplyStyle, после inherited ApplyStyle, и как я понимаю, стиль к этому моменту уже будет загружен...

    Но костыль, да, поэтому с учетом замечания, я переписал процедуру EsFindStyleResource, теперь, как я понимаю все хорошо? :)

    type
      TOpenStyledControl = class(TStyledControl);
    
    function EsFindStyleResource(Self: TStyledControl; StyleName: string): TFmxObject;
    var
      StyleObject: TFmxObject;
    begin
      // если Self.ChildrenCount < 1 то в компоненте не загружен стиль,
      // т.к. известно что главный эллемент стиля ВСЕГДА находиться по нулевому индексу.
      if (TOpenStyledControl(Self).ResourceLink = nil) or (Self.ChildrenCount < 1) then
        Exit(nil);
    
      StyleObject := nil;
    
      Self.Children[0].EnumObjects(
        function (Obj: TFmxObject): TEnumProcResult
        begin
          if Obj.StyleName.ToLower = StyleName.ToLower then
          begin
            Result := TEnumProcResult.Stop;
            StyleObject := Obj;
          end else
            Result := TEnumProcResult.Continue;
        end);
    
      Result := StyleObject;
    end;

     

  9. 57 минут назад, Brovin Yaroslav сказал:

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

    Да производительность стилей, это конечно отдельная тема...

  10. 1 час назад, Brovin Yaroslav сказал:

    Не ищет потому что так и не планировалось. Так как компонент не обязательно используется в стиле.

    Например по второй картинке:

    selection является дочерним к панели. И есть предположение, что FindStyleResource должен найти его. С одной стороны логично.

    С другой стороны такая же картинка может быть на форме. И в этом случае FindStyleResource уже не должен найти selection. По скольку в FindStyleResource нету контекста, в чем мы ищем, поэтому он всегда ищет объект только в стиле для стилевых компонентов.

    Собственно, я предполагал что это так, но насколько плох мой подход по обходу его?

    Я проверял, да - если на мой компонент кинуть кнопку и прописать ей StyleName := 'selection', то при отсутствии в стиле объекта 'selection', мой метод найдет кнопку, что неверно, однако зачем вообще прописывать кнопке на форме StyleName?

     

    Кроме того, я придумал другой метод, который ищет только среди объектов стиля, то есть не обладает недостатком, который я привел выше.

    Требую критики :)

    function EsFindStyleResource(Self: TStyledControl; StyleName: string): TFmxObject;
    var
      StyleObject: TFmxObject;
    begin
      // если Self.ChildrenCount < 1 то в компоненте не загружен стиль,
      // т.к. известно что главный эллемент стиля ВСЕГДА находиться по нулевому индексу.
      if Self.ChildrenCount < 1 then
        Exit(nil);
    
      StyleObject := nil;
    
      Self.Children[0].EnumObjects(
        function (Obj: TFmxObject): TEnumProcResult
        begin
          if Obj.StyleName.ToLower = StyleName.ToLower then
          begin
            Result := TEnumProcResult.Stop;
            StyleObject := Obj;
          end else
            Result := TEnumProcResult.Continue;
        end);
    
      Result := StyleObject;
    end;
    
    procedure TEsImageSelection.ApplyStyle;
    var
      T: TControl;
    begin
      inherited ApplyStyle;
    
      T := EsFindStyleResource(Self, 'selection') as TControl;
    
      if T <> nil then
        ShowMessage('"selection" founded!');
    end;

    Имхо, это не плохой метод, главное чтобы не было дополнительных подводных камней...

  11. ЧАВО:

    Опишу "багофичу" на которую я наткнулся.

    Предположим что вы пишете свой компонент, наследуемый от TStyledControl (или любого другого компонента, который происходит от  TStyledControl), для доступа к элементам стиля обычно используют FindStyleResource('ИмяРесурса') (есть вариант в виде FindStyleResource<Класс>('ИмяРесурса', Переменная)) , например компонент TImageControl получает Image так:

    procedure TImageControl.ApplyStyle;
    begin
      inherited;
      if FindStyleResource<TImage>('image', FImage) then
        UpdateImage;
    end;

    И FindStyleResource работает отлично, пока в дереве стиля искомый объект лежит на НЕ TStyledControl-ах, то есть FindStyleResource будет успешно находить объект, который расположен на TRectangle, но не найдет его же, но на TPanel!

    Пример:

    Код, в процедуре ApplyStyle:

    procedure TEsImageSelection.ApplyStyle;
    var
      T: TControl;
    begin
      inherited ApplyStyle;
      if FindStyleResource<TControl>('selection', T) then
        ShowMessage('"selection" founded!');
    end;

    Что делает данный код? - При нахождении стилевого объекта выдает соответствующее сообщение.

    Рассмотрим стиль:

    zz.png

    Как видите в варианте A, "Selection" лежит на НЕ наследнике TStyledControl. Запустив программу можно убедиться что FindStyleResource<TControl>('selection', T) найдет объект "Selection".

    В варианте B, при запуске можно с удивлением обнаружить что FindStyleResource<TControl>('selection', T) не находит объект "Selection"!

    Почему так?

    Судя по исходникам поиск во вложенных TStyledControl-ах сломан специально, дабы не всплывали еще большие глюки\проблемы.(но я не изучал вопрос очень подробно, во внутренний код работы с загрузкой и поиском стилей - кромешный ад, с наслаиванием истории Fire-Monkey разных лет).

    Как можно обойти проблему?

    Я нашел следующее решение:

    (Однако я совершенно не уверен в отсутствии побочных эффектов, возможно @Brovin Yaroslav сможет прокомментировать его?)

    Данный код находит искомый стилевой объект, в отличии от FindStyleResource.

    procedure TEsImageSelection.ApplyStyle;
    var
      T: TControl;
    begin
      inherited ApplyStyle;
      
      T := nil;
      EnumObjects(
        function (Obj: TFmxObject): TEnumProcResult
        begin
          if Obj.StyleName.ToLower = 'selection' then
          begin
            T := TControl(Obj);
            Result := TEnumProcResult.Stop;
          end else
            Result := TEnumProcResult.Continue;
        end);
    
      if T <> nil then
        ShowMessage('"selection" founded!');
    end;

     

    Процедура-замена FindStyleResource, работает как ожидается:

    type
      TOpenStyledControl = class(TStyledControl);
    
    function EsFindStyleResource(Self: TStyledControl; StyleName: string): TFmxObject;
    var
      StyleObject: TFmxObject;
    begin
      // если Self.ChildrenCount < 1 то в компоненте не загружен стиль,
      // т.к. известно что главный эллемент стиля ВСЕГДА находиться по нулевому индексу.
      if (TOpenStyledControl(Self).ResourceLink = nil) or (Self.ChildrenCount < 1) then
        Exit(nil);
    
      StyleObject := nil;
    
      Self.Children[0].EnumObjects(
        function (Obj: TFmxObject): TEnumProcResult
        begin
          if Obj.StyleName.ToLower = StyleName.ToLower then
          begin
            Result := TEnumProcResult.Stop;
            StyleObject := Obj;
          end else
            Result := TEnumProcResult.Continue;
        end);
    
      Result := StyleObject;
    end;

     

×
×
  • Создать...