"Открепление" элементов формы.

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

"Открепление" элементов формы.

Сообщение wofs » 09.09.2017 06:14:53

Итак, начало здесь: viewtopic.php?f=5&t=25397
Задача сделать "открепление" вкладок в отдельное окно, просто потянув за них.
Изображение
Изображение

Вот, что на сегодня получилось (исходник) (работает в Win+Mac):
https://yadi.sk/d/kiqP9JFA3MjSyy

Зачем это надо.
Планируется каждую вкладку сделать максимально автономной, что бы при необходимости добавить функционал - мы просто подключали нужный нам пакет lpk (эх... dll-ку/dynlib бы цеплять... как там нынче в Lazarus с формами в динамических библиотеках?).
Притом хочется иметь возможность, при необходимости, "открепить" вкладку от главного окна и получить полноценное окно с заданными функциями.

Как мы делаем.
Создаем Form2, на него размещаем контролы.
При запуске приложения (или при нажатии кнопки) меняем родителя контрола (сперва хотел использовать InsertControl и вставить целиком окно, но возникли проблемы в MacOs X. Но менять родителя вышло даже удобнее) на один из табов главного окна.
Код: Выделить всё
procedure TForm1.InsertForm2ToFotm1();// Отображаем элемент окна Form2 на контроле Form1
begin
  if FindComponent('Form2') = nil then
    Form2:=TForm2.Create(self) else Form2.Hide;

    with Form2.Panel1 do
    begin
      with Form1 do begin
          PageControl1.AddTabSheet;
          PageControl1.Page[0].Caption:='Потяни меня';
          Form2.Panel1.Parent:=PageControl1.Pages[0];
      end;
      Align:=alclient;
    end;

end;   

Если необходимо "открепить" дочерний контрол, то просто тянем его за заголовк таба и "вытягиваем" контрол в новое (родное) окно.
Код: Выделить всё
procedure TForm1.PageControl1MouseDown(Sender: TObject; Button: TMouseButton; // ловим нажатие кнопки мыши в PageControl
  Shift: TShiftState; X, Y: Integer);
begin
     if Button=mbLeft then
       begin
         mX:=X;
         mY:=Y;
         mStateClick:=true;
       end;
end;

procedure TForm1.PageControl1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
const
  mXYdelta = 10;
begin
  if mStateClick then
    begin
         PageControl1.cursor:=crDrag; // меняем курсор

        if ((X<mX-mXYdelta) or (X>mX+mXYdelta) or (Y<mY-mXYdelta) or (Y>mY+mXYdelta)) then
        begin
             mX:=X;
             mY:=Y;
             mStateClick:=false;
             DeleteForm2FromForm1(Form1.PageControl1.TabIndex);
        end;
    end else PageControl1.cursor:=crDefault;
end;             

procedure TForm1.DeleteForm2FromForm1(TabIndex:Integer); // Удаляем  элемент окна Form2 с контрола Form1 и отображаем в Form2 отдельно
begin
  with Form2 do begin
  // Hide;
   Form1.PageControl1.Page[TabIndex].Destroy;
   Form2.Panel1.Parent:=Form2;
   WindowState:=wsNormal;
   Show;
  end;
end;       


Открепили, но есть вопрос.

Как продолжить "тащить" уже новое окно?
То есть взяли, потащили - оторвали и продолжаем тащить? Подскажите решение, пожалуйста. Желательно кроссплатформенное.
Аватара пользователя
wofs
постоялец
 
Сообщения: 379
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: "Открепление" элементов формы.

Сообщение Лекс Айрин » 09.09.2017 10:13:25

Попробуй финт ушами... можно оформить контрол как окно без заголовка и выставить родителем (parents) pageComtrol (точнее, его вкладку) как только мы теряем фокус при вытягивании (или просто при попытке сдвига заголовка вкладки), можно будет сразу же открепить окно, отобразить заголовок и немного сдвинуть окно так, чтобы заголовок попал под курсор. Даже если окно перестанет двигаться, его уже можно двигать как обычное. Тем более, что ты примерно так и делаешь.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: "Открепление" элементов формы.

Сообщение wofs » 09.09.2017 10:21:19

Лекс Айрин писал(а):Попробуй финт ушами... можно оформить контрол как окно без заголовка

С этим я ловлю проблемы в Макоси (первый вариант)... Там запросто встраивается чужой контрол в любое окно, но ни в какую не встраивается целиком окно как контрол.
В этом топе я переделал и все работает в 2х осях (никсы проверю позже - надо ноут у супруги отобрать). Осталось придумать как продолжать тянуть окно после отделения без "передергивания курсора".

Основная проблема - я не могу отследить клик или любое действие с заголовком открепленного окна. Как двигать дальше я придумал, а вот сказать "хватит" не могу.

Добавлено спустя 6 минут 10 секунд:
Или даже не клик мыши на заголовке, а вообще клик.
Аватара пользователя
wofs
постоялец
 
Сообщения: 379
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: "Открепление" элементов формы.

Сообщение Лекс Айрин » 09.09.2017 10:35:07

wofs писал(а):Или даже не клик мыши на заголовке, а вообще клик.


