Поле.отд
Главная     ◄Глагол     ◄Азбука     ◄Задачи на Глаголе     Примеры приложений ►   Среда разработки ►   Отладка программ ►   Отличия от Оберона ►   Отличия от Паскаля ►   Ассемблер ARM ►   Глагол для ARM ►   ? и Ответы
 
 glagol.png Программируем по-русски
 

Основная задача Глагола — дать человеку возможность воплощать свои мысли на языке, близком к его родному языку.

Издатель Глагола
 

 
(*~\Глагол\Отделы\Поле~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
(**)                        ОТДЕЛ Поле;
(*============================================================================*
 * НАЗНАЧЕНИЕ: на поле располагаются наделы ввода/вывода текстовых данных
 * Поле следит за передачей посылок от клавиатуры и мышки к выбранному наделу.
 *============================================================================*)
ИСПОЛЬЗУЕТ 
  Рамка,
  Надел,
  Окно ИЗ "..\Обмен\",
  Ввод ИЗ "..\Обмен\";
ПОСТ          (* встроенные состояния поля (<= 0): *)
  сРабота-= 0;
   сДалее-=-1;
  сОтмена-=-2;
ВИД
  Доступ-=ДОСТУП К Вид;
  Задача=ЗАДАЧА(поле:Доступ; посылка+:Ввод.Посылка);
  Вид-=НАБОР(Рамка.Вид)
    наделы        :Надел.Доступ; (* связка наделов поля           *)
    выбранныйНадел:Надел.Доступ; (* надел, выбранный человеком    *)
    Приём         :Задача;       (* оставшийся ввод и управление  *)
    состояние+    :ЦЕЛ;          (* м.б. как выше, так и др.      *)
  КОН;

  (* посылки к наделам *)
  Отрисовка-=НАБОР(Ввод.Посылка) КОН;
  Буквица-  =НАБОР(Ввод.Посылка)
               буквица+:ЦЕЛ
             КОН;

ЗАДАЧА^ ПереместитьВвод(поле:Доступ; дальше:КЛЮЧ);
(* опережающее определение задачи *)

(******************************************************************************)
ЗАДАЧА Рисовать-(поле:Доступ);
(* Перерисовывает все наделы поля *)
ПЕР
  надел,первыйНадел:Надел.Доступ;
  отрисовка:Отрисовка;
УКАЗ
  (* убираем указку *)
  Окно.РазмерУказки(0);
  (* при необходимости наделы сами нарисуют указку *)
  первыйНадел:=поле.наделы;
  надел:=первыйНадел;
  ПОВТОРЯТЬ
    Рамка.Выставить(надел,поле);
    надел.Приём(надел,отрисовка);
    надел:=надел.следующий
  ДО надел = первыйНадел
КОН Рисовать;

(******************************************************************************)
ЗАДАЧА ОкноНаВсёПоле-(поле:Доступ);
(* Выравнивает окно по границе поля *)
УКАЗ
  Окно.ИзменитьРазмер(поле.нс+1,поле.пк+1)
КОН ОкноНаВсёПоле;

(******************************************************************************)
ЗАДАЧА СостояниеНаделу-(надел:Надел.Доступ; состояние:ЦЕЛ);
(* изменить состояние надела *)
ПЕР
  отрисовка:Отрисовка;
  поле:Доступ;
УКАЗ
  ЕСЛИ (надел = ПУСТО)
     ИЛИ
       (надел.состояние = состояние)
  ТО
    ВОЗВРАТ (* из ЗАДАЧИ *)
  КОН;
  поле:=надел.поле(Доступ);
  ВЫБРАТЬ состояние ИЗ
  | Надел.сОбычный:
      ЕСЛИ надел.состояние = Надел.сВыбран ТО
        (* уберём указку *)
        Окно.РазмерУказки(0)
      КОН
  | Надел.сВыбран:
      ЕСЛИ (надел.состояние # Надел.сОтключен)
         И (Надел.прВыбираемый В надел.признаки)
         И (надел # поле.выбранныйНадел)
      ТО
        СостояниеНаделу(поле.выбранныйНадел,Надел.сОбычный);
        поле.выбранныйНадел:=надел
      ИНАЧЕ
        ВОЗВРАТ (* из ЗАДАЧИ *)
      КОН
  | Надел.сОтключен:
      ЕСЛИ надел = поле.выбранныйНадел ТО
        ПереместитьВвод(поле,ВКЛ)
      КОН
  ИНАЧЕ
  КОН;
  надел.состояние:=состояние;
  надел.Приём(надел,отрисовка)
КОН СостояниеНаделу;

(******************************************************************************)
ЗАДАЧА ПереместитьВвод(поле:Доступ; дальше:КЛЮЧ);
ПЕР
  надел,первыйНадел:Надел.Доступ;
УКАЗ
  первыйНадел:=поле.выбранныйНадел;
  надел:=первыйНадел;
  ПОВТОРЯТЬ
    ЕСЛИ дальше ТО
      надел:=надел.следующий
    ИНАЧЕ
      надел:=надел.предыдущий
    КОН;
    ЕСЛИ (Надел.прВыбираемый В надел.признаки)
       И (надел.состояние # Надел.сОтключен)
    ТО
      СостояниеНаделу(надел,Надел.сВыбран);
      ВОЗВРАТ (* из ЗАДАЧИ *)
    КОН
  ДО надел = первыйНадел
КОН ПереместитьВвод;
 
(******************************************************************************)
ЗАДАЧА Проверить-(поле:Доступ);
ПЕР
  надел,выбранныйНадел,первыйНадел:Надел.Доступ;
  родп:ЦЕЛ; (* род посылки *)
  (* посылки *)
  отКлавиш:Ввод.ОтКлавиш;
  отМышки:Ввод.ОтМышки;
  буквица:Буквица;
УКАЗ
  родп:=Окно.Опрос(отКлавиш,отМышки);
  выбранныйНадел:=поле.выбранныйНадел;
  ЕСЛИ родп = Ввод.клавиши ТО (* пришла посылка от клавиатуры *)
    (* сначало её обрабатывает надел с текущим вводом *)
    ЕСЛИ выбранныйНадел # ПУСТО ТО 
      выбранныйНадел.Приём(выбранныйНадел,отКлавиш);
      ЕСЛИ отКлавиш.код = 0 ТО ВОЗВРАТ (* из ЗАДАЧИ *) КОН;
    КОН;
    (* остаток обрабатывает пользователь поля *)
    поле.Приём(поле,отКлавиш);
    ЕСЛИ отКлавиш.код = 0 ТО ВОЗВРАТ (* из ЗАДАЧИ *) КОН;
    (* опрашиваем буквицы наделов *)
    буквица.буквица:=отКлавиш.код;
    первыйНадел:=поле.наделы;
    надел:=первыйНадел;
    КОЛЬЦО
      ЕСЛИ НЕ (Надел.прГлухой В надел.признаки)
         И (надел.состояние # Надел.сОтключен)
      ТО
        надел.Приём(надел,буквица);
        ЕСЛИ буквица.буквица = 0 ТО (* надел отозвался *)
          СостояниеНаделу(надел,Надел.сВыбран);
          ВОЗВРАТ (* из ЗАДАЧИ *)
        КОН
      КОН;
      надел:=надел.следующий;
      ЕСЛИ надел = первыйНадел ТО
        ВЫХОД  (* из КОЛЬЦА *)
      КОН
    КОН;
    (* под конец проверяем смену ввода *)
    ЕСЛИ выбранныйНадел # ПУСТО ТО
      ЕСЛИ отКлавиш.код = 9 ТО   (* по Tab *)
        ПереместитьВвод(поле,НЕ отКлавиш.упрШифт)
      АЕСЛИ НЕ (отКлавиш.упрШифт ИЛИ отКлавиш.упрКонтр) ТО
        ВЫБРАТЬ отКлавиш.код ИЗ  (* по стрелкам *)
(* <- ^*) | 25H,26H: ПереместитьВвод(поле,ОТКЛ)
(* -> V*) | 27H,28H: ПереместитьВвод(поле,ВКЛ)
        ИНАЧЕ
        КОН
      КОН
    КОН
  АЕСЛИ родп = Ввод.мышка ТО (* пришла посылка от мышки *)
    ЕСЛИ Ввод.прокрут В отМышки.события ТО (* прокрут колеса *)
      ЕСЛИ выбранныйНадел # ПУСТО ТО 
        выбранныйНадел.Приём(выбранныйНадел,отМышки)
      КОН
    ИНАЧЕ (* нажатие и отпускание кнопки *)
      ЕСЛИ (отМышки.к < поле.лк)
       ИЛИ (отМышки.к > поле.пк)
       ИЛИ (отМышки.с < поле.вс)
       ИЛИ (отМышки.с > поле.нс)
      ТО (* мимо поля *)
        ВОЗВРАТ (* из ЗАДАЧИ *)
      КОН;
      (* ищем надел в который попала мышка *)
      ЕСЛИ выбранныйНадел # ПУСТО ТО (* скорее всего она попала в выбранный *)
        первыйНадел:=выбранныйНадел
      ИНАЧЕ
        первыйНадел:=поле.наделы
      КОН;
      надел:=первыйНадел;
      КОЛЬЦО
        ЕСЛИ НЕ (Надел.прГлухой В надел.признаки)
           И (надел.состояние # Надел.сОтключен)
           И (отМышки.к >= надел.лк) И (отМышки.к <= надел.пк)
           И (отМышки.с >= надел.вс) И (отМышки.с <= надел.нс)
        ТО                             (* попалась *)
          ЕСЛИ выбранныйНадел # ПУСТО ТО
            СостояниеНаделу(надел,Надел.сВыбран)
          КОН;
          (* преобразуем к местным координатам *)
          УМЕНЬШИТЬ(отМышки.к,надел.лк);
          УМЕНЬШИТЬ(отМышки.с,надел.вс);
          ЕСЛИ (отМышки.события = {})
             И (отМышки.кнопки = {})
          ТО                   (* отпущена кнопка *)
            надел.Приём(надел,отМышки)
          КОН;
          (* поиск прекратить *)
          ВЫХОД (* из КОЛЬЦА *) 
        КОН;
        надел:=надел.следующий;
        ЕСЛИ надел = первыйНадел ТО ВЫХОД (* из КОЛЬЦА *) КОН
      КОН
    КОН;
    ЕСЛИ НЕ отМышки.отработана ТО (* что осталось, обрабатывает пользователь поля *)
      поле.Приём(поле,отМышки)
    КОН
  АЕСЛИ родп = Ввод.закрыт ТО
    поле.состояние:=сОтмена
  КОН
КОН Проверить;

(******************************************************************************)
ЗАДАЧА ДобавитьНадел-(поле:Доступ; надел:Надел.Доступ);
(* Добавляет <надел> в <поле> *)
УКАЗ
  (* добавляем в связку *)
  Надел.Добавить(поле.наделы,надел);
  (* обратная связь для надела *)
  надел.поле:=поле; 
  (* поиск первого возможного надела с вводом *)
  ЕСЛИ (поле.выбранныйНадел = ПУСТО)
     И (надел.состояние # Надел.сОтключен)
     И (Надел.прВыбираемый В надел.признаки)
  ТО
    надел.состояние:=Надел.сВыбран;
    поле.выбранныйНадел:=надел
  КОН;
КОН ДобавитьНадел;

(******************************************************************************)
ЗАДАЧА Создать-(верх,лево,строк,колонок:ЦЕЛ;
                             окружение:Доступ;
                              середина:КЛЮЧ;
                                 Приём:Задача):Доступ;
ПЕР
  поле:Доступ; 
УКАЗ
  СОЗДАТЬ(поле);
  ЕСЛИ окружение = ПУСТО ТО
    (* окружением является всё окно экрана *)
    СОЗДАТЬ(окружение);
    Рамка.Подготовить(окружение,0,0,строк,колонок)
  КОН;
  ЕСЛИ середина ТО
     (* помещаем поле в середину окружения *)
    верх:=(окружение.нс-окружение.вс-строк+1) ДЕЛИТЬ 2;
    лево:=(окружение.пк-окружение.лк-колонок+1) ДЕЛИТЬ 2
  КОН;
  Рамка.Подготовить(поле,верх,лево,строк,колонок);
  Рамка.Выставить(поле,окружение);
  поле.Приём:=Приём;
  ВОЗВРАТ поле (* из ЗАДАЧИ *)
КОН Создать;

КОН Поле.

 
 


Вопросы, замечания и предложения высылайте на atimopheyev@yahoo.com

 
Главная     ◄Глагол     ◄Азбука     ◄Задачи на Глаголе     Примеры приложений ►   Среда разработки ►   Отладка программ ►   Отличия от Оберона ►   Отличия от Паскаля ►   Ассемблер ARM ►   Глагол для ARM ►   ? и Ответы