📄 jvdockvsnetstyle.pas
字号:
//=== { TJvDockVSBlock } =====================================================
constructor TJvDockVSBlock.Create(Owner: TJvDockVSChannel);
begin
inherited Create;
FVSChannel := Owner;
FVSPaneList := TList.Create;
FImageList := TImageList.CreateSize(16, 16);
FInactiveBlockWidth := 24;
FActiveBlockWidth := 24;
end;
destructor TJvDockVSBlock.Destroy;
var
I: Integer;
begin
FImageList.Free;
for I := 0 to VSPaneCount - 1 do
VSPanes[I].Free;
FVSPaneList.Free;
inherited Destroy;
end;
procedure TJvDockVSBlock.AddDockControl(Control: TWinControl);
var
I, PaneWidth, FirstIndex: Integer;
function GetPaneWidth: Integer;
begin
Result := 100;
if Control = nil then
Exit;
case VSChannel.Align of
alLeft, alRight:
Result := Control.Width;
alTop, alBottom:
Result := Control.Height;
end;
end;
begin
PaneWidth := GetPaneWidth;
if Control is TJvDockTabHostForm then
begin
FBlockType := btTabBlock;
with TJvDockTabHostForm(Control) do
begin
FirstIndex := FVSPaneList.Count;
for I := 0 to DockableControl.DockClientCount - 1 do
begin
AddPane(PageControl.DockClients[I], PaneWidth);
TJvDockVSNETTabSheet(PageControl.Pages[I]).OldVisible := PageControl.DockClients[I].Visible;
if PageControl.Pages[I] <> PageControl.ActivePage then
PageControl.DockClients[I].Visible := False;
end;
UpdateActiveDockControl(FirstIndex);
end;
end
else
begin
FBlockType := btConjoinBlock;
AddPane(Control, PaneWidth);
ActiveDockControl := Control;
end;
ResetActiveBlockWidth;
end;
procedure TJvDockVSBlock.AddPane(AControl: TControl; const AWidth: Integer);
var
Icon: TIcon;
ADockClient: TJvDockClient;
begin
{ Dangerous? cast }
FVSPaneList.Add(TJvDockVSPane.Create(Self, TForm(AControl), AWidth, FVSPaneList.Count));
if not JvGlobalDockIsLoading then
begin
ADockClient := FindDockClient(AControl);
if ADockClient <> nil then
ADockClient.VSPaneWidth := AWidth;
end;
{ Add the form icon }
if TForm(AControl).Icon = nil then
begin
Icon := TIcon.Create;
Icon.Width := 16;
Icon.Height := 16;
FImageList.AddIcon(Icon);
Icon.Free;
end
else
FImageList.AddIcon(TForm(AControl).Icon);
end;
procedure TJvDockVSBlock.DeletePane(Index: Integer);
var
I: Integer;
ActiveDockControlRemoved: Boolean;
begin
for I := Index to FVSPaneList.Count - 2 do
VSPanes[I + 1].FIndex := VSPanes[I].FIndex;
ActiveDockControlRemoved := VSPanes[Index].FDockForm = Self.ActiveDockControl;
VSPanes[Index].Free;
FVSPaneList.Delete(Index);
{ Remove the form icon }
if Index < FImageList.Count then
FImageList.Delete(Index);
if ActiveDockControlRemoved then
UpdateActiveDockControl(Index);
end;
function TJvDockVSBlock.GetTotalWidth: Integer;
begin
Result := (FVSPaneList.Count - 1) * FInactiveBlockWidth + FActiveBlockWidth;
end;
function TJvDockVSBlock.GetVSPane(Index: Integer): TJvDockVSPane;
begin
Result := TJvDockVSPane(FVSPaneList[Index]);
end;
function TJvDockVSBlock.GetVSPaneCount: Integer;
begin
Result := FVSPaneList.Count;
end;
procedure TJvDockVSBlock.RemoveDockControl(Control: TWinControl);
begin
ResetActiveBlockWidth;
end;
procedure TJvDockVSBlock.ResetActiveBlockWidth;
var
I: Integer;
begin
for I := 0 to VSPaneCount - 1 do
FActiveBlockWidth := Max(FActiveBlockWidth, Min(VSChannel.ActivePaneSize,
TForm(VSChannel.Parent).Canvas.TextWidth(VSPanes[I].FDockForm.Caption) + InactiveBlockWidth + 10));
end;
procedure TJvDockVSBlock.SetActiveDockControl(ADockControl: TWinControl);
begin
if FActiveDockControl <> ADockControl then
begin
FActiveDockControl := ADockControl;
VSChannel.Invalidate;
end;
end;
procedure TJvDockVSBlock.UpdateActiveDockControl(StartIndex: Integer);
var
I: Integer;
begin
{ Start looking at position StartIndex for a visible pane }
for I := 0 to VSPaneCount - 1 do
if VSPanes[(I + StartIndex) mod VSPaneCount].FVisible then
begin
ActiveDockControl := VSPanes[(I + StartIndex) mod VSPaneCount].FDockForm;
Break;
end;
end;
//=== { TJvDockVSChannel } ===================================================
constructor TJvDockVSChannel.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
if AOwner is TJvDockVSNETPanel then
begin
FVSNETDockPanel := TJvDockVSNETPanel(AOwner);
DockServer := FVSNETDockPanel.DockServer;
end;
FBlockList := TList.Create;
FChannelWidth := 22;
FBlockStartOffset := 2;
FBlockUpOffset := 2;
FBlockInterval := 13;
Color := VSNETPageInactiveSheetColor;
ParentFont := True;
ActivePaneSize := MaxActivePaneWidth;
FActiveDockForm := nil;
end;
destructor TJvDockVSChannel.Destroy;
begin
if Assigned(GlobalPopupPanelAnimate) and (GlobalPopupPanelAnimate.FVSChannel = Self) then
begin
GlobalPopupPanelAnimate.Free;
GlobalPopupPanelAnimate := nil;
end;
FreeBlockList;
FAnimationStartTimer.Free;
inherited Destroy;
end;
procedure TJvDockVSChannel.AddDockControl(Control: TWinControl);
var
Block: TJvDockVSBlock;
begin
if Control is TJvDockTabHostForm then
begin
Block := TJvDockVSBlock.Create(Self);
Block.AddDockControl(Control);
FBlockList.Add(Block);
end
else
begin
if (BlockCount >= 1) and (Blocks[0].BlockType = btConjoinBlock) then
Blocks[0].AddDockControl(Control)
else
begin
Block := TJvDockVSBlock.Create(Self);
Block.AddDockControl(Control);
FBlockList.Insert(0, Block);
end;
end;
HideAllPopupPanel(Self);
ResetPosition;
Invalidate;
end;
procedure TJvDockVSChannel.AnimatePopupPanel(AnimateStyle: TJvDockPoppupPanelAnimateStyle);
begin
if AnimateStyle = pasShow then
begin
end
else
if AnimateStyle = pasHide then
begin
end;
end;
procedure TJvDockVSChannel.AnimationStartTimerOnTimerHandler(Sender: TObject);
var
CursorPos: TPoint;
begin
// Show the form only if the cursor is still above the same pane
try
GetCursorPos(CursorPos);
CursorPos := Self.ScreenToClient(CursorPos);
if GetDockFormWithMousePos(Point(CursorPos.X, CursorPos.Y)) = Pointer(FAnimationStartTimer.Tag) then
PopupDockForm(TJvDockVSPane(Pointer(FAnimationStartTimer.Tag)));
finally
FAnimationStartTimer.Free;
FAnimationStartTimer := nil;
end;
end;
procedure TJvDockVSChannel.CMMouseLeave(var Msg: TMessage);
begin
inherited;
end;
procedure TJvDockVSChannel.CreateVSPopupPanel(DockStyle: TComponent);
begin
Assert(Assigned(DockStyle));
FVSPopupPanel := TJvDockVSPopupPanel.Create(FVSNETDockPanel);
{ Channel is maintainer/Creator }
FVSPopupPanel.FreeNotification(Self);
FVSPopupPanel.Name := FVSNETDockPanel.Name + '_PopupPanel';
FVSPopupPanel.Visible := False;
if Parent is TForm then
begin
FVSPopupPanel.Parent := Parent;
FVSPopupPanel.Align := alNone;
FVSPopupPanel.BringToFront;
end;
FVSPopupPanelSplitter := TJvDockVSPopupPanelSplitter.Create(Parent);
{ Channel is maintainer/Creator }
FVSPopupPanelSplitter.FreeNotification(Self);
if Parent is TForm then
begin
FVSPopupPanelSplitter.Parent := Parent;
FVSPopupPanelSplitter.Align := alNone;
FVSPopupPanelSplitter.VSPopupPanel := VSPopupPanel;
FVSPopupPanelSplitter.Color := clBtnFace;
FVSPopupPanelSplitter.Visible := False;
end;
end;
procedure TJvDockVSChannel.DeleteBlock(Index: Integer);
begin
Blocks[Index].Free;
FBlockList.Delete(Index);
end;
procedure TJvDockVSChannel.DestroyVSPopupPanel;
begin
FreeAndNil(FVSPopupPanel);
FreeAndNil(FVSPopupPanelSplitter);
end;
function TJvDockVSChannel.FindDockControl(Control: TWinControl;
var BlockIndex: Integer; var PaneIndex: Integer): Boolean;
var
I, J: Integer;
begin
Result := False;
BlockIndex := -1;
PaneIndex := -1;
if Control = nil then
Exit;
for I := 0 to BlockCount - 1 do
begin
for J := 0 to Blocks[I].VSPaneCount - 1 do
if Blocks[I].VSPanes[J].FDockForm = Control then
begin
BlockIndex := I;
PaneIndex := J;
Result := True;
Exit;
end;
if Blocks[I].FBlockType = btTabBlock then
begin
J := 0;
if Blocks[I].VSPanes[0].FDockForm.HostDockSite.Parent = Control then
begin
BlockIndex := I;
PaneIndex := J;
Result := True;
Exit;
end;
end;
end;
end;
function TJvDockVSChannel.FindPane(Control: TWinControl): TJvDockVSPane;
var
I, J: Integer;
begin
Result := nil;
if FindDockControl(Control, I, J) then
Result := Blocks[I].VSPanes[J];
end;
procedure TJvDockVSChannel.FreeBlockList;
var
I: Integer;
begin
for I := 0 to FBlockList.Count - 1 do
Blocks[I].Free;
FreeAndNil(FBlockList);
end;
function TJvDockVSChannel.GetBlockCount: Integer;
begin
Result := FBlockList.Count;
end;
procedure TJvDockVSChannel.GetBlockRect(Block: TJvDockVSBlock; Index: Integer;
var ARect: TRect);
var
BlockWidth: Integer;
begin
if Block.VSPanes[Index].FDockForm <> Block.FActiveDockControl then
BlockWidth := Block.InactiveBlockWidth
else
BlockWidth := Block.ActiveBlockWidth;
case Align of
alLeft:
begin
ARect.Left := -1;
ARect.Top := FCurrentPos;
ARect.Right := Width - FBlockUpOffset;
ARect.Bottom := ARect.Top + BlockWidth;
end;
alRight:
begin
ARect.Left := FBlockUpOffset;
ARect.Top := FCurrentPos;
ARect.Right := Width + 1;
ARect.Bottom := ARect.Top + BlockWidth;
end;
alTop:
begin
ARect.Left := FCurrentPos;
ARect.Top := -1;
ARect.Right := ARect.Left + BlockWidth;
ARect.Bottom := Height - FBlockUpOffset;
end;
alBottom:
begin
ARect.Left := FCurrentPos;
ARect.Top := FBlockUpOffset;
ARect.Right := ARect.Left + BlockWidth;
ARect.Bottom := Height + 1;
end;
end;
Inc(FCurrentPos, BlockWidth - 1);
end;
function TJvDockVSChannel.GetBlocks(Index: Integer): TJvDockVSBlock;
begin
Result := TJvDockVSBlock(FBlockList[Index]);
end;
function TJvDockVSChannel.GetDockFormWithMousePos(MousePos: TPoint): TJvDockVSPane;
var
I, J: Integer;
ARect: TRect;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -