OberonCore

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

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




Начать новую тему Ответить на тему  [ Сообщений: 32 ]  На страницу 1, 2  След.
Автор Сообщение
СообщениеДобавлено: Пятница, 05 Сентябрь, 2008 14:21 

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

Для сфокусированного отображения всё просто. А вот если отображение не в фокусе, то как определить момент сползания курсора с отображения?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 05 Сентябрь, 2008 15:56 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2449
Откуда: Россия, Томск
Иван Кузьмицкий писал(а):
Для сфокусированного отображения всё просто. А вот если отображение не в фокусе, то как определить момент сползания курсора с отображения?
Ха! Удачи!
Фреймворк не предусматривает такой возможности. Максимум - можно перехватить отработку мыши контейнером и посчитать координаты. Если же курсор выскочит сразу за пределы контейнера (или окна или Блэкбокса), то никто об этом не узнает. Можете ставить хук на оконную процедуру, если с WinApi знакомы.
По теме можно почитать тут: viewtopic.php?f=24&t=370


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 05 Сентябрь, 2008 16:12 

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

Я думал, что получится такой трюк: при входе курсора на вьюшку, активировать Services.Action и периодически проверять координаты. Вроде даже получилось. Но если отображение - кнопка, при нажатии на которую закрывается окно, то отложенное действие теряет фрейм, в котором оно запрашивает координаты через f.Input - и тут же трап.

Тогда я решил сделать по-другому. При вползании курсора, из обработчика HandleCtrlMsg посылается сообщение HoverMsg самой же вьюшке, где оно обрабатывается в HandleViewMsg, и оттуда же запускается действие Services.Action. Это же действие периодически посылает сообщение HoverMsg вьюшке, и по идее, всё должно быть "пучком". Но опять не сложилось - при обработке HoverMsg, я делаю Views.Update(b, Views.keepFrames), который жОстко трапает при вызове Broadcast, в точке
Код:
IF v.guard > 0 THEN ASSERT(v.guard # g, 21) END;
Я не понял, почему.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 05 Сентябрь, 2008 17:30 

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

Суть вот какая (жалко, ДРАКОНом не владею - нарисовал бы схему! Ничего, вот устаканятся дела - возьмём на вооружение).

На форме лежит кнопка (отображение-контейнер).
Код:
CONST
   hoverDelay = 40;
TYPE
   ActionHover = POINTER TO RECORD (Services.Action)
      b: Button;
   END;

   Button = POINTER TO RECORD (Views.View)
      control: ButtonContext;
      bitmap: ButtonContext;
      selected: BOOLEAN;
      ident: Identity;   (* temporary dummy model *)
      focus: ButtonContext;   (* current focus; either top or bottom *)
      path: Path;
      picw, pich: INTEGER; (* пользовательские габариты картинки *)
      flat: BOOLEAN;
      hover: BOOLEAN; (* признак "зависания" курсора над контролом *)
      ahover: ActionHover;
   END;

В обработчике сообщений контроллера, при получении сообщения Controllers.CursorMessage взводится флаг "ховер", отображение обновляется и запускается отложенное действие:
Код:
| msg: Controllers.CursorMessage DO
   IF ~b.hover THEN
      b.hover := TRUE; b.Update; (* первоначальное включение ховера *)
      IF b.ahover = NIL THEN (* запустить периодическую проверку ховера *)
         NEW(b.ahover); b.ahover.b := b; Services.DoLater(b.ahover, Services.Ticks() + hoverDelay);
      END
   END

Процедура этого самого отложенного действия, периодически отсылает отображению сообщение HoverMsg. Ну и проверяет режим "ховера" - если таковой включён, то регистрируется заново, обеспечивая периодичность. А если "ховер" выключен, то процедура делает обновление отображения и вырубается.
Код:
(* Периодическая проверка ховера. Если курсор вне контрола, то ховер вырубается. Если нет, проверка запускается вновь.*)
PROCEDURE (a: ActionHover) Do;
   VAR hoverMsg: HoverMsg;
BEGIN
   Views.Broadcast(a.b, hoverMsg);
   IF a.b.hover THEN Services.DoLater(a, Services.Ticks() + hoverDelay) ELSE Views.Update(a.b, Views.keepFrames) END
END Do;

Ну а в обработчике сообщений отображения, ловится сообщение HoverMsg, и запускается проверка координат курсора. То есть, в случае вылета курсора за пределы рамки отображения, отложенное действие отработает минимум два раза. Один раз отошлёт сообщение (при обработке которого выяснится, что курсор вне рамки), а второй раз - обнаружит выключение ховера и вырубится.
Код:
PROCEDURE (b: Button) HandleViewMsg (f: Views.Frame; VAR msg: Views.Message);
BEGIN
   WITH msg: HoverMsg DO
      CheckHover(f, b);
   ELSE
   END
END HandleViewMsg;

Ну и вот сама проверка координат курсора:
Код:
PROCEDURE CheckHover(f: Views.Frame; b: Button);
   VAR w, h, x, y: INTEGER; modifiers: SET; isDown: BOOLEAN;
BEGIN
      b.context.GetSize(w, h); f.Input(x, y, modifiers, isDown);
      IF ((x > 0) & (x < w)) & ((y > 0) & (y <h)) THEN
         IF ~b.hover THEN
            b.hover := TRUE;
         END
      ELSE
         IF b.hover THEN b.hover := FALSE; b.ahover := NIL END
      END;
END CheckHover;


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 05 Сентябрь, 2008 18:38 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Иван Кузьмицкий писал(а):
Вопсчем, у меня что-то получилось. Не знаю, насколько это правильно, но по крайней мере, используются штатные средства ББ.


А фрэймворк доточить не проще было? Это ж любимая тема оберонщиков: не клепать заплаток, остановиться, переосмыслить, сделать лучше и возможно даже проще. При том, что фрэймворк "без пробелем расширяется"...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 05 Сентябрь, 2008 19:56 

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 06 Сентябрь, 2008 00:17 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Иван Кузьмицкий писал(а):
"Доточить", не проще. Нет никакого желания копаться в потрохах винапи.


С винапи все как раз просто.

Иван Кузьмицкий писал(а):
Насчёт расширяемости, это Вы, Влад, угадали в точку. Фреймворк не предоставляет некоей возможности, зато можно её получить имеющимися штатными средствами.


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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 06 Сентябрь, 2008 08:52 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2935
Откуда: г. Ярославль
Vlad писал(а):
Иван Кузьмицкий писал(а):
"Доточить", не проще. Нет никакого желания копаться в потрохах винапи.

С винапи все как раз просто.
ББ - это ж не совсем винапи. Вернее, совсем не. А чтоб сделать ховер, надо опускаться на уровень винапи и, по сути, делать новую версию ББ. Я к такому не готов пока :)

Vlad писал(а):
Иван Кузьмицкий писал(а):
Насчёт расширяемости, это Вы, Влад, угадали в точку. Фреймворк не предоставляет некоей возможности, зато можно её получить имеющимися штатными средствами.


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


Ну Влад, Вы же хитрите :) Разве реализация нужного поведения гуя штатными средствами нынче считается хаком? Сильно сомневаюсь. Хак - это использование штатных средств неестественным образом. А в данном примере, я считаю, механизмы ББ применяются вполне естественно: отследили курсор и переключили состояние кнопки. Ну нет у ящика ховера, нет - не заложили в своё время. И вычурность тут ни при чём, просто нет данной финдюльки. Ну, нет и нет - зато любую финдюльку можно сделать, если понадобится.

P.S. Конечно, будь ховер встроен в ББ, было бы куда веселее, тут я с Вами согласен :)


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

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4625
Откуда: Россия, Орёл
Сорри за то, что не в тему, но чесслово, надоело.

