OberonCore
https://forum.oberoncore.ru/

Изменение размеров обёрнутого TextViews.View
https://forum.oberoncore.ru/viewtopic.php?f=24&t=1001
Страница 1 из 1

Автор:  Иван Кузьмицкий [ Понедельник, 26 Май, 2008 13:11 ]
Заголовок сообщения:  Изменение размеров обёрнутого TextViews.View

Пришла мысль, что текстовый документ прекрасно подходит для визуального редактирования полос (bands) отчёта. В качестве полос выступают формы. Нужно теперь спрятать от пользователя "излишнюю" функциональность текста.

Ещё понадобилось управлять размерами обёрнутого текста

Обернуть отображение текста в свою View, потом обрабатывать надлежащим образом сообщения... Обернуть текст просто, а вот изменить размеры обёрнутого отображения - никак :(

Вот исходник:
Код:
   IMPORT
      Containers, Controllers, Dialog, Properties, Ports, Models, Stores, StdLog, TextViews, Views;

   CONST   mm = Ports.mm;

   TYPE
      View = POINTER TO RECORD (Views.View)
         inner: Views.View;
      END;

   PROCEDURE (v: View) ThisModel (): Models.Model;
   BEGIN
      RETURN v.inner.ThisModel()
   END ThisModel;

   PROCEDURE (v: View) Restore (f: Views.Frame; l, t, r, b: INTEGER);
      VAR msg: Properties.SetMsg; prop: Properties.SizeProp;
   BEGIN
      v.inner.context.SetSize(20*mm, 20*mm); (*попытка изменения размера №2 *)

      Views.InstallFrame(f, v.inner, 10*mm, 10*mm, 0, TRUE);
   END Restore;

   PROCEDURE (v: View) HandleCtrlMsg (f: Views.Frame; VAR msg: Controllers.Message; VAR focus: Views.View);
   BEGIN
      focus := v.inner
   END HandleCtrlMsg;
   
   PROCEDURE Wrap*;
      VAR poll: Controllers.PollOpsMsg; w: View; replace: Controllers.ReplaceViewMsg; msg: Properties.SetMsg; prop: Properties.SizeProp;
   BEGIN
      Controllers.PollOps(poll);
      IF (poll.singleton # NIL) & ~(poll.singleton IS View) THEN
         (*попытка изменения размера №1, перед подменой*)
         NEW(prop);
         prop.width := 20*mm; prop.height := 20*mm;
         prop.valid := {Properties.width, Properties.height};
         prop.known := prop.valid;
         msg.prop := prop;
         Views.HandlePropMsg(poll.singleton, msg);

         NEW(w); w.inner := poll.singleton; Stores.Join(w, w.inner);
         replace.old := poll.singleton; replace.new := w;
         Controllers.Forward(replace);

      ELSE Dialog.Beep
      END
   END Wrap;


Вопрос, собственно, такой - правильно ли посылать сообщение об изменении размеров тексту?

Автор:  Александр Ильин [ Понедельник, 26 Май, 2008 14:51 ]
Заголовок сообщения:  Re: Изменение размеров обёрнутого TextViews.View

Изнутри Restore менять размеры нельзя. Я делал "отложенно" с помощью Services.Action:
Код:
   TYPE
      (** SetSizeAction используется для отложенной установки размера view. **)
      SetSizeAction = POINTER TO RECORD (Services.Action)
         view: View;
         width, height: INTEGER
      END;

   (* SetSizeAction *)

   PROCEDURE (a: SetSizeAction) Do;
      VAR m: Models.Model;
   BEGIN
      m := a.view.context.ThisModel();
      Models.BeginModification(Models.notRecorded, m);
      a.view.context.SetSize(a.width, a.height);
      Models.EndModification(Models.notRecorded, m)
   END Do;

   PROCEDURE SetSizeLater (v: View; width, height: INTEGER);
      VAR action: SetSizeAction;
   BEGIN
      NEW(action);
      action.view := v;
      action.width := width;
      action.height := height;
      Services.DoLater(action, Services.now);
   END SetSizeLater;

Примерно так. Для установки размеров отображений следует использовать процедуру SetSizeLater. Код немного подправил прямо в браузере перед отправкой, так что мог что-то проглядеть. Models.notRecorded - недокументированная константа = 3. Можно Models.BeginModification/EndModification убрать, но тогда при каждом изменении размера документ будет получать статус "изменённый" и спрашивать о сохранении при закрытии окна. Мне это было крайне нежелательно, поскольку объекты всегда имели автоматический размер.

Автор:  Info21 [ Понедельник, 26 Май, 2008 19:22 ]
Заголовок сообщения:  Re: Изменение размеров обёрнутого TextViews.View

Как-то странно... размеры обычно по-другому меняются...


6.3 Preference messages

You might have noticed that the size of a newly opened view is rather arbitrary. However, before opening the view, the framework sends the view a message with a proposed size. The view may adapt this proposal to its own needs. To do that, the message of type Properties.SizePref must be answered in the view's HandlePropMsg procedure. Before a view is displayed for the first time, the proposed size for the width and the height of the view is Views.undefined. The following version of our sample view draws a rectangle with a width of 2 cm and a height of 1 cm. Changes compared to the previous version are written in bold face.

Автор:  Александр Ильин [ Понедельник, 26 Май, 2008 19:29 ]
Заголовок сообщения:  Re: Изменение размеров обёрнутого TextViews.View

Это только для "newly opened view... Before a view is displayed for the first time".

Автор:  Иван Кузьмицкий [ Понедельник, 26 Май, 2008 19:46 ]
Заголовок сообщения:  Re: Изменение размеров обёрнутого TextViews.View

Я всё равно чего-то недопонимаю, а чего - понять не могу (почти по Жванецкому).

Пробегусь по порядку.

Есть текстовый документ. Выделяем корневое отображение и запускаем процедуру обёртывания. При обёртывании создаём отображение-обёртку и посылаем контейнеру сообщение Controllers.ReplaceViewMsg для того, чтобы он подменил старое отображение на новое.

После подмены новая вьюшка отображается вместо старой, на том же месте и с теми же размерами. Очевидно, что задействуется контекст обёртываемой вьюшки. Чтобы обёрнутая вьюшка отобразилась, нужно в процедуре Restore инсталлировать для неё новый кадр, с помощью InstallFrame.

Я пробовал в InstallFrame задать смещение вьюшки. Получается так, что обёрнутый текст отображается со смещением, но ширина его остаётся старой, и буквы справа исчезают на величину смещения.

Может, и нельзя изменить размер обёрнутой вьюшки, ведь у них, похоже, контекст с обёрткой одинаковый?

Автор:  Иван Кузьмицкий [ Понедельник, 26 Май, 2008 20:06 ]
Заголовок сообщения:  Re: Изменение размеров обёрнутого TextViews.View

Александр Ильин писал(а):
Изнутри Restore менять размеры нельзя. Я делал "отложенно" с помощью Services.Action


Не в этой ли

viewtopic.php?f=24&t=345&p=3373&hilit=InstallFrame#p3373

ветке обсуждалось отложенное изменение размеров?

Автор:  Иван Кузьмицкий [ Понедельник, 26 Май, 2008 21:21 ]
Заголовок сообщения:  Re: Изменение размеров обёрнутого TextViews.View

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

Автор:  Евгений Темиргалеев [ Вторник, 27 Май, 2008 08:53 ]
Заголовок сообщения:  Re: Изменение размеров обёрнутого TextViews.View

Иван Кузьмицкий писал(а):
Может, и нельзя изменить размер обёрнутой вьюшки, ведь у них, похоже, контекст с обёрткой одинаковый?
А Вы пример-то смотрели ObxWrappers? Там как раз и написано, что они используют для обёртки контекст обёртываемого отображения, т.к. их размеры обёртки будут такие-же как у обёртываемого.

Т.е., как я понимаю, если Вам нужен другой размер - нужно делать свой контекст наподобие ObxTwins (статич. контейнер с одним отображением, работающий наподобие обёртки).

Автор:  Иван Кузьмицкий [ Вторник, 27 Май, 2008 09:40 ]
Заголовок сообщения:  Re: Изменение размеров обёрнутого TextViews.View

Да, конечно, я по ObxWrap и делал.

Я только не понимаю, в каком месте у обёртки появляется тот же контекст, что и у обёртываемой вьюшки. Потому что, судя по исходнику Containers.ReplaceView, подмена происходит только если контексты одинаковые. Более того, там даже ASSERT взведён, на условие new.context = old.context.

Остаётся только Stores.Join, но про отображения там ни слова. Пока загадка.

Цитата:
нужно делать свой контекст наподобие ObxTwins


Видимо, так даже правильнее, чем изгаляться над текстовым отображением :)

Автор:  Евгений Темиргалеев [ Воскресенье, 11 Март, 2012 22:55 ]
Заголовок сообщения:  Re: Изменение размеров обёрнутого TextViews.View

Александр Ильин писал(а):
Изнутри Restore менять размеры нельзя. Я делал "отложенно" с помощью Services.Action:

... Models.notRecorded - недокументированная константа = 3. Можно Models.BeginModification/EndModification убрать, но тогда при каждом изменении размера документ будет получать статус "изменённый" и спрашивать о сохранении при закрытии окна. Мне это было крайне нежелательно, поскольку объекты всегда имели автоматический размер.
1) Изнутри Restore менять можно, если каким-либо образом гарантируется "отсутствие" рекурсии.
2) notRecorded с т.з. пользователя = сочетание clean + invisble
Код:
IF vv.context # NIL THEN
   Views.BeginModification(Views.invisible, vv);
   Views.BeginModification(Views.clean, vv);
   vv.context.SetSize(Views.undefined, Views.undefined);
   Views.EndModification(Views.clean, vv);
   Views.EndModification(Views.invisible, vv);
   Views.Update(vv, Views.keepFrames)
END
(до clean+invisible только щас допетрил, до этого использовал только clean --- забивало очередь undo/redo)

Автор:  Александр Ильин [ Воскресенье, 11 Март, 2012 23:24 ]
Заголовок сообщения:  Re: Изменение размеров обёрнутого TextViews.View

Евгений Темиргалеев писал(а):
2) notRecorded с т.з. пользователя = сочетание clean + invisble
...
(до clean+invisible только щас допетрил, до этого использовал только clean --- забивало очередь undo/redo)
Неа. "Views.invisible" операции точно так же забивают очередь Undo/Redo, просто они "приклеиваются" к предыдущей операции и не видны как отдельные. Если вы нажмёте Ctrl+Z, то сначала отменятся все последние "невидимые" операции, потом одна "видимая". В документации к Views.invisible так и написано: "When executing an Undo operation, first all invisible operations are undone and afterwards the visible operations."

С точки зрения пользователя будет так: он отменяет ввод текста, но попутно вдруг меняются размеры у встроенных в тот же текст вьюшек. Проходили, знаем. Нужен notRecorded.
Да он и есть, и в самом фреймворке используется, просто не опубликован в интерфейсе. См. Documents.StdDocument.DocCopyOf.

PS: Невидимые операции "забивают" очередь Undo/Redo в том смысле, что без толку накапливаются в памяти. Хотя пользователю и не видны, да.

Автор:  Евгений Темиргалеев [ Понедельник, 12 Март, 2012 10:36 ]
Заголовок сообщения:  Re: Изменение размеров обёрнутого TextViews.View

Спасибо за разъяснения. :) "Повторение, мать учения".
Александр Ильин писал(а):
С точки зрения пользователя будет так: он отменяет ввод текста, но попутно вдруг меняются размеры у встроенных в тот же текст вьюшек. Проходили, знаем. Нужен notRecorded.
...
PS: Невидимые операции "забивают" очередь Undo/Redo в том смысле, что без толку накапливаются в памяти. Хотя пользователю и не видны, да.
Полной эквивалентности нет, Вы правы. Поспешные выводы, "головокружение от успехов". Речь же шла ровно про это.

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

С точки зрения порчи вида отменой --- для конечного пользователя и конкретного приложения, это, пожалуй, может быть причиной... Но насчёт допустимости notRecored для всеобщего использования --- есть подозрения, что интегрально это будет конечному пользователю больше во вред.

P.S. Нельзя ли реализовать специальную операцию по изменению размера так, что на Undo/Redo она не будет "портить вида"? --- вопрос, как сочетать её с последовательностью других операций...

Автор:  Александр Ильин [ Понедельник, 12 Март, 2012 11:54 ]
Заголовок сообщения:  Re: Изменение размеров обёрнутого TextViews.View

