OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Четверг, 28 Март, 2024 11:13

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 15 ] 
Автор Сообщение
СообщениеДобавлено: Понедельник, 26 Май, 2008 13:11 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2935
Откуда: г. Ярославль
Пришла мысль, что текстовый документ прекрасно подходит для визуального редактирования полос (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 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2449
Откуда: Россия, Томск
Изнутри 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 убрать, но тогда при каждом изменении размера документ будет получать статус "изменённый" и спрашивать о сохранении при закрытии окна. Мне это было крайне нежелательно, поскольку объекты всегда имели автоматический размер.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 26 Май, 2008 19:22 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
Как-то странно... размеры обычно по-другому меняются...


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 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2449
Откуда: Россия, Томск
Это только для "newly opened view... Before a view is displayed for the first time".


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 26 Май, 2008 19:46 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2935
Откуда: г. Ярославль
Я всё равно чего-то недопонимаю, а чего - понять не могу (почти по Жванецкому).

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

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

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

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

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 26 Май, 2008 20:06 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2935
Откуда: г. Ярославль
Александр Ильин писал(а):
Изнутри Restore менять размеры нельзя. Я делал "отложенно" с помощью Services.Action


Не в этой ли

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

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 26 Май, 2008 21:21 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2935
Откуда: г. Ярославль
Начинаю склоняться к тому, чтобы редактор полос делать не на основе текстового документа, а на основе формы, как контейнера для произвольно расположенных элементов управления.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 27 Май, 2008 08:53 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4625
Откуда: Россия, Орёл
Иван Кузьмицкий писал(а):
Может, и нельзя изменить размер обёрнутой вьюшки, ведь у них, похоже, контекст с обёрткой одинаковый?
А Вы пример-то смотрели ObxWrappers? Там как раз и написано, что они используют для обёртки контекст обёртываемого отображения, т.к. их размеры обёртки будут такие-же как у обёртываемого.

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 27 Май, 2008 09:40 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2935
Откуда: г. Ярославль
Да, конечно, я по ObxWrap и делал.

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

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

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


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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 11 Март, 2012 22:55 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4625
Откуда: Россия, Орёл
Александр Ильин писал(а):
Изнутри 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 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2449
Откуда: Россия, Томск
Евгений Темиргалеев писал(а):
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 
Модератор
Аватара пользователя

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

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

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

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 12 Март, 2012 11:54 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2449
Откуда: Россия, Томск
Евгений Темиргалеев писал(а):
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 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4625
Откуда: Россия, Орёл
Для отчёту: при определённом стечении обстоятельств (у меня: прокрутка к ещё не видимой вьюшке в открытом документе) происходит конфликт при отправке сообщений по шине (при изменении размера из Restore). Убрал в экшен. Спасибо, Александр.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 17 Март, 2012 21:38 

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


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


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 15 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB