OberonCore https://forum.oberoncore.ru/ |
|
Элементы меню для документа в обёртке https://forum.oberoncore.ru/viewtopic.php?f=23&t=2126 |
Страница 1 из 1 |
Автор: | GameHunter [ Пятница, 27 Ноябрь, 2009 01:00 ] |
Заголовок сообщения: | Элементы меню для документа в обёртке |
Уважаемые специалисты, Я изучаю ББ, пытаюсь написать обёртку для изменения фона документов. Проблема такая: когда вьюшка документа обёрнута, некоторые пункты меню, активные без обёртки, не активны. Например, Dev -> Edit mode, Dev -> Layout mode, ... В чём дело? код: Код: MODULE MyWrapper;
IMPORT Dialog, Stores, Models, Views, Controllers, Properties, Ports; CONST minVersion = 0; maxVersion = 0; TYPE View = POINTER TO RECORD (Views.View) inner: Views.View; BackgroundColor:Ports.Color; END; FindMsg = RECORD (Controllers.Message) v:Views.View; END; PROCEDURE (v: View) Internalize (VAR rd: Stores.Reader); VAR version: INTEGER; BEGIN rd.ReadVersion(minVersion, maxVersion, version); IF ~rd.cancelled THEN Views.ReadView(rd, v.inner); (* generate Views.Alien if necessary *) rd.ReadInt(v.BackgroundColor); END END Internalize; PROCEDURE (v: View) Externalize (VAR wr: Stores.Writer); BEGIN wr.WriteVersion(maxVersion); Views.WriteView(wr, v.inner); (* handle Views.Alien if necessary *) wr.WriteInt(v.BackgroundColor); END Externalize; PROCEDURE (v: View) CopyFromModelView (source: Views.View; model: Models.Model); BEGIN WITH source: View DO v.BackgroundColor:=source.BackgroundColor; IF model = NIL THEN v.inner := Views.CopyOf(source.inner, Views.deep) ELSE v.inner := Views.CopyWithNewModel(source.inner, model) END END END CopyFromModelView; PROCEDURE (v: View) ThisModel (): Models.Model; BEGIN RETURN v.inner.ThisModel() END ThisModel; PROCEDURE (v: View) InitContext (context: Models.Context); BEGIN v.InitContext^(context); v.inner.InitContext(context) (* wrapper and wrapped view share the same context *) END InitContext; PROCEDURE (v: View) Neutralize; BEGIN v.inner.Neutralize END Neutralize; PROCEDURE (v: View) Restore (f: Views.Frame; l, t, r, b: INTEGER); BEGIN Views.InstallFrame(f, v.inner, 0, 0, 0, TRUE); END Restore; PROCEDURE (v: View) HandleCtrlMsg (f: Views.Frame; VAR msg: Controllers.Message; VAR focus: Views.View); BEGIN WITH msg:FindMsg DO IF v.inner=msg.v THEN msg.v:=v ELSE focus:=v.inner END ELSE focus := v.inner END; END HandleCtrlMsg; PROCEDURE (v: View) HandleViewMsg (f:Views.Frame; VAR msg:Views.Message); BEGIN WITH msg: Views.ScrollClassMsg DO msg.allowBitmapScrolling := TRUE ELSE END END HandleViewMsg; PROCEDURE (v: View) HandlePropMsg (VAR msg: Properties.Message); BEGIN Views.HandlePropMsg(v.inner, msg) END HandlePropMsg; PROCEDURE (v: View) GetBackground (VAR color: Ports.Color); BEGIN color:=v.BackgroundColor END GetBackground; PROCEDURE WrapView(v:Views.View): View; VAR w:View; replace: Controllers.ReplaceViewMsg; BEGIN ASSERT(v#NIL); ASSERT(~(v IS View)); NEW(w); w.inner := v; Stores.Join(w, w.inner); replace.old := v; replace.new := w; Controllers.Forward(replace); RETURN w END WrapView; PROCEDURE UnwrapView(v:View); VAR replace: Controllers.ReplaceViewMsg; BEGIN ASSERT(v#NIL); replace.old := v; replace.new := v.inner; Controllers.Forward(replace); END UnwrapView; PROCEDURE FindWrapper (inner:Views.View): View; VAR find:FindMsg; BEGIN find.v:=inner; Controllers.Forward(find); IF find.v=inner THEN RETURN NIL ELSE RETURN find.v(View) END; END FindWrapper; PROCEDURE GetCurrentView (): Views.View; BEGIN RETURN Controllers.FocusView() END GetCurrentView; PROCEDURE SetBackgroundColor * (); VAR set:BOOLEAN; color:Ports.Color; v:View; FocusView:Views.View; script: Stores.Operation; BEGIN FocusView:=GetCurrentView(); IF FocusView=NIL THEN RETURN END; v:=FindWrapper(FocusView); IF v#NIL THEN color:=v.BackgroundColor ELSE color:=Ports.defaultColor END; Dialog.GetColor(color,color,set); IF set THEN IF v=NIL THEN v:=WrapView(FocusView); END; v.BackgroundColor:=color; Views.Update(v,FALSE) END; END SetBackgroundColor; PROCEDURE SetTransparentBackground * (); VAR FocusView:Views.View; v:View; BEGIN FocusView:=GetCurrentView(); v:=FindWrapper(FocusView); IF v#NIL THEN UnwrapView(v); END; END SetTransparentBackground; END MyWrapper. |
Автор: | Info21 [ Пятница, 27 Ноябрь, 2009 01:14 ] |
Заголовок сообщения: | Re: Элементы меню для документа в обёртке |
В меню указывается тип объекта, для которого меню. Посмотрите менюшные документы, там всё очевидно. |
Автор: | Илья Ермаков [ Пятница, 27 Ноябрь, 2009 01:18 ] |
Заголовок сообщения: | Re: Элементы меню для документа в обёртке |
Когда пишете обёртку, надо быть внимательным с обработкой фокуса. Если всё нормально, то среда будет считать, что в фокусе именно внутреннее отображение - и меню будет вести себя, как положено. |
Автор: | Евгений Темиргалеев [ Пятница, 27 Ноябрь, 2009 10:06 ] |
Заголовок сообщения: | Re: Элементы меню для документа в обёртке |
В Cpc есть пример: http://www.zinnamturm.eu/downloadsOS.ht ... ckgrounder Цитата: Set Background Colour in Views.
StdBackgrounder is a simple example of implementing a 'Wrapper'. It is used to add a background colour to arbitrary Views embedded into a Text Document. |
Автор: | GameHunter [ Суббота, 28 Ноябрь, 2009 00:31 ] |
Заголовок сообщения: | Re: Элементы меню для документа в обёртке |
В StdBackgrounder'е та же проблема: при фокусе обёрнутого документа некоторые пункты меню гаснут. Вроде, я делаю всё как в примере - все необходимые сообщения передаю обёрнутой вюшке. Что же ещё надо сделать, чтобы система приняла обёртку за обёрнутую вюшку? |
Автор: | Евгений Темиргалеев [ Суббота, 28 Ноябрь, 2009 01:03 ] |
Заголовок сообщения: | Re: Элементы меню для документа в обёртке |
от стандартного примера ObxWrappers отличие есть : Код: (* HandleModelMsg: framework performs message propagation *) (* HandleViewMsg: framework performs message propagation *) может в этом дело |
Автор: | Info21 [ Суббота, 28 Ноябрь, 2009 10:42 ] |
Заголовок сообщения: | Re: Элементы меню для документа в обёртке |
Евгений Темиргалеев писал(а): от стандартного примера ObxWrappers отличие есть : Кстати, механизм этих самых message propagations в документации ББ описан так, что может вызвать заворот мозгов. Код: (* HandleModelMsg: framework performs message propagation *) (* HandleViewMsg: framework performs message propagation *) может в этом дело У них там особый жаргон, меня ставили в тупик модальные конструкции, которые в принципе можно трактовать прямо противоположным образом. Хотя надо признать, что изложение довольно систематическое, только предварительного учебничка по жаргону нет ![]() В общем, некоторого разжевывания этих механизмов пока не хватает. |
Автор: | Иван Горячев [ Суббота, 28 Ноябрь, 2009 11:33 ] |
Заголовок сообщения: | Re: Элементы меню для документа в обёртке |
Активность меню определяется через Controllers.PollOpsMsg. Причём в поле msg.type нужно возвращать имя абстрактного базового класса (обёртываемого объекта, надо полагать) |
Автор: | GameHunter [ Вторник, 01 Декабрь, 2009 00:04 ] |
Заголовок сообщения: | Re: Элементы меню для документа в обёртке |
Цитата: Активность меню определяется через Controllers.PollOpsMsg. Причём в поле msg.type нужно возвращать имя абстрактного базового класса (обёртываемого объекта, надо полагать) Не помогает. Обнаружил, что все меню корректно работают, если вьюшка вложенная в документ. Вероятно, обёртка все сообщения отсылает правильно, но что-то не стыкуется на верхнем уровне документа... |
Автор: | Иван Горячев [ Вторник, 01 Декабрь, 2009 02:47 ] |
Заголовок сообщения: | Re: Элементы меню для документа в обёртке |
GameHunter писал(а): Не помогает. Прошу прощения, послал Вас немножко не туда ![]() Вся работа с меню происходит в модуле HostMenus. Там нас интересуют процедуры: PrepareMenu, UpdateMenu и UpdateType и переменная type. 1. Связка UpdateMenu/UpdateType/type отвечает за динамическое формирование строки меню в зависимости от выбранной вьюшки (т.е. тех меню, у которых в файле Menus.odc указан ViewType). Общая схема такова: UpdateType с помощью Controllers.PollOps посылает сообщение Controllers.PollOpsMsg, и по результату заполняет type, а затем UpdateMenu ориентируясь на полученный тип пересоздаёт что надо. 2. PrepareMenu отвечает за активность пунктов, галочки и прочую атрибутику отдельных пунктов. Делается это через StdDialog.CheckFilter, который вызывает guard прописанный в файле Menus.odc. Т.е. для каждого конкретного случая нужно смотреть как работает конкретный guard. Вы указали неработающие пункты - Dev->Set...Mode. Guard для них - StdCmds.Set...ModeGuard, а интересует нас - GetMode. Он использует Views.HandlePropMsg с сообщением Containers.GetOpts. Но! Посылается это сообщение только если у вас отображение-singleton или контейнер (т.е. расширение Containers.View). А вот разобраться, как именно оно находит этот singleton меня не хватило - там пяток модулей с хуками и фабриками друг на друга, и проследить цепочку вызовов - ![]() |
Автор: | Иван Горячев [ Вторник, 01 Декабрь, 2009 10:54 ] |
Заголовок сообщения: | Re: Элементы меню для документа в обёртке |
Кстати, ещё один момент: приведённый модуль неправильно ищет view для обёртывания - если я в документ вставлю коммандер, выделю его (F6) - и попытаюсь обернуть - обернётся документ, а не коммандер. Потому как должно быть: Код: PROCEDURE GetCurrentView (): Views.View;
VAR c : Containers.Controller; BEGIN c := Containers.Focus(); IF (c # NIL) & (c.Singleton() # NIL) THEN (*возвращаем именно выбранный view *) RETURN c.Singleton() ELSE (* можно вернуть и текущий контейнер. Но можно и не возвращать, дабы не плодить поведений по умолчанию *) RETURN Controllers.FocusView() END END GetCurrentView; |
Автор: | GameHunter [ Среда, 02 Декабрь, 2009 12:22 ] |
Заголовок сообщения: | Re: Элементы меню для документа в обёртке |
Цитата: Но думаю проблема в том, что Ваша обёртка - Views.View, а не Containers.View. Вы правы, охрана этих пунктов меню рассчитана на Containers.View. Получается, что, вообще говоря, универсальную "прозрачную" обётрку создать не возможно, т.к. для этого она должна иметь тип обёртываемой вьюшки ![]() |
Автор: | Иван Горячев [ Среда, 02 Декабрь, 2009 14:21 ] |
Заголовок сообщения: | Re: Элементы меню для документа в обёртке |
Почему? Берём в качестве базы Containers.View - и вперёд. Поскольку в контейнерах по определению может лежать всё что угодно, должно получиться. Только возни больше. Но возможно что для каджого класса отображений (т.е. текстов, форм, etc.) придётся создавать свои обёртки. Грабли тут на самом деле в другом - обёрнутые документы проблематично передавать - у получателя должны быть соотвествующие модули. |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |