Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > Custom ScrollBar своими руками


Автор: Psychosis 11.8.2005, 23:26
Уже 6 дней мучаюсь, никак не могу написать...

Этот scrollbar должен быть расширяемым. Имеется ввиду, что верний предел (Max), на самом деле не является пределом. Просто, при перемещении ползунка до этого Max, и далее, это значении Max будет увеличиваться пропорционально тому, насколько мы этот ползунок удвинули дальше. При последующем обратном движении, Max будет уменьшаться, но не опустится менее первоначального Max. Т.е. здесь есть как бы два предела первоначальный (OriginalMax) и текущий (CurrentMax).

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

Ответ желательно в форме обработчиков для трех событий:
- MouseDown
- MouseMove
- MouseUp

Язык C++ или ObjectPascal....

Автор: sergejzr 11.8.2005, 23:30
Цитата(Psychosis @ 11.8.2005, 22:26)
Ответ желательно в форме обработчиков для трех событий:
- MouseDown
- MouseMove
- MouseUp

??
Почему бы не ловить событие onchange. Там запоминать значение и сравнивать его с новым. Затем менять соответсвенно MaxValue и двигать бегунок на новое значение setValue()

Автор: Guest 11.8.2005, 23:45
Position у стандартного Scrollbar'а не может выходить за [min; max] никогда!

Код

procedure TForm1.ScrollBar1Change(Sender: TObject);
begin
  Caption := IntToStr(ScrollBar1.Position);
end;


Будет от 0 (min) до 100 (max)....

Автор: sergejzr 12.8.2005, 01:33
Надо значит ввести фактор и перерешивать координаты

канвас = scrollbar_value*factor
scrollbar_value=канвас/factor

faсtor меняется в зависимости от "настоящего" размера канваса и составляет настоящий_макс/100

Чтото вроде этого.
Единственно что тебе надо - вычислять настоящий макс в зависимости от предидущего значения скрола.

Автор: Psychosis 12.8.2005, 03:25
Нет, совсем не то!
Умножить TScrollBar.Position на какой-либо фактор я могу, только мне не это надо...

Я пишу свой собственный ScrollBar, да и к тому же не от TComponent, у меня есть свой собственный класс TArea (от TObject), от него порожден TCustomRectArea, затем TRectArea.

У TArea основные функциональные методы:
Код

    procedure MouseDown(AButton: TMouseButton; AShiftState: TShiftState; APosition: TPoint); virtual;
    procedure MouseMove(AShiftState: TShiftState; APosition: TPoint); virtual;
    procedure MouseUp(AButton: TMouseButton; AShiftState: TShiftState; APosition: TPoint); virtual;
    procedure PaintTo(ACanvas: TCanvas); virtual;


Отрисовка производиться на канву формы через буфферный битмап, события от мыши, так же, поступают от формы и передаются самой парентной TArea. У TArea есть список дочерних TArea.... and so on

Так вот я хочу написать нормальный TScrollBar (TScrollBarArea), а не такой глючный как стандартный виндовский и с доп. возможностями.
У стандартного есть например такой глюк, когда тянуть ползунок далеко вправо, за пределы ScrollBar'а, то ползунок перескакивает на позицию 0. Или если предварительно поместить ползунок на середину, а затем аналогично далеко потянуть его влево, то он перескочит на середину...

Так вот, TScrollBar у меня называется TScrollBarAreaNew, но он нам не интересен, т.к. реализует только расположение кнопок для прокрутки и "TSliderBarArea", кот. нас и интересует.
Код

  TScrollBarAreaNew = class(TRectArea)
  private
    FDecreaseButtonArea: TCustomTimerButtonArea;
    FIncreaseButtonArea: TCustomTimerButtonArea;
    FSliderBarArea: TSliderBarArea;
    FListLayout: TListLayout;

    function GetOrientation: TOrientation;
    procedure SetOrientation(AValue: TOrientation);

    function GetMin: Real;
    procedure SetMin(AValue: Real);
    function GetMax: Real;
    procedure SetMax(AValue: Real);
  protected
    procedure DecreaseButtonAreaPaintHandler(ACanvas: TCanvas);
    procedure IncreaseButtonAreaPaintHandler(ACanvas: TCanvas);
    procedure DecreaseButtonAreaTimerHandler(ASender: TObject);
    procedure IncreaseButtonAreaTimerHandler(ASender: TObject);
  public
    constructor Create; override;
    destructor Destroy; override;

    property Orientation: TOrientation read GetOrientation write SetOrientation;

    property Min: Real read GetMin write SetMin;
    property Max: Real read GetMax write SetMax;

    procedure Resize; override;
  end;


TSliderBarArea - по сути, просто контейнер, кот. определяет в каких пределах может ездить "TSliderArea".
Код

  TSliderBarArea = class(TRectArea)
  private
    FSliderArea: TSliderArea;
  public
    constructor Create; override;
    destructor Destroy; override;

    procedure Resize; override;

    procedure PaintTo(ACanvas: TCanvas); override;
  end;


Вот с "TSliderArea" и есть основная "Ж"

Код

  TSliderArea = class({TRectArea}TCustomRectArea)
  private
    FCaught: Boolean;
    FCatchPoint: TPoint;
    FOriginalPoint: TPoint;

    FPosition: Real;
    FSize: Real;
    FMin: Real;
    FMax: Real;
    FRealMin: Real;
    FRealMax: Real;
  protected
    function GetLeft: Integer; override;
    procedure SetLeft(AValue: Integer); override;
    function GetTop: Integer; override;
    procedure SetTop(AValue: Integer); override;
    function GetWidth: Integer; override;
    procedure SetWidth(AValue: Integer); override;
    function GetHeight: Integer; override;
    procedure SetHeight(AValue: Integer); override;
  public
    procedure MouseDown(AButton: TMouseButton; AShiftState: TShiftState; APosition: TPoint); override;
    procedure MouseMove(AShiftState: TShiftState; APosition: TPoint); override;
    procedure MouseUp(AButton: TMouseButton; AShiftState: TShiftState; APosition: TPoint); override;

    procedure PaintTo(ACanvas: TCanvas); override;
  end;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)