Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.11.26;
Скачать: CL | DM;

Вниз

UI: Выделение с прокруткой.   Найти похожие ветки 

 
guav ©   (2006-10-15 17:51) [0]

В программе реализовано выделение прямоугольной области мышью при зажатии левой или правой кнопки (как в пеинте или в ListView). Рисуется оно на TPaintBox лежащем на TScrollBox. Есть требование сделать так чтобы при выводе мыши из области пеинтбокса скроллбокс прокручивался, чтобы можно было выделять большие области.
Как реализовать такую прокрутку ?


 
Eraser ©   (2006-10-15 18:08) [1]

> [0] guav ©   (15.10.06 17:51)

код из совершенно другой программы, но со сходной функциональностью.
if FConnection.AdvMouseScroll and (FConnection.RenderMode = 1) then
 begin
   if HorzScrollBar.IsScrollBarVisible then
   begin
     // Вычисляем 20% от ширины окна.
     a1 := ClientWidth div 5;
     // Проверяем правую границу окна.
     if (x > ClientWidth - a1) and (FLastX > ClientWidth - a1) then
     begin
       FLastX := ClientWidth - a1;
       nX := X - FLastX;
       //Caption := "Pos = " + IntToStr(HorzScrollBar.Position) +
       //  " Range = " + IntToStr(HorzScrollBar.Range) +
       //  " ClientWidth = " + IntToStr(ClientWidth) +
       //  " nX = " + IntToStr(nX);
       //Caption := "X = " + IntToStr(x) +
       //  "LastX = " + IntToStr(FLastX) +
       //  " nX = " + IntToStr(nX);
       if (nX > 0) and
       (HorzScrollBar.Position + 1 < HorzScrollBar.Range - ClientWidth) then
       begin
         HorzScrollBar.Position := HorzScrollBar.Position + nX;
         ptCursor := ClientToScreen(Point(FLastX, FLastY));
         SetCursorPos(ptCursor.X, ptCursor.Y);
       end;
     end;
     // Проверяем левую границу окна.
     if (x < a1) and (FLastX < a1) then
     begin
       FLastX := a1;
       nX := FLastX - X;
       if (nX > 0) and
       (HorzScrollBar.Position > 0) then
       begin
         HorzScrollBar.Position := HorzScrollBar.Position - nX;
         ptCursor := ClientToScreen(Point(FLastX, FLastY));
         SetCursorPos(ptCursor.X, ptCursor.Y);
       end;
     end;
   end;
   FLastX := x;
   if VertScrollBar.IsScrollBarVisible then
   begin
     // Вычисляем 20% от высоты окна.
     a1 := ClientHeight div 5;
     // Проверяем нижнюю окна.
     if (y > ClientHeight - a1) and (FLastY > ClientHeight - a1) then
     begin
       nY := Y - FLastY;
       if (nY > 0) and
       (VertScrollBar.Position < VertScrollBar.Range - ClientHeight) then
       begin
         //Caption := IntToStr(VertScrollBar.Position) + " X " +
         //  IntToStr(VertScrollBar.Range - ClientHeight);
         VertScrollBar.Position := VertScrollBar.Position + nY;
         ptCursor := ClientToScreen(Point(FLastX, FLastY));
         SetCursorPos(ptCursor.X, ptCursor.Y);
       end;
     end;
     // Проверяем верхнюю границу окна.
     if (y < a1) and (FLastY < a1) then
     begin
       nY := FLastY - Y;
       if (nY > 0) and
       (VertScrollBar.Position > 0) then
       begin
         VertScrollBar.Position := VertScrollBar.Position - nY;
         ptCursor := ClientToScreen(Point(FLastX, FLastY));
         SetCursorPos(ptCursor.X, ptCursor.Y);
       end;
     end;
   end;
   FLastY := y;
 end;


 
guav ©   (2006-10-15 18:18) [2]

> [1] Eraser ©   (15.10.06 18:08)

Спасибо.
Идея понятна. Никаких таймеров с автопрокруткой, вместо этого при попытке выйти из области прокрутка и SetCursorPos обратно в область. Реализация, конечно, проще в этом случае, но, думаю, пользователю будет удобнее "как в Listview"; вообще не стоит злоупотреблять функциями вроде SetCursorPos или ClipCursor.
Всё же хотелось бы узнать как сделать "как в Listview".


 
Eraser ©   (2006-10-15 18:21) [3]

> [2] guav ©   (15.10.06 18:18)

думаю примерно так же, только убрать SetCursorPos.

> вообще не стоит злоупотреблять функциями вроде SetCursorPos
> или ClipCursor.

согласен, черевато багами. но в моем случае сделал, чтобы выглядело как у конкурентов :)


 
Eraser ©   (2006-10-15 18:30) [4]

все таки для граф. редактора удобнее когда процесс полностью контролируешь, а автопрокрутка в ListView уж очень слабоуправляема.


 
guav ©   (2006-10-15 18:46) [5]

> [4] Eraser ©   (15.10.06 18:30)

Уговорил, сделаю так, не понравится пользователям - переделаю.


 
guav ©   (2006-10-16 00:30) [6]

Таки не понравился такой подход мне самому.
Будем делать как в ListView.
Нашел, что похожий скроллинг у грида.
В TCustomGrid.MouseDown : SetTimer(Handle, 1, 60, nil); - т.е. никакая специальная API функция для таких дел не используется, просто прокручивание по одной ячейке по таймеру. Мжет правда мне не подойти, т.к. у меня не ячейки а пиксели, они значительно меньше.
Ещё пример похожего скролинга - в редакторе или в IE при выделении текста, если завести курсор мыши выше или ниже окна с текстом.


 
AlexeyT ©   (2006-10-16 01:21) [7]

Правильно делать как раз с таймером, IMHO. Когда мышь вне твоего поля, таймер прокручивает контрол, когда мышь вернулась, таймер выключаешь. Я у себя так сделал.


 
Eraser ©   (2006-10-16 01:22) [8]

> [6] guav ©   (16.10.06 00:30)


> Мжет правда мне не подойти, т.к. у меня не ячейки а пиксели,
> они значительно меньше.

ну можно скролировать не по 1 пикселю.

> Ещё пример похожего скролинга - в редакторе или в IE при
> выделении текста, если завести курсор мыши выше или ниже
> окна с текстом

угу, можно даже сделать, чтобы скорость скроллинга зависела от удаления мыши от границ контрола.


 
guav ©   (2006-10-16 14:01) [9]

Меня настроаживает это:

> SetTimer(Handle, 1, 60, nil);
- есть подозрение, что такие малые задержки не выполняются точно, при этом, для попиксельной прокрутки и этой задержки было бы мало.


> [7] AlexeyT ©   (16.10.06 01:21)

Что за контрол ? Грид, эдит, или графическое поле ввода ? Какой


 
guav ©   (2006-10-16 14:03) [10]

> Какой

интервал таймера ?



Страницы: 1 вся ветка

Текущий архив: 2006.11.26;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.037 c
15-1162763416
albanier
2006-11-06 00:50
2006.11.26
QIP


6-1152433865
anton773
2006-07-09 12:31
2006.11.26
закачка файла


1-1160634052
gdaujk
2006-10-12 10:20
2006.11.26
Вариантный массив


15-1162823059
Виктор1985
2006-11-06 17:24
2006.11.26
Аналог RSDN@Home для дельфимастера?


3-1158775178
Lexa11_2002
2006-09-20 21:59
2006.11.26
Как сделать лучше структуру данных