Пришел Vlad, который в ББ нихрена не смыслит и по теме сказать ему нечего. Зато, как обычно, начал всех строить: ББ - дерьмо, пишите на WinApi, оно лучше и т.д. и т.п.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 06 Сентябрь, 2008 13:59 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
Иван Кузьмицкий писал(а):
P.S. Конечно, будь ховер встроен в ББ, было бы куда веселее ..

А он сильно нужен? И как можно было бы его встроить (сначала на уровне интерфейсов)?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 06 Сентябрь, 2008 14:33 

Зарегистрирован: Вторник, 29 Август, 2006 12:32
Сообщения: 2662
Откуда: Россия, Ярославль
Ну, сильно-не сильно, но это явно не самая последняя вещь в хорошем GUI. Контрол который реагирует на событие "наезд мыши" как бы побуждает пользователя к действию, имхо.

Ну и реализовать можно было бы введя всего один новый тип сообщений контроллера типа,
Код:
MouseOver = RECORD(Views.CtrlMessage)
over : BOOLEAN (* сообщает, вошёл или покинул курсор область отображения контрола *)
END;


P.S. А ведь в ББ есть возможность задавать тип курсора мыши при наведении на отображение. Значит, это событие каким-то образом контроллируется внутри ББ.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 06 Сентябрь, 2008 19:53 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
Пётр Кушнир писал(а):
P.S. А ведь в ББ есть возможность задавать тип курсора мыши при наведении на отображение. Значит, это событие каким-то образом контроллируется внутри ББ.

Возможно, в Блэкбоксе для этого используются стандартные функции WinAPI -- в Win32 каждое окно (а любой визуальный компонент -- виджет или вьюшка в вашей терминологии -- является окном в Windows) имеет свойство-тип курсора мыши...
Ч. Петзолд. Программирование для Windows® 95 писал(а):
У функции RegisterClassEx имеется один параметр: указатель на структуру типа WNDCLASSEX. Структура
WNDCLASSEX определяется в заголовочных файла Windows следующим образом:
Код:
typedef struct tagWNDCLASSEX
{
  UINT cbSize;
  UINT style;
  WNDPROC lpfnWndProc;
  int cbClsExtra;
  int cbWndExtra;
  HINSTANCE hInstance;
  HICON hIcon;
  HCURSOR hCursor;       // вот оно!
  HBRUSH hbrBackground;
  LPCSTR lpszMenuName;
  LPCSTR lpszClassName;
  HICON hIconSm;
} WNDCLASSEX;



Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 06 Сентябрь, 2008 20:45 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2449
Откуда: Россия, Томск
Geniepro писал(а):
вьюшка в вашей терминологии -- является окном в Windows
Это не так.


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

Зарегистрирован: Вторник, 29 Август, 2006 12:32
Сообщения: 2662
Откуда: Россия, Ярославль
Geniepro писал(а):
Пётр Кушнир писал(а):
P.S. А ведь в ББ есть возможность задавать тип курсора мыши при наведении на отображение. Значит, это событие каким-то образом контроллируется внутри ББ.

Возможно, в Блэкбоксе для этого используются стандартные функции WinAPI -- в Win32 каждое окно (а любой визуальный компонент -- виджет или вьюшка в вашей терминологии -- является окном в Windows) имеет свойство-тип курсора мыши...

Да ну понятно, что в основе лежит ВинАПИ, я сказал об этом скорее в плане того, что отслеживание всё таки происходит, только программисту не предоставили возможности(типа той, что описана ранее) об этом узнать...
Отображение, или "вьюшка" в вашей терминологии, это скорее разрисованный по всякому кадр(плюс вариации в виде отображения виндовых контролов через HostCFrames) и соответственно, курсор задаётся иным способом.


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

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
Александр Ильин писал(а):
Geniepro писал(а):
вьюшка в вашей терминологии -- является окном в Windows
Это не так.

