mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-19 02:59:19 +02:00
Moved drag-able notebook
git-svn-id: trunk@26257 -
This commit is contained in:
parent
2b652bd86c
commit
afbdf3e742
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -1223,7 +1223,10 @@ components/lazcontrols/Makefile svneol=native#text/plain
|
|||||||
components/lazcontrols/Makefile.fpc svneol=native#text/plain
|
components/lazcontrols/Makefile.fpc svneol=native#text/plain
|
||||||
components/lazcontrols/dividerbevel.pas svneol=native#text/pascal
|
components/lazcontrols/dividerbevel.pas svneol=native#text/pascal
|
||||||
components/lazcontrols/dividerbevel_icon.lrs svneol=native#text/pascal
|
components/lazcontrols/dividerbevel_icon.lrs svneol=native#text/pascal
|
||||||
|
components/lazcontrols/extendednotebook.pas svneol=native#text/pascal
|
||||||
|
components/lazcontrols/extendednotebook_icon.lrs svneol=native#text/pascal
|
||||||
components/lazcontrols/images/tdividerbevel.png -text
|
components/lazcontrols/images/tdividerbevel.png -text
|
||||||
|
components/lazcontrols/images/textnotebook.png -text
|
||||||
components/lazcontrols/lazcontrols.lpk svneol=native#text/xml
|
components/lazcontrols/lazcontrols.lpk svneol=native#text/xml
|
||||||
components/lazcontrols/lazcontrols.pas svneol=native#text/pascal
|
components/lazcontrols/lazcontrols.pas svneol=native#text/pascal
|
||||||
components/lazreport/doc/contributors.txt svneol=native#text/plain
|
components/lazreport/doc/contributors.txt svneol=native#text/plain
|
||||||
|
448
components/lazcontrols/extendednotebook.pas
Normal file
448
components/lazcontrols/extendednotebook.pas
Normal file
@ -0,0 +1,448 @@
|
|||||||
|
{ DividerBevel
|
||||||
|
|
||||||
|
Copyright (C) 2010 <name of author> <contact>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or modify it
|
||||||
|
under the same terms as the Lazarus Component Library (LCL)
|
||||||
|
|
||||||
|
See the file COPYING.modifiedLGPL.txt, included in this distribution,
|
||||||
|
for details about the copyright.
|
||||||
|
|
||||||
|
}
|
||||||
|
unit ExtendedNotebook;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, sysutils, LResources, Forms, Controls, Graphics, Dialogs, ExtCtrls,
|
||||||
|
LCLIntf, LCLType, math;
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
TNotebookTabDragDropEvent = procedure(Sender, Source: TObject;
|
||||||
|
OldIndex, NewIndex: Integer;
|
||||||
|
CopyDrag: Boolean;
|
||||||
|
var Done: Boolean) of object;
|
||||||
|
TNotebookTabDragOverEvent = procedure(Sender, Source: TObject;
|
||||||
|
OldIndex, NewIndex: Integer;
|
||||||
|
CopyDrag: Boolean;
|
||||||
|
var Accept: Boolean) of object;
|
||||||
|
|
||||||
|
{ TExtendedNotebook }
|
||||||
|
|
||||||
|
TExtendedNotebook = class(TNotebook)
|
||||||
|
private
|
||||||
|
FDraggingTabIndex: Integer;
|
||||||
|
FOnTabDragDrop: TDragDropEvent;
|
||||||
|
FOnTabDragOver: TDragOverEvent;
|
||||||
|
FOnTabDragOverEx: TNotebookTabDragOverEvent;
|
||||||
|
FOnTabDragDropEx: TNotebookTabDragDropEvent;
|
||||||
|
FOnTabEndDrag: TEndDragEvent;
|
||||||
|
FOnTabStartDrag: TStartDragEvent;
|
||||||
|
FTabDragMode: TDragMode;
|
||||||
|
FTabDragAcceptMode: TDragMode;
|
||||||
|
|
||||||
|
FTabDragged: boolean;
|
||||||
|
FDragOverIndex: Integer;
|
||||||
|
FDragToRightSide: Boolean;
|
||||||
|
FDragOverTabRect, FDragNextToTabRect: TRect;
|
||||||
|
|
||||||
|
procedure InitDrag;
|
||||||
|
procedure InvalidateRect(ARect: TRect);
|
||||||
|
function TabIndexForDrag(x, y: Integer): Integer;
|
||||||
|
function TabRectEx(AIndex, X, Y: Integer; out IsRightHalf: Boolean): TRect;
|
||||||
|
protected
|
||||||
|
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
||||||
|
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X,
|
||||||
|
Y: Integer); override;
|
||||||
|
procedure DoStartDrag(var DragObject: TDragObject); override;
|
||||||
|
procedure DoEndDrag(Target: TObject; X,Y: Integer); override;
|
||||||
|
procedure DragOver(Source: TObject; X, Y: Integer; State: TDragState;
|
||||||
|
var Accept: Boolean); override;
|
||||||
|
procedure DragCanceled; override;
|
||||||
|
procedure PaintWindow(DC: HDC); override;
|
||||||
|
public
|
||||||
|
constructor Create(TheOwner: TComponent); override;
|
||||||
|
procedure DragDrop(Source: TObject; X, Y: Integer); override;
|
||||||
|
procedure BeginDragTab(ATabIndex: Integer; Immediate: Boolean; Threshold: Integer = -1);
|
||||||
|
property DraggingTabIndex: Integer read FDraggingTabIndex;
|
||||||
|
published
|
||||||
|
property OnTabDragOver: TDragOverEvent read FOnTabDragOver write FOnTabDragOver;
|
||||||
|
property OnTabDragOverEx: TNotebookTabDragOverEvent read FOnTabDragOverEx write FOnTabDragOverEx;
|
||||||
|
property OnTabDragDrop: TDragDropEvent read FOnTabDragDrop write FOnTabDragDrop;
|
||||||
|
property OnTabDragDropEx: TNotebookTabDragDropEvent read FOnTabDragDropEx write FOnTabDragDropEx;
|
||||||
|
property OnTabEndDrag: TEndDragEvent read FOnTabEndDrag write FOnTabEndDrag;
|
||||||
|
property OnTabStartDrag: TStartDragEvent read FOnTabStartDrag write FOnTabStartDrag;
|
||||||
|
|
||||||
|
property TabDragMode: TDragMode read FTabDragMode write FTabDragMode
|
||||||
|
default dmManual;
|
||||||
|
property TabDragAcceptMode: TDragMode read FTabDragAcceptMode write FTabDragAcceptMode
|
||||||
|
default dmManual;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure Register;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
procedure Register;
|
||||||
|
begin
|
||||||
|
{$I extendednotebook_icon.lrs}
|
||||||
|
RegisterComponents('LazControls',[TExtendedNotebook]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TExtendedNotebook }
|
||||||
|
|
||||||
|
procedure TExtendedNotebook.InitDrag;
|
||||||
|
begin
|
||||||
|
DragCursor := crDrag;
|
||||||
|
FDragOverIndex := -1;
|
||||||
|
FDragOverTabRect := Rect(0, 0, 0, 0);
|
||||||
|
FDragNextToTabRect := Rect(0, 0, 0, 0);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TExtendedNotebook.InvalidateRect(ARect: TRect);
|
||||||
|
begin
|
||||||
|
LCLIntf.InvalidateRect(Handle, @ARect, false);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TExtendedNotebook.TabIndexForDrag(x, y: Integer): Integer;
|
||||||
|
var
|
||||||
|
TabPos: TRect;
|
||||||
|
begin
|
||||||
|
Result := TabIndexAtClientPos(Point(X,Y));
|
||||||
|
if Result < 0 then begin
|
||||||
|
TabPos := TabRect(PageCount-1);
|
||||||
|
// Check empty space after last tab
|
||||||
|
if (TabPos.Right > 1) and (X > TabPos.Left) and
|
||||||
|
(Y >= TabPos.Top) and (Y <= TabPos.Bottom)
|
||||||
|
then
|
||||||
|
Result := PageCount - 1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TExtendedNotebook.TabRectEx(AIndex, X, Y: Integer; out IsRightHalf: Boolean): TRect;
|
||||||
|
begin
|
||||||
|
Result := TabRect(AIndex);
|
||||||
|
if (TabPosition in [tpLeft, tpRight]) then // Drag-To-Bottom/Lower
|
||||||
|
IsRightHalf := Y > (Result.Top + Result.Bottom) div 2
|
||||||
|
else
|
||||||
|
IsRightHalf := X > (Result.Left + Result.Right) div 2;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TExtendedNotebook.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
|
||||||
|
Y: Integer);
|
||||||
|
var
|
||||||
|
t: Integer;
|
||||||
|
begin
|
||||||
|
InitDrag;
|
||||||
|
FTabDragged:=false;
|
||||||
|
inherited MouseDown(Button, Shift, X, Y);
|
||||||
|
t := TabIndexAtClientPos(Point(X,Y));
|
||||||
|
if (fTabDragMode = dmAutomatic) and (Button = mbLeft) and (t >= 0) then
|
||||||
|
BeginDragTab(t, False);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TExtendedNotebook.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
||||||
|
var
|
||||||
|
MouseUpTabIndex: LongInt;
|
||||||
|
begin
|
||||||
|
InitDrag;
|
||||||
|
inherited MouseUp(Button, Shift, X, Y);
|
||||||
|
if not FTabDragged then begin
|
||||||
|
// no drag => check for normal click and activate page
|
||||||
|
MouseUpTabIndex := TabIndexAtClientPos(Point(X,Y));
|
||||||
|
if (Button = mbLeft) and (FDraggingTabIndex = MouseUpTabIndex) and
|
||||||
|
(FDraggingTabIndex >= 0)
|
||||||
|
then
|
||||||
|
PageIndex:=MouseUpTabIndex;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TExtendedNotebook.DoStartDrag(var DragObject: TDragObject);
|
||||||
|
begin
|
||||||
|
if FDraggingTabIndex < 0 then
|
||||||
|
inherited DoStartDrag(DragObject)
|
||||||
|
else
|
||||||
|
if Assigned(FOnTabStartDrag) then FOnTabStartDrag(Self, DragObject);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TExtendedNotebook.DoEndDrag(Target: TObject; X, Y: Integer);
|
||||||
|
begin
|
||||||
|
if FDraggingTabIndex < 0 then
|
||||||
|
inherited DoEndDrag(Target, X, Y)
|
||||||
|
else
|
||||||
|
if Assigned(FOnTabEndDrag) then FOnTabEndDrag(Self, Target, x, Y);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TExtendedNotebook.DragOver(Source: TObject; X, Y: Integer; State: TDragState;
|
||||||
|
var Accept: Boolean);
|
||||||
|
var
|
||||||
|
TabIndex: Integer;
|
||||||
|
LastRect, LastNRect: TRect;
|
||||||
|
LastIndex: Integer;
|
||||||
|
LastRight, NeedInvalidate: Boolean;
|
||||||
|
Ctrl: Boolean;
|
||||||
|
Src: TExtendedNotebook;
|
||||||
|
begin
|
||||||
|
if (not (Source is TExtendedNotebook)) or
|
||||||
|
(TExtendedNotebook(Source).FDraggingTabIndex < 0)
|
||||||
|
then begin
|
||||||
|
// normal DragOver
|
||||||
|
inherited DragOver(Source, X, Y, State, Accept);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Tab drag over
|
||||||
|
TabIndex := TabIndexForDrag(X,Y);
|
||||||
|
|
||||||
|
Accept := (FTabDragAcceptMode = dmAutomatic) and (Source = Self) and
|
||||||
|
(TabIndex >= 0) and (TabIndex <> FDraggingTabIndex);
|
||||||
|
|
||||||
|
if Assigned(FOnTabDragOver) then
|
||||||
|
FOnTabDragOver(Self,Source,X,Y,State,Accept);
|
||||||
|
|
||||||
|
if ((state = dsDragLeave) or (TabIndex < 0)) and
|
||||||
|
(FDragOverIndex >= 0)
|
||||||
|
then begin
|
||||||
|
InvalidateRect(FDragOverTabRect);
|
||||||
|
InvalidateRect(FDragNextToTabRect);
|
||||||
|
FDragOverIndex := -1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (TabIndex < 0) then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
Ctrl := (GetKeyState(VK_CONTROL) and $8000)<>0;
|
||||||
|
if Ctrl then
|
||||||
|
DragCursor := crMultiDrag
|
||||||
|
else
|
||||||
|
DragCursor := crDrag;
|
||||||
|
|
||||||
|
LastIndex := FDragOverIndex;
|
||||||
|
LastRight := FDragToRightSide;
|
||||||
|
LastRect := FDragOverTabRect;
|
||||||
|
LastNRect := FDragNextToTabRect;
|
||||||
|
FDragOverIndex := TabIndex;
|
||||||
|
FDragOverTabRect := TabRectEx(TabIndex, X, Y, FDragToRightSide);
|
||||||
|
|
||||||
|
if (Source = Self) and (TabIndex = FDraggingTabIndex - 1) then
|
||||||
|
FDragToRightSide := False;
|
||||||
|
if (Source = Self) and (TabIndex = FDraggingTabIndex + 1) then
|
||||||
|
FDragToRightSide := True;
|
||||||
|
|
||||||
|
NeedInvalidate := (FDragOverIndex <> LastIndex) or (FDragToRightSide <> LastRight);
|
||||||
|
if NeedInvalidate then begin
|
||||||
|
InvalidateRect(LastRect);
|
||||||
|
InvalidateRect(LastNRect);
|
||||||
|
InvalidateRect(FDragOverTabRect);
|
||||||
|
InvalidateRect(FDragNextToTabRect);
|
||||||
|
end;
|
||||||
|
|
||||||
|
if FDragToRightSide then begin
|
||||||
|
inc(TabIndex);
|
||||||
|
if TabIndex < PageCount then
|
||||||
|
FDragNextToTabRect := TabRect(TabIndex);
|
||||||
|
end else begin
|
||||||
|
if TabIndex > 0 then
|
||||||
|
FDragNextToTabRect := TabRect(TabIndex - 1);
|
||||||
|
end;
|
||||||
|
if NeedInvalidate then
|
||||||
|
InvalidateRect(FDragNextToTabRect);
|
||||||
|
|
||||||
|
Src := TExtendedNotebook(Source);
|
||||||
|
if (Source = self) and (TabIndex > Src.DraggingTabIndex) then
|
||||||
|
dec(TabIndex);
|
||||||
|
|
||||||
|
if Assigned(FOnTabDragOverEx) then
|
||||||
|
FOnTabDragOverEx(Self, Source, Src.DraggingTabIndex, TabIndex, Ctrl, Accept);
|
||||||
|
|
||||||
|
if (not Accept) or (state = dsDragLeave) then begin
|
||||||
|
InvalidateRect(FDragOverTabRect);
|
||||||
|
InvalidateRect(FDragNextToTabRect);
|
||||||
|
FDragOverIndex := -1;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TExtendedNotebook.DragCanceled;
|
||||||
|
begin
|
||||||
|
inherited DragCanceled;
|
||||||
|
if (FDragOverIndex >= 0) then begin
|
||||||
|
InvalidateRect(FDragOverTabRect);
|
||||||
|
InvalidateRect(FDragNextToTabRect);
|
||||||
|
end;
|
||||||
|
FDragOverIndex := -1;
|
||||||
|
DragCursor := crDrag;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TExtendedNotebook.PaintWindow(DC: HDC);
|
||||||
|
var
|
||||||
|
Points: Array [0..3] of TPoint;
|
||||||
|
|
||||||
|
procedure DrawLeftArrow(ARect: TRect);
|
||||||
|
var y, h: Integer;
|
||||||
|
begin
|
||||||
|
h := Min( (Abs(ARect.Bottom - ARect.Top) - 4) div 2,
|
||||||
|
(Abs(ARect.Left - ARect.Right) - 4) div 2 );
|
||||||
|
y := (ARect.Top + ARect.Bottom) div 2;
|
||||||
|
Points[0].X := ARect.Left + 2 + h;
|
||||||
|
Points[0].y := y - h;
|
||||||
|
Points[1].X := ARect.Left + 2 + h;
|
||||||
|
Points[1].y := y + h;
|
||||||
|
Points[2].X := ARect.Left + 2;
|
||||||
|
Points[2].y := y;
|
||||||
|
Points[3] := Points[0];
|
||||||
|
Polygon(DC, @Points, 4, False);
|
||||||
|
end;
|
||||||
|
procedure DrawRightArrow(ARect: TRect);
|
||||||
|
var y, h: Integer;
|
||||||
|
begin
|
||||||
|
h := Min( (Abs(ARect.Bottom - ARect.Top) - 4) div 2,
|
||||||
|
(Abs(ARect.Left - ARect.Right) - 4) div 2 );
|
||||||
|
y := (ARect.Top + ARect.Bottom) div 2;
|
||||||
|
Points[0].X := ARect.Right - 2 - h;
|
||||||
|
Points[0].y := y - h;
|
||||||
|
Points[1].X := ARect.Right - 2 - h;
|
||||||
|
Points[1].y := y + h;
|
||||||
|
Points[2].X := ARect.Right - 2;
|
||||||
|
Points[2].y := y;
|
||||||
|
Points[3] := Points[0];
|
||||||
|
Polygon(DC, @Points, 4, False);
|
||||||
|
end;
|
||||||
|
procedure DrawTopArrow(ARect: TRect);
|
||||||
|
var x, h: Integer;
|
||||||
|
begin
|
||||||
|
h := Min( (Abs(ARect.Bottom - ARect.Top) - 4) div 2,
|
||||||
|
(Abs(ARect.Left - ARect.Right) - 4) div 2 );
|
||||||
|
x := (ARect.Left + ARect.Right) div 2;
|
||||||
|
Points[0].Y := ARect.Top + 2 + h;
|
||||||
|
Points[0].X := x - h;
|
||||||
|
Points[1].Y := ARect.Top + 2 + h;
|
||||||
|
Points[1].X := x + h;
|
||||||
|
Points[2].Y := ARect.Top + 2;
|
||||||
|
Points[2].X := x;
|
||||||
|
Points[3] := Points[0];
|
||||||
|
Polygon(DC, @Points, 4, False);
|
||||||
|
end;
|
||||||
|
procedure DrawBottomArrow(ARect: TRect);
|
||||||
|
var x, h: Integer;
|
||||||
|
begin
|
||||||
|
h := Min( (Abs(ARect.Bottom - ARect.Top) - 4) div 2,
|
||||||
|
(Abs(ARect.Left - ARect.Right) - 4) div 2 );
|
||||||
|
x := (ARect.Left + ARect.Right) div 2;
|
||||||
|
Points[0].Y := ARect.Bottom - 2 - h;
|
||||||
|
Points[0].X := X - h;
|
||||||
|
Points[1].Y := ARect.Bottom - 2 - h;
|
||||||
|
Points[1].X := X + h;
|
||||||
|
Points[2].Y := ARect.Bottom - 2;
|
||||||
|
Points[2].X := X;
|
||||||
|
Points[3] := Points[0];
|
||||||
|
Polygon(DC, @Points, 4, False);
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
inherited PaintWindow(DC);
|
||||||
|
if FDragOverIndex < 0 then exit;
|
||||||
|
|
||||||
|
if (TabPosition in [tpLeft, tpRight]) then begin
|
||||||
|
if FDragToRightSide then begin
|
||||||
|
DrawBottomArrow(FDragOverTabRect);
|
||||||
|
if (FDragOverIndex < PageCount - 1) then
|
||||||
|
DrawTopArrow(FDragNextToTabRect);
|
||||||
|
end else begin
|
||||||
|
DrawTopArrow(FDragOverTabRect);
|
||||||
|
if (FDragOverIndex > 0) then
|
||||||
|
DrawBottomArrow(FDragNextToTabRect);
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if FDragToRightSide then begin
|
||||||
|
DrawRightArrow(FDragOverTabRect);
|
||||||
|
if (FDragOverIndex < PageCount - 1) then
|
||||||
|
DrawLeftArrow(FDragNextToTabRect);
|
||||||
|
end else begin
|
||||||
|
DrawLeftArrow(FDragOverTabRect);
|
||||||
|
if (FDragOverIndex > 0) then
|
||||||
|
DrawRightArrow(FDragNextToTabRect);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TExtendedNotebook.Create(TheOwner: TComponent);
|
||||||
|
begin
|
||||||
|
inherited Create(TheOwner);
|
||||||
|
InitDrag;
|
||||||
|
fTabDragMode := dmManual;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TExtendedNotebook.DragDrop(Source: TObject; X, Y: Integer);
|
||||||
|
var
|
||||||
|
TabIndex, TabIndex2: Integer;
|
||||||
|
ToRight: Boolean;
|
||||||
|
Ctrl: Boolean;
|
||||||
|
Src: TExtendedNotebook;
|
||||||
|
Accept: Boolean;
|
||||||
|
begin
|
||||||
|
if (not (Source is TExtendedNotebook)) or
|
||||||
|
(TExtendedNotebook(Source).FDraggingTabIndex < 0)
|
||||||
|
then begin
|
||||||
|
// normal DragDrop
|
||||||
|
inherited DragDrop(Source, X, Y);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Tab DragDrop
|
||||||
|
If Assigned(FOnTabDragDrop) then FOnTabDragDrop(Self, Source,X,Y);
|
||||||
|
|
||||||
|
if (FDragOverIndex >= 0) then begin
|
||||||
|
InvalidateRect(FDragOverTabRect);
|
||||||
|
InvalidateRect(FDragNextToTabRect);
|
||||||
|
end;
|
||||||
|
FDragOverIndex := -1;
|
||||||
|
DragCursor := crDrag;
|
||||||
|
|
||||||
|
TabIndex := TabIndexForDrag(X,Y);
|
||||||
|
TabRectEx(TabIndex, X, Y, ToRight);
|
||||||
|
|
||||||
|
if (Source = Self) and (TabIndex = FDraggingTabIndex - 1) then
|
||||||
|
ToRight := False;
|
||||||
|
if (Source = Self) and (TabIndex = FDraggingTabIndex + 1) then
|
||||||
|
ToRight := True;
|
||||||
|
if ToRight then
|
||||||
|
inc(TabIndex);
|
||||||
|
|
||||||
|
Src := TExtendedNotebook(Source);
|
||||||
|
TabIndex2 := TabIndex;
|
||||||
|
if (Source = self) and (TabIndex > Src.DraggingTabIndex) then
|
||||||
|
dec(TabIndex);
|
||||||
|
|
||||||
|
if assigned(FOnTabDragDropEx) then begin
|
||||||
|
Ctrl := (GetKeyState(VK_CONTROL) and $8000)<>0;
|
||||||
|
Accept := True;
|
||||||
|
if Assigned(FOnTabDragOverEx) then
|
||||||
|
FOnTabDragOverEx(Self, Source, Src.DraggingTabIndex, TabIndex, Ctrl, Accept);
|
||||||
|
if Accept then
|
||||||
|
FOnTabDragDropEx(Self, Source, Src.DraggingTabIndex, TabIndex, Ctrl, FTabDragged);
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (not FTabDragged) and (FTabDragAcceptMode = dmAutomatic) and
|
||||||
|
(Source = Self) and (TabIndex2 >= 0) and (TabIndex2 <> FDraggingTabIndex)
|
||||||
|
then begin
|
||||||
|
Pages.Move(Src.DraggingTabIndex, TabIndex);
|
||||||
|
FTabDragged := True;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TExtendedNotebook.BeginDragTab(ATabIndex: Integer; Immediate: Boolean;
|
||||||
|
Threshold: Integer = -1);
|
||||||
|
begin
|
||||||
|
if (ATabIndex < 0) or (ATabIndex >= PageCount) then
|
||||||
|
raise Exception.Create('Bad index');
|
||||||
|
FDraggingTabIndex := ATabIndex;
|
||||||
|
BeginDrag(Immediate, Threshold);
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
19
components/lazcontrols/extendednotebook_icon.lrs
Normal file
19
components/lazcontrols/extendednotebook_icon.lrs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
LazarusResources.Add('textnotebook','PNG',[
|
||||||
|
#137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#24#0#0#0#24#8#6#0#0#0#224'w='#248#0
|
||||||
|
+#0#0#1'sRGB'#0#174#206#28#233#0#0#0#4'gAMA'#0#0#177#143#11#252'a'#5#0#0#0#9
|
||||||
|
+'pHYs'#0#0#14#195#0#0#14#195#1#199'o'#168'd'#0#0#1'CIDATHKc'#252#15#4#12'4'#4
|
||||||
|
+'L44'#27'l4#6'#31#236'>'#255#129#161'i'#193'v'#178#237#174'K'#240'dp5'#20#128
|
||||||
|
+#232#7'Y'#128#14'l'#242#150#253#255#248#233'7'#6#198'&'#142'K'#12'f&'#206' '
|
||||||
|
+#186#127#239#9#3':'#6'9'#136'X'#177#195#7#15'a'#6'Qy'#249'd'#178#131#5']'#163
|
||||||
|
+#143#151'>'#131#173#189#29'j'#16#149#149'M'#194#22'b$'#139#129#204'9t'#224' '
|
||||||
|
+'X'#31#206' z'#240#224#14#3'2'#6#185#144#24'1X'#208#192'|'#4#182#0#20'4'#176
|
||||||
|
+#224'AW'#0#146'WPP'#193#25't'#248#228'@'#154#192#22'tv'#230'2'#128#194#12#4
|
||||||
|
+#182'l'#187#8#183#12#217'p'#144#235#209#1'L'#12#175'%'#200#1#140#28#7#247#239
|
||||||
|
+#223'&9'#236'Az@a'#143#17#7#132#130#136#146#164#5#207#201#160#176#7#5#15#12
|
||||||
|
+'dfz'#130#153'0'#239'c'#11'"l'#242#143#31'>'#3#155#3'K'#166#240'T'#4'N'#179
|
||||||
|
+#208#248#0#197#9#12#224#11'gB'#150#195'#'#153'P'#16#225'r=,'#233#226#11'B'
|
||||||
|
+#130#169#8#221''''#200#134#225#179#24#166#142'`'#16'Q'#18#193'D'#7#17'%'#150
|
||||||
|
+#16#29'D'#228'ZB'#159' '#194#230':Pz&'#7#163#155#133'Re'#210#162'>'#192#168
|
||||||
|
+#147#177#149#166#228#134'?('#243'b'#173#244#201'5'#16#155'>'#0'F'#185#255#147
|
||||||
|
+#18#219#213#163#0#0#0#0'IEND'#174'B`'#130
|
||||||
|
]);
|
BIN
components/lazcontrols/images/textnotebook.png
Normal file
BIN
components/lazcontrols/images/textnotebook.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 430 B |
@ -11,15 +11,22 @@
|
|||||||
</SearchPaths>
|
</SearchPaths>
|
||||||
<Other>
|
<Other>
|
||||||
<CompilerPath Value="$(CompPath)"/>
|
<CompilerPath Value="$(CompPath)"/>
|
||||||
|
<CreateMakefileOnBuild Value="True"/>
|
||||||
</Other>
|
</Other>
|
||||||
</CompilerOptions>
|
</CompilerOptions>
|
||||||
<Files Count="1">
|
<Files Count="2">
|
||||||
<Item1>
|
<Item1>
|
||||||
<Filename Value="dividerbevel.pas"/>
|
<Filename Value="dividerbevel.pas"/>
|
||||||
<HasRegisterProc Value="True"/>
|
<HasRegisterProc Value="True"/>
|
||||||
<UnitName Value="dividerbevel"/>
|
<UnitName Value="DividerBevel"/>
|
||||||
</Item1>
|
</Item1>
|
||||||
|
<Item2>
|
||||||
|
<Filename Value="extendednotebook.pas"/>
|
||||||
|
<HasRegisterProc Value="True"/>
|
||||||
|
<UnitName Value="ExtendedNotebook"/>
|
||||||
|
</Item2>
|
||||||
</Files>
|
</Files>
|
||||||
|
<LazDoc Paths="docs\"/>
|
||||||
<Type Value="RunAndDesignTime"/>
|
<Type Value="RunAndDesignTime"/>
|
||||||
<RequiredPkgs Count="2">
|
<RequiredPkgs Count="2">
|
||||||
<Item1>
|
<Item1>
|
||||||
|
@ -7,13 +7,14 @@ unit lazcontrols;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
DividerBevel, LazarusPackageIntf;
|
DividerBevel, ExtendedNotebook, LazarusPackageIntf;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
procedure Register;
|
procedure Register;
|
||||||
begin
|
begin
|
||||||
RegisterUnit('DividerBevel', @DividerBevel.Register);
|
RegisterUnit('DividerBevel', @DividerBevel.Register);
|
||||||
|
RegisterUnit('ExtendedNotebook', @ExtendedNotebook.Register);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
|
@ -40,7 +40,7 @@ uses
|
|||||||
{$IFDEF IDE_MEM_CHECK}
|
{$IFDEF IDE_MEM_CHECK}
|
||||||
MemCheck,
|
MemCheck,
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
Classes, SysUtils, Math, Controls, LCLProc, LCLType, LResources,
|
Classes, SysUtils, Math, Controls, ExtendedNotebook, LCLProc, LCLType, LResources,
|
||||||
LCLIntf, FileUtil, Forms, ComCtrls, Dialogs, StdCtrls, Graphics, Translations,
|
LCLIntf, FileUtil, Forms, ComCtrls, Dialogs, StdCtrls, Graphics, Translations,
|
||||||
ClipBrd, types, Extctrls, Menus, HelpIntfs, LConvEncoding,
|
ClipBrd, types, Extctrls, Menus, HelpIntfs, LConvEncoding,
|
||||||
// codetools
|
// codetools
|
||||||
@ -49,7 +49,7 @@ uses
|
|||||||
SynEditLines, SynEditStrConst, SynEditTypes, SynEdit, SynRegExpr,
|
SynEditLines, SynEditStrConst, SynEditTypes, SynEdit, SynRegExpr,
|
||||||
SynEditHighlighter, SynEditAutoComplete, SynEditKeyCmds, SynCompletion,
|
SynEditHighlighter, SynEditAutoComplete, SynEditKeyCmds, SynCompletion,
|
||||||
SynEditMiscClasses, SynEditMarkupHighAll, SynEditMarks,
|
SynEditMiscClasses, SynEditMarkupHighAll, SynEditMarks,
|
||||||
SynBeautifier, SynEditTextBase, SynPluginTemplateEdit, SynPluginSyncroEdit,
|
SynBeautifier, SynEditTextBase,
|
||||||
SynPluginSyncronizedEditBase, SourceSynEditor,
|
SynPluginSyncronizedEditBase, SourceSynEditor,
|
||||||
// Intf
|
// Intf
|
||||||
SrcEditorIntf, MenuIntf, LazIDEIntf, PackageIntf, IDEHelpIntf, IDEImagesIntf,
|
SrcEditorIntf, MenuIntf, LazIDEIntf, PackageIntf, IDEHelpIntf, IDEImagesIntf,
|
||||||
@ -524,39 +524,6 @@ type
|
|||||||
);
|
);
|
||||||
TSourceNotebookStates = set of TSourceNotebookState;
|
TSourceNotebookStates = set of TSourceNotebookState;
|
||||||
|
|
||||||
TDragMoveTabEvent = procedure(Sender, Source: TObject; OldIndex, NewIndex: Integer; CopyDrag: Boolean) of object;
|
|
||||||
TDragMoveTabQuery = function(Sender, Source: TObject; OldIndex, NewIndex: Integer; CopyDrag: Boolean): Boolean of object;
|
|
||||||
|
|
||||||
{ TSourceDragableNotebook }
|
|
||||||
|
|
||||||
TSourceDragableNotebook = class(TNoteBook)
|
|
||||||
private
|
|
||||||
FMouseDownTabIndex: Integer;
|
|
||||||
FOnCanDragMoveTab: TDragMoveTabQuery;
|
|
||||||
FOnDragMoveTab: TDragMoveTabEvent;
|
|
||||||
FTabDragged: boolean;
|
|
||||||
|
|
||||||
FDragOverIndex: Integer;
|
|
||||||
FDragToRightSide: Boolean;
|
|
||||||
FDragOverTabRect, FDragNextToTabRect: TRect;
|
|
||||||
|
|
||||||
protected
|
|
||||||
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
||||||
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X,
|
|
||||||
Y: Integer); override;
|
|
||||||
procedure DragOver(Source: TObject; X, Y: Integer; State: TDragState;
|
|
||||||
var Accept: Boolean); override;
|
|
||||||
procedure DragCanceled; override;
|
|
||||||
property MouseDownTabIndex: Integer read FMouseDownTabIndex;
|
|
||||||
procedure PaintWindow(DC: HDC); override;
|
|
||||||
procedure InitDrag;
|
|
||||||
public
|
|
||||||
constructor Create(TheOwner: TComponent); override;
|
|
||||||
procedure DragDrop(Source: TObject; X, Y: Integer); override;
|
|
||||||
property OnDragMoveTab: TDragMoveTabEvent read FOnDragMoveTab write FOnDragMoveTab;
|
|
||||||
property OnCanDragMoveTab: TDragMoveTabQuery read FOnCanDragMoveTab write FOnCanDragMoveTab;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TSourceNotebook }
|
{ TSourceNotebook }
|
||||||
|
|
||||||
TSourceNotebook = class(TSourceEditorWindowInterface)
|
TSourceNotebook = class(TSourceEditorWindowInterface)
|
||||||
@ -565,7 +532,7 @@ type
|
|||||||
Shift: TShiftState; X, Y: Integer);
|
Shift: TShiftState; X, Y: Integer);
|
||||||
procedure StatusBarDblClick(Sender: TObject);
|
procedure StatusBarDblClick(Sender: TObject);
|
||||||
private
|
private
|
||||||
FNotebook: TSourceDragableNotebook;
|
FNotebook: TExtendedNotebook;
|
||||||
FBaseCaption: String;
|
FBaseCaption: String;
|
||||||
FIsClosing: Boolean;
|
FIsClosing: Boolean;
|
||||||
SrcPopUpMenu: TPopupMenu;
|
SrcPopUpMenu: TPopupMenu;
|
||||||
@ -711,9 +678,11 @@ type
|
|||||||
procedure NotebookMouseDown(Sender: TObject; Button: TMouseButton;
|
procedure NotebookMouseDown(Sender: TObject; Button: TMouseButton;
|
||||||
Shift: TShiftState; X,Y: Integer);
|
Shift: TShiftState; X,Y: Integer);
|
||||||
procedure NotebookDragTabMove(Sender, Source: TObject;
|
procedure NotebookDragTabMove(Sender, Source: TObject;
|
||||||
OldIndex, NewIndex: Integer; CopyDrag: Boolean);
|
OldIndex, NewIndex: Integer; CopyDrag: Boolean;
|
||||||
function NotebookCanDragTabMove(Sender, Source: TObject;
|
var Done: Boolean);
|
||||||
OldIndex, NewIndex: Integer; CopyDrag: Boolean): Boolean;
|
procedure NotebookCanDragTabMove(Sender, Source: TObject;
|
||||||
|
OldIndex, NewIndex: Integer; CopyDrag: Boolean;
|
||||||
|
var Accept: Boolean);
|
||||||
procedure NotebookDragOver(Sender, Source: TObject;
|
procedure NotebookDragOver(Sender, Source: TObject;
|
||||||
X,Y: Integer; State: TDragState; var Accept: Boolean);
|
X,Y: Integer; State: TDragState; var Accept: Boolean);
|
||||||
procedure NotebookEndDrag(Sender, Target: TObject; X,Y: Integer);
|
procedure NotebookEndDrag(Sender, Target: TObject; X,Y: Integer);
|
||||||
@ -4913,7 +4882,7 @@ Begin
|
|||||||
{$IFDEF IDE_MEM_CHECK}
|
{$IFDEF IDE_MEM_CHECK}
|
||||||
CheckHeapWrtMemCnt('[TSourceNotebook.CreateNotebook] A ');
|
CheckHeapWrtMemCnt('[TSourceNotebook.CreateNotebook] A ');
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
FNotebook := TSourceDragableNotebook.Create(self);
|
FNotebook := TExtendedNotebook.Create(self);
|
||||||
{$IFDEF IDE_DEBUG}
|
{$IFDEF IDE_DEBUG}
|
||||||
writeln('[TSourceNotebook.CreateNotebook] B');
|
writeln('[TSourceNotebook.CreateNotebook] B');
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
@ -4942,10 +4911,11 @@ Begin
|
|||||||
OnPageChanged := @NotebookPageChanged;
|
OnPageChanged := @NotebookPageChanged;
|
||||||
OnCloseTabClicked:=@CloseTabClicked;
|
OnCloseTabClicked:=@CloseTabClicked;
|
||||||
OnMouseDown:=@NotebookMouseDown;
|
OnMouseDown:=@NotebookMouseDown;
|
||||||
OnCanDragMoveTab := @NotebookCanDragTabMove;
|
TabDragMode := dmAutomatic;
|
||||||
OnDragOver := @NotebookDragOver;
|
OnTabDragOverEx := @NotebookCanDragTabMove;
|
||||||
OnEndDrag := @NotebookEndDrag;
|
OnTabDragDropEx := @NotebookDragTabMove;
|
||||||
OnDragMoveTab := @NotebookDragTabMove;
|
OnTabDragOver := @NotebookDragOver;
|
||||||
|
OnTabEndDrag := @NotebookEndDrag;
|
||||||
ShowHint:=true;
|
ShowHint:=true;
|
||||||
OnShowHint:=@NotebookShowTabHint;
|
OnShowHint:=@NotebookShowTabHint;
|
||||||
{$IFDEF IDE_DEBUG}
|
{$IFDEF IDE_DEBUG}
|
||||||
@ -5927,7 +5897,7 @@ begin
|
|||||||
inherited DragOver(Source, X, Y, State, Accept);
|
inherited DragOver(Source, X, Y, State, Accept);
|
||||||
if State = dsDragLeave then
|
if State = dsDragLeave then
|
||||||
FUpdateTabAndPageTimer.Enabled := True
|
FUpdateTabAndPageTimer.Enabled := True
|
||||||
else if Source is TSourceDragableNotebook then
|
else if Source is TExtendedNotebook then
|
||||||
FNotebook.ShowTabs := True;
|
FNotebook.ShowTabs := True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -6892,7 +6862,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSourceNotebook.NotebookDragTabMove(Sender, Source: TObject; OldIndex,
|
procedure TSourceNotebook.NotebookDragTabMove(Sender, Source: TObject; OldIndex,
|
||||||
NewIndex: Integer; CopyDrag: Boolean);
|
NewIndex: Integer; CopyDrag: Boolean; var Done: Boolean);
|
||||||
function SourceIndex: Integer;
|
function SourceIndex: Integer;
|
||||||
begin
|
begin
|
||||||
Result := Manager.SourceWindowCount - 1;
|
Result := Manager.SourceWindowCount - 1;
|
||||||
@ -6902,24 +6872,30 @@ procedure TSourceNotebook.NotebookDragTabMove(Sender, Source: TObject; OldIndex,
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
begin
|
begin
|
||||||
|
{$IFnDEF SingleSrcWindow}
|
||||||
If CopyDrag then begin
|
If CopyDrag then begin
|
||||||
Manager.SourceWindows[SourceIndex].CopyEditor
|
Manager.SourceWindows[SourceIndex].CopyEditor
|
||||||
(OldIndex, Manager.IndexOfSourceWindow(self), NewIndex);
|
(OldIndex, Manager.IndexOfSourceWindow(self), NewIndex);
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
|
{$ENDIF}
|
||||||
if (Source = FNotebook) then
|
if (Source = FNotebook) then
|
||||||
MoveEditor(OldIndex, NewIndex)
|
MoveEditor(OldIndex, NewIndex)
|
||||||
else begin
|
else begin
|
||||||
Manager.SourceWindows[SourceIndex].MoveEditor
|
Manager.SourceWindows[SourceIndex].MoveEditor
|
||||||
(OldIndex, Manager.IndexOfSourceWindow(self), NewIndex);
|
(OldIndex, Manager.IndexOfSourceWindow(self), NewIndex);
|
||||||
end;
|
end;
|
||||||
|
{$IFnDEF SingleSrcWindow}
|
||||||
end;
|
end;
|
||||||
|
{$ENDIF}
|
||||||
Manager.ActiveSourceWindow := self;
|
Manager.ActiveSourceWindow := self;
|
||||||
Manager.ShowActiveWindowOnTop(True);
|
Manager.ShowActiveWindowOnTop(True);
|
||||||
|
Done := True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSourceNotebook.NotebookCanDragTabMove(Sender, Source: TObject;
|
procedure TSourceNotebook.NotebookCanDragTabMove(Sender, Source: TObject;
|
||||||
OldIndex, NewIndex: Integer; CopyDrag: Boolean): Boolean;
|
OldIndex, NewIndex: Integer; CopyDrag: Boolean; var Accept: Boolean);
|
||||||
|
|
||||||
function SourceIndex: Integer;
|
function SourceIndex: Integer;
|
||||||
begin
|
begin
|
||||||
Result := Manager.SourceWindowCount - 1;
|
Result := Manager.SourceWindowCount - 1;
|
||||||
@ -6935,10 +6911,12 @@ begin
|
|||||||
Src := Manager.SourceWindows[SourceIndex];
|
Src := Manager.SourceWindows[SourceIndex];
|
||||||
NBHasSharedEditor := IndexOfEditorInShareWith
|
NBHasSharedEditor := IndexOfEditorInShareWith
|
||||||
(Src.FindSourceEditorWithPageIndex(OldIndex)) >= 0;
|
(Src.FindSourceEditorWithPageIndex(OldIndex)) >= 0;
|
||||||
|
{$IFnDEF SingleSrcWindow}
|
||||||
if CopyDrag then
|
if CopyDrag then
|
||||||
Result := (NewIndex >= 0) and (Source <> Sender) and (not NBHasSharedEditor)
|
Accept := (NewIndex >= 0) and (Source <> Sender) and (not NBHasSharedEditor)
|
||||||
else
|
else
|
||||||
Result := (NewIndex >= 0) and
|
{$ENDIF}
|
||||||
|
Accept := (NewIndex >= 0) and
|
||||||
((Source <> Sender) or (OldIndex <> NewIndex)) and
|
((Source <> Sender) or (OldIndex <> NewIndex)) and
|
||||||
((Source = Sender) or (not NBHasSharedEditor));
|
((Source = Sender) or (not NBHasSharedEditor));
|
||||||
end;
|
end;
|
||||||
@ -6949,7 +6927,7 @@ begin
|
|||||||
FUpdateTabAndPageTimer.Enabled := False;
|
FUpdateTabAndPageTimer.Enabled := False;
|
||||||
if State = dsDragLeave then
|
if State = dsDragLeave then
|
||||||
FUpdateTabAndPageTimer.Enabled := True
|
FUpdateTabAndPageTimer.Enabled := True
|
||||||
else if Source is TSourceDragableNotebook then
|
else if Source is TExtendedNotebook then
|
||||||
FNotebook.ShowTabs := True;
|
FNotebook.ShowTabs := True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -7562,313 +7540,6 @@ begin
|
|||||||
FreeThenNil(aWordCompletion);
|
FreeThenNil(aWordCompletion);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TSourceDragableNotebook }
|
|
||||||
|
|
||||||
procedure TSourceDragableNotebook.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
|
|
||||||
Y: Integer);
|
|
||||||
begin
|
|
||||||
InitDrag;
|
|
||||||
FTabDragged:=false;
|
|
||||||
inherited MouseDown(Button, Shift, X, Y);
|
|
||||||
FMouseDownTabIndex := TabIndexAtClientPos(Point(X,Y));
|
|
||||||
if (Button = mbLeft) and (FMouseDownTabIndex >= 0) then
|
|
||||||
BeginDrag(False);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TSourceDragableNotebook.MouseUp(Button: TMouseButton; Shift: TShiftState;
|
|
||||||
X, Y: Integer);
|
|
||||||
var
|
|
||||||
MouseUpTabIndex: LongInt;
|
|
||||||
begin
|
|
||||||
InitDrag;
|
|
||||||
inherited MouseUp(Button, Shift, X, Y);
|
|
||||||
if not FTabDragged then begin
|
|
||||||
// no drag => check for normal click and activate page
|
|
||||||
MouseUpTabIndex := TabIndexAtClientPos(Point(X,Y));
|
|
||||||
if (Button = mbLeft) and (FMouseDownTabIndex = MouseUpTabIndex) and
|
|
||||||
(FMouseDownTabIndex >= 0)
|
|
||||||
then
|
|
||||||
PageIndex:=MouseUpTabIndex;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TSourceDragableNotebook.DragOver(Source: TObject; X, Y: Integer; State: TDragState;
|
|
||||||
var Accept: Boolean);
|
|
||||||
var
|
|
||||||
TabIndex: Integer;
|
|
||||||
TabPos, LastRect, LastNRect, tmp: TRect;
|
|
||||||
LastIndex: Integer;
|
|
||||||
LastRight, NeedInvalidate: Boolean;
|
|
||||||
Ctrl: Boolean;
|
|
||||||
Src: TSourceDragableNotebook;
|
|
||||||
begin
|
|
||||||
inherited DragOver(Source, X, Y, State, Accept);
|
|
||||||
if (state = dsDragLeave) and (FDragOverIndex >= 0) then begin
|
|
||||||
tmp := FDragOverTabRect;
|
|
||||||
InvalidateRect(Handle, @tmp, false);
|
|
||||||
tmp := FDragNextToTabRect;
|
|
||||||
InvalidateRect(Handle, @tmp, false);
|
|
||||||
FDragOverIndex := -1;
|
|
||||||
end;
|
|
||||||
// currently limited to source=self => extendable to allow dragging tabs from other notebooks
|
|
||||||
if (Source is TSourceDragableNotebook) and
|
|
||||||
(TSourceDragableNotebook(Source).FMouseDownTabIndex >= 0)
|
|
||||||
then begin
|
|
||||||
{$IFnDEF SingleSrcWindow}
|
|
||||||
Ctrl := (GetKeyState(VK_CONTROL) and $8000)<>0;
|
|
||||||
{$ELSE}
|
|
||||||
Ctrl := false;
|
|
||||||
{$ENDIF}
|
|
||||||
if Ctrl then
|
|
||||||
DragCursor := crMultiDrag
|
|
||||||
else
|
|
||||||
DragCursor := crDrag;
|
|
||||||
|
|
||||||
|
|
||||||
TabIndex := TabIndexAtClientPos(Point(X,Y));
|
|
||||||
if TabIndex < 0 then begin
|
|
||||||
TabPos := TabRect(PageCount-1);
|
|
||||||
if (TabPos.Right > 1) and (X > TabPos.Left) then
|
|
||||||
TabIndex := PageCount - 1;
|
|
||||||
end;
|
|
||||||
if TabIndex < 0 then begin
|
|
||||||
Accept := False;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
LastIndex := FDragOverIndex;
|
|
||||||
LastRight := FDragToRightSide;
|
|
||||||
LastRect := FDragOverTabRect;
|
|
||||||
LastNRect := FDragNextToTabRect;
|
|
||||||
FDragOverIndex := TabIndex;
|
|
||||||
FDragOverTabRect := TabRect(TabIndex);
|
|
||||||
|
|
||||||
if (TabPosition in [tpLeft, tpRight]) then
|
|
||||||
// Drag-To-Bottom/Lower
|
|
||||||
FDragToRightSide := Y > (FDragOverTabRect.Top + FDragOverTabRect.Bottom) div 2
|
|
||||||
else
|
|
||||||
FDragToRightSide := X > (FDragOverTabRect.Left + FDragOverTabRect.Right) div 2;
|
|
||||||
|
|
||||||
if (Source = Self) and (TabIndex = FMouseDownTabIndex - 1) then
|
|
||||||
FDragToRightSide := False;
|
|
||||||
if (Source = Self) and (TabIndex = FMouseDownTabIndex + 1) then
|
|
||||||
FDragToRightSide := True;
|
|
||||||
|
|
||||||
NeedInvalidate := (FDragOverIndex <> LastIndex) or (FDragToRightSide <> LastRight);
|
|
||||||
if NeedInvalidate then begin
|
|
||||||
InvalidateRect(Handle, @LastRect, false);
|
|
||||||
InvalidateRect(Handle, @LastNRect, false);
|
|
||||||
tmp := FDragOverTabRect;
|
|
||||||
InvalidateRect(Handle, @tmp, false);
|
|
||||||
tmp := FDragNextToTabRect;
|
|
||||||
InvalidateRect(Handle, @tmp, false);
|
|
||||||
end;
|
|
||||||
|
|
||||||
if FDragToRightSide then begin
|
|
||||||
inc(TabIndex);
|
|
||||||
if TabIndex < PageCount then
|
|
||||||
FDragNextToTabRect := TabRect(TabIndex);
|
|
||||||
end else begin
|
|
||||||
if TabIndex > 0 then
|
|
||||||
FDragNextToTabRect := TabRect(TabIndex - 1);
|
|
||||||
end;
|
|
||||||
if NeedInvalidate then begin
|
|
||||||
tmp := FDragNextToTabRect;
|
|
||||||
InvalidateRect(Handle, @tmp, false);
|
|
||||||
end;
|
|
||||||
|
|
||||||
Src := TSourceDragableNotebook(Source);
|
|
||||||
if (Source = self) and (TabIndex > Src.MouseDownTabIndex) then
|
|
||||||
dec(TabIndex);
|
|
||||||
|
|
||||||
Accept := OnCanDragMoveTab(Self, Source, Src.MouseDownTabIndex, TabIndex, Ctrl);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
FDragOverIndex := -1;
|
|
||||||
if (not Accept) or (state = dsDragLeave) then
|
|
||||||
FDragOverIndex := -1;
|
|
||||||
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TSourceDragableNotebook.DragCanceled;
|
|
||||||
var
|
|
||||||
tmp: TRect;
|
|
||||||
begin
|
|
||||||
inherited DragCanceled;
|
|
||||||
if (FDragOverIndex >= 0) then begin
|
|
||||||
tmp := FDragOverTabRect;
|
|
||||||
InvalidateRect(Handle, @tmp, false);
|
|
||||||
tmp := FDragNextToTabRect;
|
|
||||||
InvalidateRect(Handle, @tmp, false);
|
|
||||||
end;
|
|
||||||
FDragOverIndex := -1;
|
|
||||||
DragCursor := crDrag;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TSourceDragableNotebook.PaintWindow(DC: HDC);
|
|
||||||
var
|
|
||||||
Points: Array [0..3] of TPoint;
|
|
||||||
|
|
||||||
procedure DrawLeftArrow(ARect: TRect);
|
|
||||||
var y, h: Integer;
|
|
||||||
begin
|
|
||||||
h := Min( (Abs(ARect.Bottom - ARect.Top) - 4) div 2,
|
|
||||||
(Abs(ARect.Left - ARect.Right) - 4) div 2 );
|
|
||||||
y := (ARect.Top + ARect.Bottom) div 2;
|
|
||||||
Points[0].X := ARect.Left + 2 + h;
|
|
||||||
Points[0].y := y - h;
|
|
||||||
Points[1].X := ARect.Left + 2 + h;
|
|
||||||
Points[1].y := y + h;
|
|
||||||
Points[2].X := ARect.Left + 2;
|
|
||||||
Points[2].y := y;
|
|
||||||
Points[3] := Points[0];
|
|
||||||
Polygon(DC, @Points, 4, False);
|
|
||||||
end;
|
|
||||||
procedure DrawRightArrow(ARect: TRect);
|
|
||||||
var y, h: Integer;
|
|
||||||
begin
|
|
||||||
h := Min( (Abs(ARect.Bottom - ARect.Top) - 4) div 2,
|
|
||||||
(Abs(ARect.Left - ARect.Right) - 4) div 2 );
|
|
||||||
y := (ARect.Top + ARect.Bottom) div 2;
|
|
||||||
Points[0].X := ARect.Right - 2 - h;
|
|
||||||
Points[0].y := y - h;
|
|
||||||
Points[1].X := ARect.Right - 2 - h;
|
|
||||||
Points[1].y := y + h;
|
|
||||||
Points[2].X := ARect.Right - 2;
|
|
||||||
Points[2].y := y;
|
|
||||||
Points[3] := Points[0];
|
|
||||||
Polygon(DC, @Points, 4, False);
|
|
||||||
end;
|
|
||||||
procedure DrawTopArrow(ARect: TRect);
|
|
||||||
var x, h: Integer;
|
|
||||||
begin
|
|
||||||
h := Min( (Abs(ARect.Bottom - ARect.Top) - 4) div 2,
|
|
||||||
(Abs(ARect.Left - ARect.Right) - 4) div 2 );
|
|
||||||
x := (ARect.Left + ARect.Right) div 2;
|
|
||||||
Points[0].Y := ARect.Top + 2 + h;
|
|
||||||
Points[0].X := x - h;
|
|
||||||
Points[1].Y := ARect.Top + 2 + h;
|
|
||||||
Points[1].X := x + h;
|
|
||||||
Points[2].Y := ARect.Top + 2;
|
|
||||||
Points[2].X := x;
|
|
||||||
Points[3] := Points[0];
|
|
||||||
Polygon(DC, @Points, 4, False);
|
|
||||||
end;
|
|
||||||
procedure DrawBottomArrow(ARect: TRect);
|
|
||||||
var x, h: Integer;
|
|
||||||
begin
|
|
||||||
h := Min( (Abs(ARect.Bottom - ARect.Top) - 4) div 2,
|
|
||||||
(Abs(ARect.Left - ARect.Right) - 4) div 2 );
|
|
||||||
x := (ARect.Left + ARect.Right) div 2;
|
|
||||||
Points[0].Y := ARect.Bottom - 2 - h;
|
|
||||||
Points[0].X := X - h;
|
|
||||||
Points[1].Y := ARect.Bottom - 2 - h;
|
|
||||||
Points[1].X := X + h;
|
|
||||||
Points[2].Y := ARect.Bottom - 2;
|
|
||||||
Points[2].X := X;
|
|
||||||
Points[3] := Points[0];
|
|
||||||
Polygon(DC, @Points, 4, False);
|
|
||||||
end;
|
|
||||||
|
|
||||||
begin
|
|
||||||
inherited PaintWindow(DC);
|
|
||||||
if FDragOverIndex < 0 then exit;
|
|
||||||
|
|
||||||
if (TabPosition in [tpLeft, tpRight]) then begin
|
|
||||||
if FDragToRightSide then begin
|
|
||||||
DrawBottomArrow(FDragOverTabRect);
|
|
||||||
if (FDragOverIndex < PageCount - 1) then
|
|
||||||
DrawTopArrow(FDragNextToTabRect);
|
|
||||||
end else begin
|
|
||||||
DrawTopArrow(FDragOverTabRect);
|
|
||||||
if (FDragOverIndex > 0) then
|
|
||||||
DrawBottomArrow(FDragNextToTabRect);
|
|
||||||
end;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
if FDragToRightSide then begin
|
|
||||||
DrawRightArrow(FDragOverTabRect);
|
|
||||||
if (FDragOverIndex < PageCount - 1) then
|
|
||||||
DrawLeftArrow(FDragNextToTabRect);
|
|
||||||
end else begin
|
|
||||||
DrawLeftArrow(FDragOverTabRect);
|
|
||||||
if (FDragOverIndex > 0) then
|
|
||||||
DrawRightArrow(FDragNextToTabRect);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TSourceDragableNotebook.InitDrag;
|
|
||||||
begin
|
|
||||||
DragCursor := crDrag;
|
|
||||||
FDragOverIndex := -1;
|
|
||||||
FDragOverTabRect := Rect(0, 0, 0, 0);
|
|
||||||
FDragNextToTabRect := Rect(0, 0, 0, 0);
|
|
||||||
end;
|
|
||||||
|
|
||||||
constructor TSourceDragableNotebook.Create(TheOwner: TComponent);
|
|
||||||
begin
|
|
||||||
inherited Create(TheOwner);
|
|
||||||
InitDrag;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TSourceDragableNotebook.DragDrop(Source: TObject; X, Y: Integer);
|
|
||||||
var
|
|
||||||
TabIndex: Integer;
|
|
||||||
TabPos, tmp: TRect;
|
|
||||||
ToRight: Boolean;
|
|
||||||
Ctrl: Boolean;
|
|
||||||
Src: TSourceDragableNotebook;
|
|
||||||
begin
|
|
||||||
inherited DragDrop(Source, X, Y);
|
|
||||||
if (FDragOverIndex >= 0) then begin
|
|
||||||
tmp := FDragOverTabRect;
|
|
||||||
InvalidateRect(Handle, @tmp, false);
|
|
||||||
tmp := FDragNextToTabRect;
|
|
||||||
InvalidateRect(Handle, @tmp, false);
|
|
||||||
end;
|
|
||||||
FDragOverIndex := -1;
|
|
||||||
DragCursor := crDrag;
|
|
||||||
|
|
||||||
if assigned(FOnDragMoveTab) and (Source is TSourceDragableNotebook) and
|
|
||||||
(TSourceDragableNotebook(Source).MouseDownTabIndex >= 0)
|
|
||||||
then begin
|
|
||||||
{$IFnDEF SingleSrcWindow}
|
|
||||||
Ctrl := (GetKeyState(VK_CONTROL) and $8000)<>0;
|
|
||||||
{$ELSE}
|
|
||||||
Ctrl := false;
|
|
||||||
{$ENDIF}
|
|
||||||
|
|
||||||
TabIndex := TabIndexAtClientPos(Point(X,Y));
|
|
||||||
if TabIndex < 0 then begin
|
|
||||||
TabPos := TabRect(PageCount-1);
|
|
||||||
if (TabPos.Right > 1) and (X > TabPos.Left) then
|
|
||||||
TabIndex := PageCount - 1;
|
|
||||||
end;
|
|
||||||
TabPos := TabRect(TabIndex);
|
|
||||||
|
|
||||||
ToRight := X > (TabPos.Left + TabPos.Right) div 2;
|
|
||||||
if (Source = Self) and (TabIndex = FMouseDownTabIndex - 1) then
|
|
||||||
ToRight := False;
|
|
||||||
if (Source = Self) and (TabIndex = FMouseDownTabIndex + 1) then
|
|
||||||
ToRight := True;
|
|
||||||
if ToRight then
|
|
||||||
inc(TabIndex);
|
|
||||||
|
|
||||||
Src := TSourceDragableNotebook(Source);
|
|
||||||
// includes unknown
|
|
||||||
if (Source = self) and (TabIndex > Src.MouseDownTabIndex) then
|
|
||||||
dec(TabIndex);
|
|
||||||
if OnCanDragMoveTab(Self, Source, Src.MouseDownTabIndex, TabIndex, Ctrl) then
|
|
||||||
begin
|
|
||||||
FTabDragged:=true;
|
|
||||||
FOnDragMoveTab(Self, Source, Src.MouseDownTabIndex, TabIndex, Ctrl);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TSourceEditorManagerBase }
|
{ TSourceEditorManagerBase }
|
||||||
|
|
||||||
procedure TSourceEditorManagerBase.FreeSourceWindows;
|
procedure TSourceEditorManagerBase.FreeSourceWindows;
|
||||||
|
Loading…
Reference in New Issue
Block a user