designer: start drawing and selection of inlined non-visual components (todo: control selection)

git-svn-id: trunk@22795 -
This commit is contained in:
paul 2009-11-26 10:39:57 +00:00
parent bea12e9550
commit c1fdc5e879

View File

@ -254,7 +254,7 @@ type
var Handled: boolean); var Handled: boolean);
function NonVisualComponentLeftTop(AComponent: TComponent): TPoint; function NonVisualComponentLeftTop(AComponent: TComponent): TPoint;
function NonVisualComponentAtPos(x,y: integer): TComponent; function NonVisualComponentAtPos(X, Y: integer): TComponent;
procedure MoveNonVisualComponentIntoForm(AComponent: TComponent); procedure MoveNonVisualComponentIntoForm(AComponent: TComponent);
procedure MoveNonVisualComponentsIntoForm; procedure MoveNonVisualComponentsIntoForm;
function WinControlAtPos(x,y: integer; UseRootAsDefault, function WinControlAtPos(x,y: integer; UseRootAsDefault,
@ -1327,6 +1327,16 @@ function TDesigner.NonVisualComponentLeftTop(AComponent: TComponent): TPoint;
begin begin
Result.X := LeftFromDesignInfo(AComponent.DesignInfo); Result.X := LeftFromDesignInfo(AComponent.DesignInfo);
Result.Y := TopFromDesignInfo(AComponent.DesignInfo); Result.Y := TopFromDesignInfo(AComponent.DesignInfo);
// convert to owner coords
while AComponent.Owner <> FLookupRoot do
begin
AComponent := AComponent.Owner;
if AComponent is TControl then
begin
inc(Result.X, TControl(AComponent).Left);
inc(Result.Y, TControl(AComponent).Top);
end;
end;
end; end;
procedure TDesigner.InvalidateWithParent(AComponent: TComponent); procedure TDesigner.InvalidateWithParent(AComponent: TComponent);
@ -2876,93 +2886,109 @@ end;
procedure TDesigner.DrawNonVisualComponents(aDDC: TDesignerDeviceContext); procedure TDesigner.DrawNonVisualComponents(aDDC: TDesignerDeviceContext);
var var
AComponent: TComponent; Surface: TBitmap;
Icon, Surface: TBitmap;
i, ItemLeft, ItemTop, ItemRight, ItemBottom: integer; procedure DrawComponent(AComponent: TComponent);
Diff, ItemLeftTop: TPoint; var
IconRect, TextRect: TRect; Icon: TBitmap;
TextSize: TSize; ItemLeft, ItemTop, ItemRight, ItemBottom: integer;
IsSelected: Boolean; Diff, ItemLeftTop: TPoint;
begin IconRect, TextRect: TRect;
Surface := nil; TextSize: TSize;
for i := 0 to FLookupRoot.ComponentCount - 1 do IsSelected: Boolean;
begin begin
AComponent := FLookupRoot.Components[i]; Diff := aDDC.FormOrigin;
if ComponentIsIcon(AComponent) then //DebugLn(['aDDC.FormOrigin - ', Diff.X, ' : ' ,Diff.Y]);
// non-visual component
ItemLeftTop := NonVisualComponentLeftTop(AComponent);
ItemLeft := ItemLeftTop.X - Diff.X;
ItemTop := ItemLeftTop.Y - Diff.Y;
ItemRight := ItemLeft + NonVisualCompWidth;
ItemBottom := ItemTop + NonVisualCompWidth;
if not aDDC.RectVisible(ItemLeft, ItemTop, ItemRight, ItemBottom) then
Exit;
IsSelected := ControlSelection.IsSelected(AComponent);
aDDC.Save;
if Surface = nil then
begin begin
Diff := aDDC.FormOrigin; Surface := TBitmap.Create;
//DebugLn(['aDDC.FormOrigin - ', Diff.X, ' : ' ,Diff.Y]); Surface.SetSize(NonVisualCompWidth, NonVisualCompWidth);
// non-visual component Surface.Canvas.Brush.Color := clBtnFace;
ItemLeftTop := NonVisualComponentLeftTop(AComponent); Surface.Canvas.Pen.Width := 1;
ItemLeft := ItemLeftTop.X - Diff.X; end;
ItemTop := ItemLeftTop.Y - Diff.Y;
ItemRight := ItemLeft + NonVisualCompWidth;
ItemBottom := ItemTop + NonVisualCompWidth;
if not aDDC.RectVisible(ItemLeft, ItemTop, ItemRight, ItemBottom) then
Continue;
IsSelected := ControlSelection.IsSelected(AComponent); IconRect := Rect(0, 0, NonVisualCompWidth, NonVisualCompWidth);
aDDC.Save; Surface.Canvas.Frame3D(IconRect, 1, bvRaised);
if Surface = nil then Surface.Canvas.FillRect(IconRect);
begin if NonVisualCompBorder > 1 then
Surface := TBitmap.Create; InflateRect(IconRect, -NonVisualCompBorder + 1, -NonVisualCompBorder + 1);
Surface.SetSize(NonVisualCompWidth, NonVisualCompWidth);
Surface.Canvas.Brush.Color := clBtnFace;
Surface.Canvas.Pen.Width := 1;
end;
IconRect := Rect(0, 0, NonVisualCompWidth, NonVisualCompWidth); // draw component Name
Surface.Canvas.Frame3D(IconRect, 1, bvRaised); if ShowComponentCaptions and (((GetKeyState(VK_LBUTTON) and $80) = 0) or not IsSelected) then
Surface.Canvas.FillRect(IconRect); begin
if NonVisualCompBorder > 1 then // workarounds gtk2 problem with DrawText on gc with GDK_INCLUDE_INFERIORS
InflateRect(IconRect, -NonVisualCompBorder + 1, -NonVisualCompBorder + 1); // it uses pango drawing and this for some reason does not take subwindow_mode
// into account
Icon := TBitmap.Create;
try
TextSize := aDDC.Canvas.TextExtent(AComponent.Name);
Icon.SetSize(TextSize.cx, TextSize.cy);
TextRect := Rect(0, 0, TextSize.cx, TextSize.cy);
if aDDC.Form <> nil then
Icon.Canvas.Brush.Color := aDDC.Form.Canvas.Brush.Color
else
Icon.Canvas.Brush.Color := clBtnFace;
Icon.Canvas.FillRect(TextRect);
DrawText(Icon.Canvas.Handle, PChar(AComponent.Name), -1, TextRect,
DT_CENTER or DT_VCENTER or DT_SINGLELINE or DT_NOCLIP);
aDDC.Canvas.Draw(
(ItemLeft + ItemRight - TextSize.cx) div 2,
ItemBottom + NonVisualCompBorder + 2, Icon);
finally
Icon.Free;
end;
end;
// draw component icon
if Assigned(FOnGetNonVisualCompIcon) then
begin
Icon := nil;
FOnGetNonVisualCompIcon(Self, AComponent, Icon);
if Icon <> nil then
begin
inc(IconRect.Left, (NonVisualCompIconWidth - Icon.Width) div 2);
inc(IconRect.Top, (NonVisualCompIconWidth - Icon.Height) div 2);
IconRect.Right := IconRect.Left + Icon.Width;
IconRect.Bottom := IconRect.Top + Icon.Height;
Surface.Canvas.StretchDraw(IconRect, Icon);
end;
end;
aDDC.Canvas.Draw(ItemLeft, ItemTop, Surface);
if (ControlSelection.Count > 1) and IsSelected then
ControlSelection.DrawMarkerAt(aDDC,
ItemLeft, ItemTop, NonVisualCompWidth, NonVisualCompWidth);
aDDC.Restore;
end;
// draw component Name procedure TraverseComponents(ALookupRoot: TComponent);
if ShowComponentCaptions and (((GetKeyState(VK_LBUTTON) and $80) = 0) or not IsSelected) then var
begin i: integer;
// workarounds gtk2 problem with DrawText on gc with GDK_INCLUDE_INFERIORS AComponent: TComponent;
// it uses pango drawing and this for some reason does not take subwindow_mode begin
// into account for i := 0 to ALookupRoot.ComponentCount - 1 do
Icon := TBitmap.Create; begin
try AComponent := ALookupRoot.Components[i];
TextSize := aDDC.Canvas.TextExtent(AComponent.Name); if csInline in AComponent.ComponentState then
Icon.SetSize(TextSize.cx, TextSize.cy); TraverseComponents(AComponent)
TextRect := Rect(0, 0, TextSize.cx, TextSize.cy); else
if aDDC.Form <> nil then if ComponentIsIcon(AComponent) then
Icon.Canvas.Brush.Color := aDDC.Form.Canvas.Brush.Color DrawComponent(AComponent);
else
Icon.Canvas.Brush.Color := clBtnFace;
Icon.Canvas.FillRect(TextRect);
DrawText(Icon.Canvas.Handle, PChar(AComponent.Name), -1, TextRect,
DT_CENTER or DT_VCENTER or DT_SINGLELINE or DT_NOCLIP);
aDDC.Canvas.Draw(
(ItemLeft + ItemRight - TextSize.cx) div 2,
ItemBottom + NonVisualCompBorder + 2, Icon);
finally
Icon.Free;
end;
end;
// draw component icon
if Assigned(FOnGetNonVisualCompIcon) then
begin
Icon := nil;
FOnGetNonVisualCompIcon(Self, AComponent, Icon);
if Icon <> nil then
begin
inc(IconRect.Left, (NonVisualCompIconWidth - Icon.Width) div 2);
inc(IconRect.Top, (NonVisualCompIconWidth - Icon.Height) div 2);
IconRect.Right := IconRect.Left + Icon.Width;
IconRect.Bottom := IconRect.Top + Icon.Height;
Surface.Canvas.StretchDraw(IconRect, Icon);
end;
end;
aDDC.Canvas.Draw(ItemLeft, ItemTop, Surface);
if (ControlSelection.Count > 1) and IsSelected then
ControlSelection.DrawMarkerAt(aDDC,
ItemLeft, ItemTop, NonVisualCompWidth, NonVisualCompWidth);
aDDC.Restore;
end; end;
end; end;
begin
Surface := nil;
TraverseComponents(FLookupRoot);
if Surface <> nil then if Surface <> nil then
Surface.Free; Surface.Free;
end; end;
@ -3104,29 +3130,59 @@ begin
end; end;
end; end;
function TDesigner.NonVisualComponentAtPos(x,y: integer): TComponent; function TDesigner.NonVisualComponentAtPos(X, Y: integer): TComponent;
var i: integer;
LeftTop: TPoint; function TraverseComponents(ALookupRoot: TComponent): TComponent;
begin var
for i:=FLookupRoot.ComponentCount-1 downto 0 do begin i: integer;
Result:=FLookupRoot.Components[i]; LeftTop: TPoint;
if ComponentIsIcon(Result) then begin begin
with Result do begin for i := ALookupRoot.ComponentCount - 1 downto 0 do
LeftTop:=NonVisualComponentLeftTop(Result); begin
if (LeftTop.x<=x) and (LeftTop.y<=y) Result := ALookupRoot.Components[i];
and (LeftTop.x+NonVisualCompWidth>x) if csInline in Result.ComponentState then
and (LeftTop.y+NonVisualCompWidth>y) then begin
exit; Result := TraverseComponents(Result);
if Result <> nil then
Exit;
end
else
if ComponentIsIcon(Result) then
begin
with Result do
begin
LeftTop := NonVisualComponentLeftTop(Result);
if (LeftTop.x <= x) and (LeftTop.y <= y) and
(LeftTop.x + NonVisualCompWidth > x) and
(LeftTop.y + NonVisualCompWidth > y) then
Exit;
end;
end; end;
end; end;
Result := nil;
end; end;
Result:=nil;
begin
Result := TraverseComponents(FLookupRoot);
end; end;
procedure TDesigner.MoveNonVisualComponentIntoForm(AComponent: TComponent); procedure TDesigner.MoveNonVisualComponentIntoForm(AComponent: TComponent);
var
P: TPoint;
Tmp: TComponent;
begin begin
with NonVisualComponentLeftTop(AComponent) do P := NonVisualComponentLeftTop(AComponent);
AComponent.DesignInfo := LeftTopToDesignInfo(x, y); Tmp := AComponent;
while Tmp.Owner <> FLookupRoot do
begin
Tmp := Tmp.Owner;
if Tmp is TControl then
begin
dec(P.X, TControl(Tmp).Left);
dec(P.Y, TControl(Tmp).Top);
end;
end;
AComponent.DesignInfo := LeftTopToDesignInfo(P.X, P.Y);
end; end;
procedure TDesigner.MoveNonVisualComponentsIntoForm; procedure TDesigner.MoveNonVisualComponentsIntoForm;