Имхо, тут надо перекрыть функцию окна и работать с ней. Хотя основной затык, видимо, в том, что приходится менять коней на переправе.

wofs писал(а):Там запросто встраивается чужой контрол в любое окно, но ни в какую не встраивается целиком окно как контрол.


А если использовать фрейм?
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: "Открепление" элементов формы.

Сообщение wofs » 09.09.2017 10:39:16

Лекс Айрин писал(а):А если использовать фрейм?

Не рассматривал - попробую вечером.

Добавлено спустя 1 минуту 29 секунд:
Лекс Айрин писал(а):Хотя основной затык, видимо, в том, что приходится менять коней на переправе.


Именно. Мышь еще нажата, а окно другое, хотя и в фокусе.
Аватара пользователя
wofs
постоялец
 
Сообщения: 379
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: "Открепление" элементов формы.

Сообщение vitaly_l » 09.09.2017 10:54:22

wofs писал(а):Именно. Мышь еще нажата, а окно другое, хотя и в фокусе.

Посмотрите какой обработчик ещё возвращает onMouseMove?
И пропишите в нём, что если (mStateClick = false and mFormChange = true) then двигать форму №2.

Добавлено спустя 5 минут 3 секунды:
И передайте фокус на Form2
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: "Открепление" элементов формы.

Сообщение wofs » 09.09.2017 11:06:06

vitaly_l писал(а):Посмотрите какой обработчик ещё возвращает onMouseMove?

Проблема в том, что onMouseMove срабатывает только на дочерних элементах, а если его прописать в форме - тишина.

vitaly_l писал(а):И передайте фокус на Form2

Форма и так в фокусе, пробовал принудительно - без изменений.

У меня проблема в том, что я не могу отловить события на заголовке новой формы. Ни перемещение мыши, ни клик, ни мышь даун, ни мышь ап.
Обработчики молчат, как буд-то заголовок - это не окно совсем.
Аватара пользователя
wofs
постоялец
 
Сообщения: 379
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: "Открепление" элементов формы.

Сообщение Лекс Айрин » 09.09.2017 11:17:05

wofs писал(а):Мышь еще нажата, а окно другое, хотя и в фокусе.


А если поменять не только коней, но и карету? т. е. просто переключить не только форму, но и обработчик onMove и пр...?

wofs писал(а):Обработчики молчат, как буд-то заголовок - это не окно совсем.


Ты прав, заголовок это не окно -- это часть, если грубо, системы. Максимум, что возможно, это выбрать какие кнопки отображать... ну и меню заодно.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: "Открепление" элементов формы.

Сообщение vitaly_l » 09.09.2017 11:40:20

wofs писал(а):У меня проблема в том, что я не могу

Код: Выделить всё
procedure TForm1.PageControl1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
const
  mXYdelta = 10;
begin
  if mStateClick then
    begin
         PageControl1.cursor:=crDrag; // меняем курсор

         вот здесь пропишите ДВИГАНИЕ ФОРМЫ!
         А когда научитесь её двигать, тогда уже скрывайте TabSheet

    end else PageControl1.cursor:=crDefault;
end;         
Последний раз редактировалось vitaly_l 09.09.2017 12:22:18, всего редактировалось 1 раз.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: "Открепление" элементов формы.

Сообщение zub » 09.09.2017 11:46:51

Простейший докинг работает из коробки
У вас нет необходимых прав для просмотра вложений в этом сообщении.
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: "Открепление" элементов формы.

Сообщение vitaly_l » 09.09.2017 12:05:14

zub писал(а):Простейший докинг работает из коробки

Но его нет для TabSheet у PageControl
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: "Открепление" элементов формы.

Сообщение wofs » 09.09.2017 13:01:04

vitaly_l писал(а):вот здесь пропишите ДВИГАНИЕ ФОРМЫ!
А когда научитесь её двигать, тогда уже скрывайте TabSheet

Хм... подумаю.
Непонятно как будет отрабатывать событие, когда мы выйдем из зоны таба...

Лекс Айрин писал(а):т. е. просто переключить не только форму, но и обработчик onMove и пр...?

А можно небольшой пример?
Аватара пользователя
wofs
постоялец
 
Сообщения: 379
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: "Открепление" элементов формы.

Сообщение Лекс Айрин » 09.09.2017 13:47:36

wofs писал(а):А можно небольшой пример?

Вот здесь я пока точно не помогу.

wofs писал(а):когда мы выйдем из зоны таба...


Вроде как, компонент получает сообщение первым, хотя, конечно, надо экспериментировать.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: "Открепление" элементов формы.

Сообщение zub » 09.09.2017 13:56:43

>>Но его нет для TabSheet у PageControl
Он есть для самого PageControl и memo
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: "Открепление" элементов формы.

Сообщение wofs » 09.09.2017 14:04:30

zub писал(а):Простейший докинг работает из коробки

Ух ты, а я не знал такой возможности!

Добавлено спустя 2 минуты 56 секунд:
Лекс Айрин
А вы имели ввиду вариант, который предложил zub, когда говорили, что тянули целиком форму?
Аватара пользователя
wofs
постоялец
 
Сообщения: 379
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

След.

Вернуться в Lazarus

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

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

Рейтинг@Mail.ru