OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Понедельник, 16 Июнь, 2025 02:37

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




Начать новую тему Ответить на тему  [ Сообщений: 3 ] 
Автор Сообщение
 Заголовок сообщения: Лог на форме
СообщениеДобавлено: Воскресенье, 24 Декабрь, 2006 11:31 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 18:08
Сообщения: 76
Хочу создать текстовой лог, который лежит на форме, открытой как OpenToolDialog.

Код:
MODULE TestControls;

   IMPORT Dialog, Controls, TextModels, Views, Models, Stores, Properties, Controllers;

   TYPE
      Log* = RECORD END;
      CustomLog = POINTER TO RECORD (Controls.Control)
         model: TextModels.Model;
         view: Views.View
      END;
      LogMsg = RECORD (Models.Message)
         string: Dialog.String
      END;
      Context = POINTER TO RECORD (Models.Context)
         w, h: INTEGER;
         view, base: Views.View;
      END;

   VAR log*: Log;

   (** Log **)
   PROCEDURE (VAR l: Log) Add* (IN s: ARRAY OF CHAR), NEW;
      VAR msg: LogMsg;
   BEGIN
      msg.string := s$; Views.Omnicast(msg)
   END Add;
   
   (** Context **)
   
   PROCEDURE (c: Context) GetSize(OUT w, h: INTEGER);
   BEGIN
      w := c.w; h := c.h
   END GetSize;
   
   PROCEDURE (c: Context) SetSize(w, h: INTEGER);
      VAR msg: Properties.SizePref;
   BEGIN
      msg.h := h; msg.w := w;
      msg.fixedH := FALSE; msg.fixedW := FALSE;
      Views.HandlePropMsg(c.view, msg);
      c.w := msg.w; c.h := msg.h
   END SetSize;

   PROCEDURE (c: Context) ThisModel(): Models.Model;
   BEGIN
      RETURN NIL
   END ThisModel;

   PROCEDURE (c: Context) Normalize(): BOOLEAN;
   BEGIN
      RETURN FALSE
   END Normalize;
   
   PROCEDURE NewContext(view: Views.View; base: Views.View): Context;
      VAR context: Context; msg: Properties.SizePref;
   BEGIN
      ASSERT(view # NIL, 20); ASSERT(base # NIL, 21);
      msg.w := Views.undefined; msg.h := Views.undefined;
      msg.fixedW := FALSE; msg.fixedH := FALSE;
      Views.HandlePropMsg(view, msg);
      IF view.context = NIL THEN
         NEW ( context );
         context.w := msg.w;  context.h := msg.h;
         context.view := view; context.base := base;
         view.InitContext( context );
         Stores.Join(view, base)
      END;
      RETURN context
   END NewContext;
      
   (** CustomLog **)
   
   PROCEDURE PaintLog (c: CustomLog; f: Views.Frame);
      VAR w, h: INTEGER;
   BEGIN
      c.context.GetSize(w, h);
      f.DrawRect(0, 0, w, h, f.dot, Ports.black);
      IF c.model # NIL THEN
         IF c.view # NIL THEN
            c.view.context.SetSize(w, h);
            Views.InstallFrame(f, c.view, 0, 0, 0, TRUE);
         END
      END;
   END PaintLog;
   
   PROCEDURE (c: CustomLog) Externalize2 (VAR wr: Stores.Writer);
   BEGIN
      wr.WriteVersion(maxVersion);
      wr.WriteStore(c.model)
   END Externalize2;
   
   PROCEDURE (c: CustomLog) Internalize2 (VAR rd: Stores.Reader);
      VAR version: INTEGER; store: Stores.Store; context: Context;
   BEGIN
      rd.ReadVersion(minVersion, maxVersion, version);
      rd.ReadStore(store);
      WITH store: TextModels.Model DO
         c.model := store;
         c.view := TextViews.dir.New(c.model);
         context := NewContext(c.view, c);
         (*MtScrollers.AddScrollerOn(c.view)*)
      END;

   END Internalize2;
   
   PROCEDURE (c: CustomLog) Restore (f: Views.Frame; l, t, r, b: INTEGER);
   BEGIN
      PaintLog(c, f)
   END Restore;
   
   PROCEDURE (c: CustomLog) HandleCtrlMsg2 (f: Views.Frame; VAR msg: Controllers.Message;
                                                                  VAR focus: Views.View);

   BEGIN
      IF ~c.disabled & c.item.Valid() THEN
         focus := c.view
      END;
   END HandleCtrlMsg2;
   
   
   PROCEDURE (c: CustomLog) HandleModelMsg (VAR msg: Models.Message);
      VAR form: TextMappers.Formatter;
   BEGIN
      WITH msg: LogMsg DO
         form.ConnectTo(c.model);
         form.WriteString(msg.string$); form.WriteLn;
         Views.Update(c, Views.keepFrames)
      ELSE (* ignore other messages *)
      END
   END HandleModelMsg;
   
   PROCEDURE (c: CustomLog) HandlePropMsg2 (VAR msg: Properties.Message);
   BEGIN
      WITH msg: Properties.FocusPref DO
         IF ~c.disabled & ~c.readOnly THEN msg.setFocus := TRUE END
      | msg: Properties.SizePref DO
         IF (msg.w = Views.undefined) OR (msg.h = Views.undefined) THEN
            msg.w := 50 * Ports.mm; msg.h := 50 * Ports.mm
         END
      ELSE
      END
   END HandlePropMsg2;
   
   PROCEDURE (c: CustomLog) CheckLink (VAR ok: BOOLEAN);
      VAR mod, name: Meta.Name; v: Meta.Item; control: REAL;
   BEGIN
      ok := FALSE;
      IF (c.item.typ = Meta.recTyp) THEN
         c.item.GetTypeName(mod, name);
         ok := TRUE
      END
   END CheckLink;
   
   PROCEDURE (c: CustomLog) Update (f: Views.Frame; op, from, to: INTEGER);
   BEGIN
      PaintLog(c, f)
   END Update;

   PROCEDURE NewLog* (p: Controls.Prop): Views.View;
      VAR c: CustomLog; context: Context;
   BEGIN
      NEW(c);
      c.model := TextModels.dir.New();
      c.view := TextViews.dir.New(c.model);
      context := NewContext(c.view, c);
      (*MtScrollers.AddScrollerOn(c.view);*)
      Controls.OpenLink(c, p); RETURN c
   END NewLog;

   PROCEDURE DepositLog*;
      VAR p: Controls.Prop;
   BEGIN
      NEW(p); p.link := "TestControls.log";
      p.label := ""; p.guard := ""; p.notifier := "";
      Views.Deposit(NewLog(p))
   END DepositLog;

Такой способ работает, сообщения добавляются. Но при добавлении скроллера (программного MtScrollers или в режиме разработки - через меню Tools - Add Scroller) - мой контрол становится белым и ничего не отображается или вылетают трапы в процедуре Restore на вызов c.view.context.SetSize(..) - c.view.context отчего-то равен NIL. Подскажите корректный способ добавления скроллера, кто знает, или другой способ создания лога.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Воскресенье, 24 Декабрь, 2006 20:26 
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
К сожалению, подробно сейчас разбираться не могу. Навскидку:
не совсем понятен смысл наследования от Control, да и вообще смысл создания нетекстового лога. По существу проблемы:
1) смущает SetSize, косвенно вызываемый из Restore - насколько я помню, этого делать нельзя, это может вести к сложным рекурсивным петлям обновления экрана;
2) прокрутка в ББ может делаться двух видов:
а) отображение, вложенное в скроллер, имеет большой размер, а уже скроллер его прокручивает. Это просто, т.к. отображению не нужно заботиться о прокрутке вообще;
б) для отображений со сложным содержанием (например, тексты) - размер отображения всегда равен размеру скроллера, показ нужного места обеспечивает само отображение, обрабатывая в HandleCtrlMsg сообщения Controllers.PollSectionMsg и SetSectionMsg.
Можно реализовать такую логику. Был уже подробный пример - см. ветку viewtopic.php?t=241.
Однако я сейчас не уверен, что у Controls нет уже своей обработки этих сообщений, а Вы наследуетесь от него - проверьте!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Воскресенье, 24 Декабрь, 2006 21:40 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 18:08
Сообщения: 76
Лог мне нужен как раз текстовой. Цель - записывать в этот лог свои строки, и сохранить этот лог. Наследование от Controls.Control чтобы использовать интерактор и соотвествующий ему элемент управления (по аналогии с Dialog.List -> ListBox) и заносить сообщения в лог:
Код:
 log.Add ("my message")

К тому же (наследуясь от Controls.Control) я получаю доступ к своему интерактору через Meta, а от Views.View - не пробовал ещё, возможно пробовать надо будет как в ObxButtons.
Метод c.view.context.SetSize(...) работает у меня в разных вьюшках без проблем. Хотя мне не нравится вызывать его каждый раз в Restore, только другого способа я пока не знаю (да и не пробовал - проблем не возникало); можно ли (и корректно ли) это делать, например, в HandlePropMsg?
А Controllers.PollSectionMsg действительно не приходит в HandleCtrlMsg2.


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

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


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

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


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

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