Что не так? Разве блэкбоксёрские вьюшки не имеют отображаемой области?
В Windows любой графический элемент является окном.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 06 Сентябрь, 2008 23:11 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
Пётр Кушнир писал(а):
Да ну понятно, что в основе лежит ВинАПИ, я сказал об этом скорее в плане того, что отслеживание всё таки происходит, только программисту не предоставили возможности(типа той, что описана ранее) об этом узнать...
Отображение, или "вьюшка" в вашей терминологии, это скорее разрисованный по всякому кадр(плюс вариации в виде отображения виндовых контролов через HostCFrames) и соответственно, курсор задаётся иным способом.

Я не знаю, как там реально устроен блекбоксовый фреймворк, но скорее всего всё-таки при создании окон (виджетов) прямо указывается, какой курсор мыши отображать над этим окном. В этом случае не Блэкбокс, а Windows определяет и управляет сменой формы курсора мыши...


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

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Надо было быть ненормальными, чтобы разрабатывая кроссплатформенный фреймворк сразу для 2-х ОС (Мак и Вин), кадрировать "виджеты" с помощью нативных окошек. От ОС берётся базовое окно и граф. контекст на него. Больше от ОС ничего не требуется.
Особый случай - стандартные контролы. Но они сделаны очень хитро и изолированно.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 07 Сентябрь, 2008 06:05 

Зарегистрирован: Вторник, 29 Ноябрь, 2005 21:41
Сообщения: 1030
Чем меньше особых случаев - тем лучше.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 08 Сентябрь, 2008 15:16 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Иван Кузьмицкий писал(а):
ББ - это ж не совсем винапи. Вернее, совсем не. А чтоб сделать ховер, надо опускаться на уровень винапи и, по сути, делать новую версию ББ. Я к такому не готов пока :)


Я имел ввиду, что на WinAPI это делается самым естественным и очевидным для данного фрэймворка способом - подпиской на соответствующее событие. Если BB не позволяет напрямую задействовать эту функциональность, то это его личные проблемы (как фрэймворка поверх другого фрэймворка, но с претензией на многоплатформенность), а не проблемы WinAPI.

Иван Кузьмицкий писал(а):
Ну Влад, Вы же хитрите :) Разве реализация нужного поведения гуя штатными средствами нынче считается хаком?


Хорошо. По пунктам. Конкретно данное решение я считакю хаком, потому что:
1) Что оно делает - совсем не очевидно.
2) Как оно это делает - тоже не очевидно.
3) Оно легко ломается (впрочем это скорее следствие п. 2).
4) Оно нормально не реюзается (а это скорее следствие п. 1).

Иван Кузьмицкий писал(а):
Ну нет у ящика ховера, нет - не заложили в своё время. И вычурность тут ни при чём, просто нет данной финдюльки. Ну, нет и нет - зато любую финдюльку можно сделать, если понадобится.


Я бы с вами мог согласиться, если бы вы разрешили п.1 и 4. Т.е., фиг с ним, с расширением фрэймворка (я сам стараюсь всячески избегать этой опции). Просто оформите это решение в виде компоненты с вменяемым интерфейсом (типа подписаться/отписаться от ховера) и минимумом требований от ее потребителей.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 08 Сентябрь, 2008 15:30 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Евгений Темиргалеев писал(а):
Зато, как обычно, начал всех строить: ББ - дерьмо


Этого я не говорил.

Евгений Темиргалеев писал(а):
, пишите на WinApi, оно лучше


И этого я не предлагал. Я просто сказал, что на WinAPI это легко и просто, потому что соответствующая поддержка есть в самом фрэймворке.

Евгений Темиргалеев писал(а):
и т.д. и т.п.


Не кипятитесь. Ну покритиковал немножко. Считаете что не за что? :) Зато глядишь, кто-нибудь предложит лучшее решение и пользователи ББ только выиграют.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 32 ]  На страницу 1, 2  След.

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


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

Сейчас этот форум просматривают: Google [Bot] и гости: 2


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

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