Евгений Темиргалеев писал(а):
P.S. Нельзя ли реализовать специальную операцию по изменению размера так, что на Undo/Redo она не будет "портить вида"? Вопрос, как сочетать её с последовательностью других операций...
У меня была конкретная задача: сделать авторазмер вьюшек при фоновом поступлении данных так, чтобы пользователь мог работать с документом как обычно. Прямой поддержки такого поведения нет. Идеологически устроено так, что контейнер полностью распоряжается своим содержимым. Если он скажет, что встроенный объект должен отобразиться в квадратике 3 на 3 пикселя, тот не смеет ослушаться.
Если подумать о минимальных шагах, которые могли бы этому поспособствовать, то я вижу 4 варианта:
1 - добавить поддержку спецсвойства "авторазмер" в заинтересованные контейнеры (требуется доработка подсистемы Text). При этом изменения размера встроенного объекта будут игнорироваться контейнером автоматически, т.е. не будут попадать в очередь undo/redo;
2 - иметь возможность менять размер напрямую, мимо цепи undo/redo. Полностью выносить изменение размера за пределы механизма отправки сообщений нельзя, так как контейнер должен иметь контроль над своим содержимым (может быть, он должен автоматически что-то выравнивать при этом в соответствии с линейкой), но предусмотреть какой-то особый "не сохраняемый" способ изменить размер можно;
3 - иметь возможность пропускать некоторые действия мимо цепи undo/redo - это и есть notRecorded;
4 - завести дополнительную шину для таких особых сообщений. Это будут операции, которые работают как прочие операции, но не сохраняются в очередь undo/redo.

Другими словами, есть общий механизм отправки сообщений по шине. Во фреймворке на этот механизм дополнительно навесили функцию undo/redo и открыли пользователю доступ гулять в прошлое. Понятно, что не все сообщения, которые потенциально можно передать по шине, возможно отменить, поэтому придумали атрибут notUndoable. Но точно так же ведь бывают и сообщения, которые вообще не имеет смысла учитывать в undo/redo. Они по всем параметрам должны быть именно в шине (контейнер должен на них реагировать, обновляя отображение), но отменять их нет смысла. Не невозможно (notUndoable), а бессмысленно: была их тысяча или не было ни одного - абсолютно не важно, потому что документ не является хранилищем данного содержимого, а представляет из себя лишь "окно", через которое нечто видно (протекающие в сети внешние процессы).

В этом и кроется системное противоречие: мы используем текстовую модель для создания безмодельного отображения. Нам важно сохранить текстовую модель как конфигурацию "окна", через которое мы нечто видим, но само содержимое видимого мы должны пропустить мимо очереди undo/redo этой модели окна.

PS: Хочу быть системным архитектором.

Автор:  Евгений Темиргалеев [ Суббота, 17 Март, 2012 20:16 ]
Заголовок сообщения:  Re: Изменение размеров обёрнутого TextViews.View

Для отчёту: при определённом стечении обстоятельств (у меня: прокрутка к ещё не видимой вьюшке в открытом документе) происходит конфликт при отправке сообщений по шине (при изменении размера из Restore). Убрал в экшен. Спасибо, Александр.

Автор:  Иван Кузьмицкий [ Суббота, 17 Март, 2012 21:38 ]
Заголовок сообщения:  Re: Изменение размеров обёрнутого TextViews.View

Евгений Темиргалеев писал(а):
Для отчёту: при определённом стечении обстоятельств (у меня: прокрутка к ещё не видимой вьюшке в открытом документе) происходит конфликт при отправке сообщений по шине (при изменении размера из Restore). Убрал в экшен. Спасибо, Александр.


Есть такая особенность дерева фреймов - оно строится только по видимым отображениям.

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/