OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Пятница, 26 Апрель, 2024 08:45

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




Начать новую тему Ответить на тему  [ Сообщений: 3 ] 
Автор Сообщение
СообщениеДобавлено: Воскресенье, 06 Июль, 2008 17:03 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
По просьбам трудящихся (viewtopic.php?p=16854#p16854).

Принцип использования тот же, что у Tools->Add Scroller.
Выделяем монолитно (singleton) вьюшку, для которой нужна поддержка невидимости. Даём команду AbfTools.AddInvisibiler.

Включение невидимости ведётся через обычный контроловский Guard, свойством disabled.

Выбираем Properties - открывается стандартное окно настройки контрола.
Далее два случая:
1) если обёрнутая вьюшка - не контрол: имеет значение только поле Guard.
2) если обёрнутая вьюшка - контрол: настраиваем все свойства сразу для неё (получается полный синхрон с обёрткой). Т.е. disabled для контрола начинает работать как invisible.

Код:
MODULE AbfTools;

   IMPORT Views, Controls, Stores, Meta, Controllers, Properties, Dialog, Models, Services;

   CONST
      invVersion = 0;

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

   PROCEDURE Init (v: Invisibiler);
      VAR prop: Controls.Prop;
   BEGIN
      Stores.Join(v, v.inner);
      IF v.inner IS Controls.Control THEN
         Controls.OpenLink(v, v.inner(Controls.Control).prop)
      ELSE
         NEW(prop);
         Controls.OpenLink(v, prop)
      END
   END Init;

   PROCEDURE (v: Invisibiler) Externalize2 (VAR wr: Stores.Writer);
   BEGIN
      wr.WriteVersion(invVersion);
      Views.WriteView(wr, v.inner)
   END Externalize2;

   PROCEDURE (v: Invisibiler) Internalize2 (VAR rd: Stores.Reader);
      VAR ver: INTEGER;
   BEGIN
      rd.ReadVersion(invVersion, invVersion, ver);
      IF ~rd.cancelled THEN
         ASSERT(ver = invVersion, 100);
         Views.ReadView(rd, v.inner);
      END
   END Internalize2;

   PROCEDURE (v: Invisibiler) CopyFromSimpleView2 (source: Controls.Control);
   BEGIN
      WITH source: Invisibiler DO
         v.inner := Views.CopyOf(source.inner, Views.deep);
         Init(v)
      END
   END CopyFromSimpleView2;

   PROCEDURE GetVis (v: Invisibiler; OUT x: BOOLEAN);
   BEGIN
      x := ~v.disabled
   END GetVis;

   PROCEDURE (v: Invisibiler) Restore (f: Views.Frame; l, t, r, b: INTEGER);
      VAR vis: BOOLEAN;
            w, h: INTEGER;
   BEGIN
      GetVis(v, vis);
      IF vis THEN
         Views.InstallFrame(f, v.inner, 0, 0, 0, TRUE)
      ELSE
         v.context.GetSize(w, h);
         Views.RemoveFrames(f, 0, 0, w, h)
      END
   END Restore;

   PROCEDURE (v: Invisibiler) HandleCtrlMsg2 (f: Views.Frame; VAR msg: Controllers.Message; VAR focus: Views.View);
      VAR vis: BOOLEAN;
   BEGIN
      GetVis(v, vis);
      IF vis THEN focus := v.inner END
   END HandleCtrlMsg2;

   PROCEDURE (v: Invisibiler) HandlePropMsg2 (VAR msg: Properties.Message);
      VAR prop: Properties.Property;
   BEGIN
      WITH msg: Controls.DefaultsPref DO
         msg.disabled := FALSE   
      ELSE
         Views.HandlePropMsg(v.inner, msg)
      END
   END HandlePropMsg2;

   PROCEDURE (v: Invisibiler) Neutralize;
   BEGIN
      v.inner.Neutralize
   END Neutralize;

   PROCEDURE (v: Invisibiler) InitContext (context: Models.Context);
   BEGIN
      v.InitContext^(context);
      v.inner.InitContext(context)
   END InitContext;

   PROCEDURE AddInvisibiler*;
      VAR poll: Controllers.PollOpsMsg; v: Invisibiler; replace: Controllers.ReplaceViewMsg;
   BEGIN
      Controllers.PollOps(poll);
      IF (poll.singleton # NIL) & ~(poll.singleton IS Invisibiler) THEN
         NEW(v); v.inner := poll.singleton; Init(v);
         replace.old := poll.singleton; replace.new := v;
         Controllers.Forward(replace)
      ELSE Dialog.Beep
      END
   END AddInvisibiler;

   PROCEDURE RemoveInvisibiler*;
      VAR poll: Controllers.PollOpsMsg; replace: Controllers.ReplaceViewMsg;
   BEGIN
      Controllers.PollOps(poll);
      IF (poll.singleton # NIL) & (poll.singleton IS Invisibiler) THEN
         replace.old := poll.singleton;
         replace.new := Views.CopyOf(poll.singleton(Invisibiler).inner, Views.shallow);
         Controllers.Forward(replace)
      ELSE Dialog.Beep
      END
   END RemoveInvisibiler;

   PROCEDURE IsInvisibiler* (v: Views.View): BOOLEAN;
   BEGIN
      RETURN v IS Invisibiler
   END IsInvisibiler;

   PROCEDURE InnerView* (v: Views.View): Views.View;
   BEGIN
      ASSERT(v IS Invisibiler, 20);
      RETURN v(Invisibiler).inner
   END InnerView;

END AbfTools.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 07 Июль, 2008 20:34 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Edward Ivanov писал(а):
Проверил - работает должным образом. :wink:
Действительно, ББ оказался достаточно гибким.
Но есть одна досадная мелочь - при обходе элементов Tab-ом фокус перемещается на невидимый(е) контрол(ы).

При отдаче фокуса контролу ему шлётся какое-то сообщение... (можно половить через Info->Message Spy).
Обёртка-невидимка должна его поймать и принудительно ещё раз сдвинуть фокус...
Времени копать сейчас нет.


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

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
По-моему, достаточно вот так (просто отказываемся брать фокус, когда невидимы):
Код:
   PROCEDURE (v: Invisibiler) HandlePropMsg2 (VAR msg: Properties.Message);
      VAR prop: Properties.Property;
            vis: BOOLEAN;
   BEGIN
      WITH msg: Controls.DefaultsPref DO
         msg.disabled := FALSE   
      | msg: Properties.FocusPref DO
         GetVis(v, vis);
         IF ~vis THEN
            msg.setFocus := FALSE
         ELSE
            Views.HandlePropMsg(v.inner, msg)
         END
      ELSE
         Views.HandlePropMsg(v.inner, msg)
      END
   END HandlePropMsg2;


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

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


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

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


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

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