← All posts tagged Flex

Constantiner

Вообще, последнее время ненавижу, когда классы, даже в концепции MVC, называют BullShitController, MailController. Ну контроллер, круто. А что конкретно он контролирует? Весь Mail? Не жмет?

С учетом того, что сам по себе MVC даже не паттерн, а просто набор общих соображений с разными вариантами реализации, такие общие названия можно давать всему, что угодно. В любом случае, трудно по названию ожидать от класса чего-то конкретного. Мне, если честно, даже открывать такие классы страшно. Боюсь разочарований.

И, кстати, чем даже стремные фреймворки типа Cairngorm, лучше доморощенных реализаций, так это тем, что в них можно более-менее точно предугадать, чего ждать от класса, названного по шаблону.

Constantiner

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

Constantiner

Чем я люблю MXML, да еще с разметкой, основанной на контейнерах, отличных от Canvas или группах с компоновкой, отличной от базовой, так это тем, что все наглядно. Посмотрел теги и все быстро понял. Поэтому, например, жутко не люблю писателей, которые делают скины во Flex 4 для всего, включая компоновки компонент. Они называют это code behind, а я называю их мудаками :)

Но когда начинается архитектура от астронавтов, то пиши-пропало. Тут, по сути, MXML и не нужен. Ибо роль свою выполняет уже весьма слабо.

Constantiner

К предыдущему #1114763 и #1114706. Только три вида операций могут сливаться. Эту инфу можно найти в коде метода merge класса flashx.textLayout.operations.CompositeOperation. Операции эти суть InsertTextOperation, SplitParagraphOperation и DeleteTextOperation. Может, кому пригодится.

Constantiner

В классе flashx.textLayout.operations.FlowOperation есть метод tlf_internal function merge(operation:FlowOperation):FlowOperation коммент к которому гласит:

Combine this operation with another operation if the result can
be represented as a single operation. In general, operations cannot be
merged. But sequential inserts or deletes may be mergeable.

Ну не суки ли написать такой важный коммент там, где можно прочитать лишь если залезть в код? :(

Constantiner

Опять сграный TLF. Ну вот хрена он кэширует операции изменения в текстовом поле? Если вставлять в текст одну и ту же букву, то он будет каждый раз присылать событие, в котором InsertTextOperation будет один и тот же объект, а вот вставляемый текст разный. Ну вот нафига?

Constantiner

В продолжение #1106352 о пиздатости дизайна TLF и Flex.

Ну вот я решил отнаследовать RichEditableTextContainerManager и, конечно, отнаследовать RichEditableText, в котором этот отнаследованный менеджер будет использоваться. Все, вроде, здорово. Мне даже не надо отнаследоваться от TextArea так как у нас есть механизм скинов, в котором мы можем легко и просто подменить наш RichEditableText на RichEditableTextExt. Конечно, тут тоже не все пучком. Ибо скин приходится полностью копировать, но это уже баян и не смешно.

Но метод создания RichEditableTextContainerManager в RichEditableText, который мне надо переопределить, состоит из одной строчки:

return new RichEditableTextContainerManager(this, staticConfiguration)
При этом staticConfiguration — это приватное статическое поле. Понятно, что код его создания придется копировать тоже. Ну вот ничего у Адобов нельзя сделать быстро просто и красиво. А ведь когда-то так не было. Как-то проще все было…

Constantiner

Ненавижу Адобов за кривизну и непродуманность года :( У них в TextArea, а если точнее, то в RichEditableText, есть поле textContainerManager типа TextContainerManager. Он якобы является фасадом для ContainerController, решая якобы задачи производительности. Вариант убогий, но приемлемый. Убогость варианта в том, что к этому полю доступ идет через контейнер (в данном случае RichEditableText), который обычно не отнаследован в других контролах, а идет композитом. Соответственно, красиво и универсально передавать некому классу TextFlow уже не получится. Надо передавать контейнер и иметь все замечательные проверки его типа и кастинги.

Тем не менее, этот TextContainerManager решает вопросы перехвата событий мыши в виде событий, когда ContainerController предполагает наследование и переопределение соответствующих обработчиков. Решение кривоватое (обращение только через контейнер), но решение. А теперь такой момент, что контекстное меню они решили из этого класса исключить. Ничего страшного. Сделаем свой ContainerController, в котором переопределим menuSelectHandler. Но в итоге оказывается, что старый ContainerController в TextFlow уже не заменить столь безболезненно, особенно ничего не зная о нашем контейнере и оперируя лишь TextFlow (как нам этого бы и хотелось).

Дело в том: что этот TextContainerManager имеет внутренний класс, отнаследованный от ContainerController, на который жестко, а не по родителям или интерфейсу завязан. То есть распутать их нельзя. NPE обеспечено. Они ссылаются друг на друга и ввиду того, что TMContainerController — класс внутренний, он не наследуется и не подменяется.

В итоге сейчас пойду наследовать TextContainerManager, что все равно предполагает, что придется общаться с контейнером.

Ух, Адобы, кривые вы уроды! И все это на фоне чрезмерной усложненности TLF, который почему-то должен быть MVC. Хотя никто не может в точности сказать, где там M, где V, а где C. Ибо роли нечетки размазаны тонким слоем по хлебу :(

Я высказался :)

Constantiner

Вот строчка из кода TLF (клас FlowLeafElement):
tlf_internal override function getEventMirror():EventDispatcher
Вроде, ничего страшного. А теперь ASDoc к этому методу:
Gets the EventDispatcher associated with this FlowElement. Use the functions
of EventDispatcher such as setEventHandler() and removeEventHandler()
to capture events that happen over this FlowLeafElement object. The
event handler that you specify will be called after this FlowElement object does
the processing it needs to do.


Ну вы поняли? Человек, писавший этот код, считает, что у EventDispatcher есть методы setEventHandler и removeEventHandler. И эти люди запрещают мне ковыряться в носу!

Constantiner

InlineGraphicElement is final. TLF — реальное говно. Реальное. У него столько лишних возможностей, но чтобы его расширить для довольно очевидных случаев (типа адекватного поведения курсора и интерактива для встроенной в текст графики) надо тупо дублировать код и упираться в private, final-классы и прочее говноедство. Уйду я от тебя, Adobe. Все грожусь, но рано или поздно уйду. Еще несколько лет назад можно было нормально разрабатывать. Но теперь произведено столько ужасного нового говнокода, что я не закрываю Google :( А я хочу просто воплощать идеи и требования. А не говноедствовать.