diff --git a/designer/abstractformeditor.pp b/designer/abstractformeditor.pp index fc862f9e53..34f0a95599 100644 --- a/designer/abstractformeditor.pp +++ b/designer/abstractformeditor.pp @@ -17,10 +17,10 @@ * * ***************************************************************************/ } -{$H+} unit AbstractFormEditor; -{$mode objfpc} +{$mode objfpc}{$H-} + interface uses @@ -70,7 +70,7 @@ or use TPropertyType TIFormInterface = class public - Function Filename : String; virtual; abstract; + Function Filename : AnsiString; virtual; abstract; Function FormModified : Boolean; virtual; abstract; Function MArkModified : Boolean; virtual; abstract; Function GetFormComponent : TIComponentInterface; virtual; abstract; @@ -92,7 +92,7 @@ or use TPropertyType TAbstractFormEditor = class public - Function Filename : String; virtual; abstract; + Function Filename : AnsiString; virtual; abstract; Function FormModified : Boolean; virtual; abstract; Function FindComponentByName(const Name : String) : TIComponentInterface; virtual; abstract; Function FindComponent(AComponent: TComponent): TIComponentInterface; virtual; abstract; diff --git a/designer/controlselection.pp b/designer/controlselection.pp index c8cc5b8af4..9564aadd69 100644 --- a/designer/controlselection.pp +++ b/designer/controlselection.pp @@ -1,4 +1,4 @@ -{ /*************************************************************************** +{/*************************************************************************** ControlSelection.pp ------------------- cointains selected controls. @@ -20,12 +20,12 @@ } unit ControlSelection; -{$mode objfpc} +{$mode objfpc}{$H+} interface uses - Classes, Controls, LCLLinux, Forms; + Classes, Controls, LCLLinux, Forms, Graphics; type TGrabberMoveEvent = procedure(Sender: TObject; dx, dy: Integer) of object; @@ -35,83 +35,133 @@ type TGrabPosition = (gpTop, gpBottom, gpLeft, gpRight); TGrabPositions = set of TGrabPosition; - TGrabber = class(TWinControl) + // A TGrabber is one of the 8 small black rectangles at the boundaries of + // a selection + TGrabber = class private - FDragging: Boolean; - FLastMouseMove, FStart: TPoint; FPositions: TGrabPositions; - FOnMove: TGrabberMoveEvent; - FOnMoved: TGrabberMoveEvent; - protected - procedure PaintWindow(DC: HDC); override; - procedure DoDragMove(NewX, NewY: integer); - procedure EndDragging(NewX, NewY: integer); - procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; - procedure MouseMove(Shift: TShiftState; X, Y: Integer); override; - procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; + FHeight: integer; + FTop: integer; + FWidth: integer; + FLeft: integer; + FOldLeft: integer; + FOldTop: integer; + FOldWidth: integer; + FOldHeight: integer; public - procedure CaptureMouseMove(Sender:TControl;Shift: TShiftState; X, Y: Integer); - procedure CaptureMouseUp(Sender:TControl;Button: TMouseButton; Shift: TShiftState; X, Y: Integer); - constructor Create(AOwner: TComponent); override; - property IsDragging:Boolean read FDragging; property Positions: TGrabPositions read FPositions write FPositions; - property OnMove: TGrabberMoveEvent read FOnMove write FOnMove; - property OnMoved: TGrabberMoveEvent read FOnMoved write FOnMoved; + property Left:integer read FLeft write FLeft; + property Top:integer read FTop write FTop; + property Width:integer read FWidth write FWidth; + property Height:integer read FHeight write FHeight; + property OldLeft:integer read FOldLeft write FOldLeft; + property OldTop:integer read FOldTop write FOldTop; + property OldWidth:integer read FOldWidth write FOldWidth; + property OldHeight:integer read FOldHeight write FOldHeight; + procedure SaveBounds; end; + + TSelectedControl = class + private + FControl:TControl; + FOldLeft: integer; + FOldTop: integer; + FOldWidth: integer; + FOldHeight: integer; + public + constructor Create(AControl:TControl); + destructor Destroy; override; + property Control:TControl read FControl write FControl; + property OldLeft:integer read FOldLeft write FOldLeft; + property OldTop:integer read FOldTop write FOldTop; + property OldWidth:integer read FOldWidth write FOldWidth; + property OldHeight:integer read FOldHeight write FOldHeight; + procedure SaveBounds; + end; + + TControlSelection = class(TObject) private - FDragging: Boolean; - FVisible: Boolean; + FControls: TList; // list of TSelectedComponent + + // current bounds (only valid when Count>0) + FLeft: Integer; + FTop: Integer; FWidth: Integer; FHeight: Integer; - FTop: Integer; - FLeft: Integer; - FStart: TPoint; + // saved bounds + FOldLeft: integer; + FOldTop: integer; + FOldWidth: integer; + FOldHeight: integer; + + FCustomForm: TCustomForm; FGrabbers: array[TGrabIndex] of TGrabber; - FControlList: TList; + FGrabberSize: integer; + FMarkerSize: integer; + FActiveGrabber:TGrabber; + FRubberBandBounds:TRect; + FVisible:boolean; + FOnChange: TNotifyEvent; - procedure AdjustSize(AControl: TControl; Initial: Boolean); - procedure ControlMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); - procedure ControlMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); - procedure ControlMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); + + procedure SetCustomForm; + function GetGrabbers(AGrabIndex:TGrabIndex): TGrabber; + procedure SetGrabbers(AGrabIndex:TGrabIndex; const AGrabber: TGrabber); + procedure SetGrabberSize(const NewSize: integer); + procedure AdjustSize; + procedure AdjustGrabber; procedure DoChange; - procedure SetGrabbers; - procedure SizeContent; procedure SetVisible(const Value: Boolean); - procedure GrabberMove(Sender: TObject; dx, dy: Integer); - procedure GrabberMoved(Sender: TObject; dx, dy: Integer); + function GetItems(Index:integer):TSelectedControl; + procedure SetItems(Index:integer; ASelectedControl:TSelectedControl); + procedure SetActiveGrabber(AGrabber:TGrabber); + procedure SetRubberBandBounds(ARect:TRect); protected public - procedure MoveContent(dx, dy: Integer); - procedure Add(AControl: TControl); - procedure Clear; - constructor Create(AOwner: TWinControl); virtual; - destructor Destroy; override; - function IsSelected(AControl: TControl): Boolean; + property Items[Index:integer]:TSelectedControl read GetItems write SetItems; default; + function Count:integer; + function IndexOf(AControl:TControl):integer; + function Add(AControl: TControl):integer; procedure Remove(AControl: TControl); + procedure Delete(Index:integer); + procedure Clear; + procedure Assign(AControlSelection:TControlSelection); + function IsSelected(AControl: TControl): Boolean; + procedure SaveBounds; procedure MoveSelection(dx, dy: integer); - procedure SizeSelection(dx, dy: integer); - property Visible: Boolean read FVisible write SetVisible; + procedure SizeSelection(dx, dy: integer); + // size all controls depending on ActiveGrabber. + // if ActiveGrabber=nil then Left,Top + property GrabberSize:integer read FGrabberSize write SetGrabberSize; + procedure DrawGrabbers; + function GrabberAtPos(X,Y:integer):TGrabber; + property Grabbers[AGrabIndex:TGrabIndex]:TGrabber read GetGrabbers write SetGrabbers; + property MarkerSize:integer read FMarkerSize write FMarkerSize; property OnChange: TNotifyEvent read FOnChange write FOnChange; - + procedure DrawMarker(AControl:TControl; DC:HDC); + property ActiveGrabber:TGrabber read FActiveGrabber write SetActiveGrabber; + property Left:integer read FLeft; + property Top:integer read FTop; + property Width:integer read FWidth; + property Height:integer read FHeight; + property RubberbandBounds:TRect read FRubberbandBounds write SetRubberbandBounds; + procedure DrawRubberband(DeleteOld:boolean; ARect:TRect); + procedure SelectWithRubberBand(ACustomForm:TCustomForm); + property Visible:boolean read FVisible write SetVisible; + constructor Create; + destructor Destroy; override; end; - procedure SetCaptureGrabber(AGrabber:TGrabber); - function GetCaptureGrabber:TGrabber; implementation + uses Sysutils, Math; -type - TSelectControl = class(TControl)//; - end; - const - GRAB_SIZE = 6; - GRAB_CURSOR: array[TGrabIndex] of TCursor = ( crSizeNWSE, crSizeNS, crSizeNESW, crSizeWE, crSizeWE, @@ -124,523 +174,464 @@ const [gpLeft, gpBottom], [gpBottom], [gpBottom, gpRight] ); -var - CaptureGrabber:TGrabber; - -procedure SetCaptureGrabber(AGrabber:TGrabber); -begin - Write('SETCAPTUREGRABBER to.... '); - if AGrabber <> nil then Writeln(Format('0x%x', [AGrabber.handle])) else writeln('nil'); - - CaptureGrabber:=AGrabber; -end; - -function GetCaptureGrabber:TGrabber; -begin - Result:=CaptureGrabber; -end; { TGrabber } -constructor TGrabber.Create(AOwner: TComponent); +procedure TGrabber.SaveBounds; begin - inherited Create(AOwner); - ControlState := ControlState + [csCustomPaint]; - FDragging := False; + FOldLeft:=FLeft; + FOldTop:=FTop; + FOldWidth:=FWidth; + FOldHeight:=FHeight; end; -procedure TGrabber.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); + +{ TSelectedControl } + +constructor TSelectedControl.Create(AControl:TControl); begin -//writeln('[TGrabber.MouseDown] X='+IntToStr(X+Left)+',Y='+IntToStr(Y+Top)); - if CaptureGrabber<>nil then exit; - // compute absolute mouse coordinates - if (Button = mbLeft) and (not FDragging) - then begin - FLastMouseMove := Point(X+Left, Y+Top); - FStart := FLastMouseMove; - FDragging := True; - SetCaptureGrabber(Self); - end else - inherited MouseDown(Button, Shift, X, Y); + inherited Create; + FControl:=AControl; end; -procedure TGrabber.MouseMove(Shift: TShiftState; X, Y: Integer); +destructor TSelectedControl.Destroy; begin - if (CaptureGrabber<>nil) and (CaptureGrabber<>Self) then begin - CaptureGrabber.CaptureMouseMove(Self,Shift, X, Y); - end else begin - if FDragging then begin -//writeln('[TGrabber.MouseMove] X='+IntToStr(X)+',Y='+IntToStr(Y)); - DoDragMove(X+Left,Y+Top); - end else - inherited MouseMove(Shift, X, Y); - end; + inherited Destroy; end; -procedure TGrabber.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +procedure TSelectedControl.SaveBounds; begin -//Writeln('MouseUp in TGrabber'); - - if (CaptureGrabber<>nil) and (CaptureGrabber<>Self) then begin - CaptureGrabber.CaptureMouseUp(Self,Button, Shift, X, Y); - end else begin -//writeln('[TGrabber.MouseUp] X='+IntToStr(X+Left)+',Y='+IntToStr(Y+Top)); - if FDragging then - EndDragging(X+Left,Y+Top) - else - inherited MouseUp(Button, Shift, X, Y); - end; -end; - -procedure TGrabber.CaptureMouseMove(Sender:TControl;Shift: TShiftState; -X, Y: Integer); -begin -//Writeln('CaptureMouseMove in TGrabber'); - if CaptureGrabber<>Self then exit; -//writeln('[TGrabber.CaptureMouseMove]'); - MouseMove(Shift,X-CaptureGrabber.Left,Y-CaptureGrabber.Top); -end; - -procedure TGrabber.CaptureMouseUp(Sender:TControl;Button: TMouseButton; -Shift: TShiftState; X, Y: Integer); -begin -//Writeln('CaptureMouseUp in TGrabber'); - if CaptureGrabber<>Self then exit; - if not (Sender is TCustomForm) then begin - inc(X,TControl(Sender).Left); - inc(Y,TControl(Sender).Top); - end; - MouseUp(Button,Shift,X-CaptureGrabber.Left,Y-CaptureGrabber.Top); -end; - -procedure TGrabber.DoDragMove(NewX, NewY: integer); -var dx, dy: Integer; -begin - if FDragging then begin -//writeln('[TGrabber.DoDragMove] NewX='+IntToStr(NewX)+',NewY='+IntToStr(NewY)); - if [gpLeft, gpRight] * Positions <> [] - then dx := NewX - FLastMouseMove.X - else dx := 0; - if [gpTop, gpBottom] * Positions <> [] - then dy := NewY - FLastMouseMove.Y - else dy := 0; - FLastMouseMove:=Point(NewX,NewY); - - if Assigned(FOnMove) then FOnMove(Self, dx, dy); - end; -end; - -procedure TGrabber.EndDragging(NewX, NewY: integer); -var dx, dy: Integer; -begin - if FDragging then begin -//writeln('[TGrabber.EndDragging] NewX='+IntToStr(NewX)+',NewY='+IntToStr(NewY)); - DoDragMove(NewX, NewY); - FDragging := False; - SetCaptureGrabber(nil); - if [gpLeft, gpRight] * Positions <> [] - then dx := NewX - FStart.X - else dx := 0; - if [gpTop, gpBottom] * Positions <> [] - then dy := NewY - FStart.Y - else dy := 0; - if Assigned(FOnMoved) then FOnMoved(Self, dx, dy); - end; -end; - -procedure TGrabber.PaintWindow(DC: HDC); -begin - FillRect(DC, Rect(0, 0, Width, Height), GetStockObject(BLACK_BRUSH)); + FOldLeft:=Control.Left; + FOldTop:=Control.Top; + FOldWidth:=Control.Width; + FOldHeight:=Control.Height; end; { TControlSelection } -procedure TControlSelection.MoveSelection(dx, dy: integer); +constructor TControlSelection.Create; +var g:TGrabIndex; begin -{Writeln('**********'); -Writeln('Move Selection'); -Writeln(Format('dx,dy = %d,%d',[dx,dy])); -Writeln(Format('FLeft,FTop= %d,%d',[FLeft,FTop])); -Writeln('**********'); - } - if (dx<>0) or (dy<>0) then begin - Inc(FLeft,dx); - Inc(FTop,dy); - MoveContent(dx,dy); - SetGrabbers; + inherited; + FControls:=TList.Create; + FGrabberSize:=6; + FMarkerSize:=4; + for g:=Low(TGrabIndex) to High(TGrabIndex) do begin + FGrabbers[g]:=TGrabber.Create; + FGrabbers[g].Positions:=GRAB_POSITIONS[g]; end; -end; - -procedure TControlSelection.SizeSelection(dx, dy: integer); -begin -{Writeln('**********'); -Writeln('Size Selection'); -Writeln(Format('dx,dy = %d,%d',[dx,dy])); -Writeln(Format('FLeft,FTop= %d,%d',[FLeft,FTop])); -Writeln('**********'); - } - if (dx<>0) or (dy<>0) then begin - Inc(FWidth,dx); - Inc(FHeight,dy); - SizeContent; - SetGrabbers; - end; -end; - - -procedure TControlSelection.Add(AControl: TControl); -begin - if AControl <> nil - then begin - WriteLn(Format('[TControlSelection.Add] %s', [AControl.ClassName])); - - if (FControlList.Count>0) and (AControl is TCustomForm) then begin - writeln('TCustomForm not added to multiselection'); - end else begin; - FControlList.Add(AControl); - end; - AdjustSize(Acontrol, FControlList.Count = 1); - Visible:=not (AControl is TCustomForm); - //This is taken care of in SETVISIBLE SetGrabbers; - with TSelectControl(AControl) do - begin - {OnMouseDown := @ControlMouseDown; - OnMouseMove := @ControlMouseMove; - OnMouseUp := @ControlMouseUp;} - end; - DoChange; - end; -end; - -procedure TControlSelection.AdjustSize(AControl: TControl; Initial: Boolean); -var - n: Integer; -begin -Writeln('AdjustSize in TCOntrolSelection'); - - if AControl <> nil - then begin - if Initial - then begin - FLeft := AControl.Left; - FTop := AControl.Top; - FWidth := AControl.Width; - FHeight := AControl.Height; - WriteLn(Format( - '[TControlSelection.AdjustSize] Initializing to X:%d, Y:%d, W:%d, H: %d' - , [FLeft, FTop, FWidth, FHeight])); - end - else begin - WriteLn(Format( - '[TControlSelection.AdjustSize] current X:%d, Y:%d, W:%d, H: %d' - , [FLeft, FTop, FWidth, FHeight])); - with AControl do - WriteLn(Format( - '[TControlSelection.AdjustSize] '+ - 'Adjust for %s --> X:%d, Y:%d, W:%d, H: %d' - , [Classname, Left, Top, Width, Height])); - n := FLeft - AControl.Left; - if n > 0 - then begin - FLeft := AControl.Left; - Inc(FWidth , n); - end; - - n := FTop - AControl.Top; - if n > 0 - then begin - FTop := AControl.Top; - Inc(FHeight, n); - end; - - n := Max(FLeft + FWidth, AControl.Left + AControl.Width); - FWidth := n - FLeft; - - n := Max(FTop + FHeight, AControl.Top + AControl.Height); - FHeight := n - FTop; - WriteLn(Format( - '[TControlSelection.AdjustSize] Adjusted to X:%d, Y:%d, W:%d, H: %d' - , [FLeft, FTop, FWidth, FHeight])); - end; - end; -end; - -procedure TControlSelection.Clear; -var - n: Integer; -begin - writeln('[TControlSelection.Clear]'); - with FControlList do - begin - for n := 0 to Count -1 do - with TSelectControl(Items[n]) do - begin - {OnMouseDown := nil; - OnMouseMove := nil; - OnMouseUp := nil;} - end; - - Clear; - end; - FWidth := 0; - FHeight := 0; - Visible := False; - //This is set in SETVISIBLE SetGrabbers; - DoChange; -end; - -procedure TControlSelection.ControlMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); -begin -Writeln('ControlMOuseDown in TCOntrolSelection'); - - if Button = mbLeft - then begin - FStart := Point(X, Y); - FDragging := True; - end; -end; - -procedure TControlSelection.ControlMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); -begin -Writeln('ControlMOuseMove in TCOntrolSelection'); - if FDragging - then begin - Inc(FLeft, X - FStart.X); - Inc(FTop, Y - FStart.Y); - SetGrabbers; - Writeln(format('X-FStart.x = %d-%d=%d',[X,FStart.x,X-FStart.x])); - Writeln(format('Y-FStart.Y = %d-%d=%d',[Y,FStart.y,Y-FStart.y])); - MoveContent(X - FStart.x, Y - FStart.Y); - end; -end; - -procedure TControlSelection.ControlMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); -begin -Writeln('TCOntrolSelection.ControlMOuseUp'); - if (Button = mbLeft) and FDragging - then begin - FDragging := False; - Writeln(format('X-FStart.x = %d-%d=%d',[X,FStart.x,X-FStart.x])); - Writeln(format('Y-FStart.Y = %d-%d=%d',[Y,FStart.y,Y-FStart.y])); - MoveContent(X - FStart.X, Y - FStart.Y); - end; -end; - -constructor TControlSelection.Create(AOwner: TWinControl); -var - GrabPos: TGrabIndex; -begin - writeln('[TControlSelection.Create] '+TComponent(AOwner).Name); - inherited Create; - - FWidth := 0; - FHeight := 0; - FLeft := 0; - FTop := 0; - FVisible := False; - - FDragging := False; - - FControlList := TList.Create; - - for GrabPos := Low(TGrabIndex) to High(TGrabIndex) do - begin - WriteLN(Format('[TControlSelection.Create] Create grabber %d', [Ord(GrabPos)])); - FGrabbers[GrabPos] := TGrabber.Create(AOwner); - with FGrabbers[GrabPos] do - begin - Parent := AOwner; - Width := GRAB_SIZE; - Height := GRAB_SIZE; - Visible := False; - Cursor := GRAB_CURSOR[GrabPos]; - Positions := GRAB_POSITIONS[GrabPos]; - OnMove := @GrabberMove; - OnMoved := @GrabberMoved; - end; - end; -Writeln('Done in TControlSelection.Create'); + FCustomForm:=nil; + FActiveGrabber:=nil; end; destructor TControlSelection.Destroy; +var g:TGrabIndex; begin Clear; - FControlList.Free; + FControls.Free; + for g:=Low(TGrabIndex) to High(TGrabIndex) do FGrabbers[g].Free; inherited Destroy; end; +procedure TControlSelection.SetCustomForm; +var NewCustomForm:TCustomForm; +begin + if Count>0 then begin + NewCustomForm:=GetParentForm(Items[0].Control); + end else begin + NewCustomForm:=nil; + end; + if NewCustomForm=FCustomForm then exit; + FCustomForm:=NewCustomForm; +end; + +function TControlSelection.GetGrabbers(AGrabIndex:TGrabIndex): TGrabber; +begin + Result:=FGrabbers[AGrabIndex]; +end; + +procedure TControlSelection.SetGrabbers(AGrabIndex:TGrabIndex; + const AGrabber: TGrabber); +begin + FGrabbers[AGrabIndex]:=AGrabber; +end; + +procedure TControlSelection.SetGrabberSize(const NewSize: integer); +begin + if NewSize=FGrabberSize then exit; + FGrabberSize:=NewSize; +end; + +procedure TControlSelection.AdjustSize; +var i,ALeft,ATop:integer; + FormOrigin:TPoint; + + procedure AbsoluteLeftTop(AControl:TControl; var ALeft, ATop:integer); + var ControlOrigin:TPoint; + begin + ControlOrigin:=AControl.ClientOrigin; + ALeft:=ControlOrigin.X-FormOrigin.X; + ATop:=ControlOrigin.Y-FormOrigin.Y; + end; + +begin + if FControls.Count>=1 then begin + FormOrigin:=FCustomForm.ClientOrigin; + AbsoluteLeftTop(Items[0].Control,ALeft,ATop); + FLeft:=ALeft; + FTop:=ATop; + FHeight:=Items[0].Control.Height; + FWidth:=Items[0].Control.Width; + for i:=1 to FControls.Count-1 do begin + AbsoluteLeftTop(Items[i].Control,ALeft,ATop); + if FLeft>ALeft then begin + inc(FWidth,FLeft-ALeft); + FLeft:=ALeft; + end; + if FTop>ATop then begin + inc(FHeight,FTop-ATop); + FTop:=ATop; + end; + FWidth:=Max(FLeft+FWidth,ALeft+Items[i].Control.Width)-FLeft; + FHeight:=Max(FTop+FHeight,ATop+Items[i].Control.Height)-FTop; + end; + AdjustGrabber; + end; +end; + +procedure TControlSelection.AdjustGrabber; +var g:TGrabIndex; +begin + for g:=Low(TGrabIndex) to High(TGrabIndex) do begin + if gpLeft in FGrabbers[g].Positions then + FGrabbers[g].Left:=FLeft-GrabberSize + else if gpRight in FGrabbers[g].Positions then + FGrabbers[g].Left:=FLeft+FWidth + else + FGrabbers[g].Left:=FLeft+((FWidth-GrabberSize) div 2); + if gpTop in FGrabbers[g].Positions then + FGrabbers[g].Top:=FTop-GrabberSize + else if gpBottom in FGrabbers[g].Positions then + FGrabbers[g].Top:=FTop+FHeight + else + FGrabbers[g].Top:=FTop+((FHeight-GrabberSize) div 2); + FGrabbers[g].Width:=GrabberSize; + FGrabbers[g].Height:=GrabberSize; + end; +end; + procedure TControlSelection.DoChange; begin if Assigned(FOnChange) then FOnChange(Self); end; -procedure TControlSelection.GrabberMove(Sender: TObject; dx, dy: Integer); +procedure TControlSelection.SetVisible(const Value: Boolean); begin - writeln('[TControlSelection.GrabberMove] '+TComponent(Sender).Name+ - ' dx='+IntToStr(dx)+',dy='+IntToStr(dy)); - - if gpLeft in TGrabber(Sender).Positions - then begin - Inc(FLeft, dx); - Dec(FWidth, dx); - end; - if gpRight in TGrabber(Sender).Positions then Inc(FWidth, dx); - - if gpTop in TGrabber(Sender).Positions - then begin - Inc(FTop, dy); - Dec(FHeight, dy) - end; - if gpBottom in TGrabber(Sender).Positions then Inc(FHeight, dy); - - SetGrabbers; + if FVisible=Value then exit; + FVisible:=Value; + DoChange; end; -procedure TControlSelection.GrabberMoved(Sender: TObject; dx, dy: Integer); +function TControlSelection.GetItems(Index:integer):TSelectedControl; begin - writeln('[TControlSelection.GrabberMoved] '+TComponent(Sender).Name - +',dx='+IntToStr(dx)+', dy='+IntToStr(dy)); - SizeContent; + Result:=TSelectedControl(FControls[Index]); +end; + +procedure TControlSelection.SetItems(Index:integer; + ASelectedControl:TSelectedControl); +begin + FControls[Index]:=ASelectedControl; +end; + +procedure TControlSelection.SaveBounds; +var i:integer; + g:TGrabIndex; +begin + for i:=0 to FControls.Count-1 do Items[i].SaveBounds; + for g:=Low(TGrabIndex) to High(TGrabIndex) do FGrabbers[g].SaveBounds; + FOldLeft:=FLeft; + FOldTop:=FTop; + FOldWidth:=FWidth; + FOldHeight:=FHeight; +end; + +procedure TControlSelection.SetActiveGrabber(AGrabber:TGrabber); +begin + FActiveGrabber:=AGrabber; +end; + +function TControlSelection.Count:integer; +begin + Result:=FControls.Count; +end; + +function TControlSelection.IndexOf(AControl:TControl):integer; +begin + Result:=Count-1; + while (Result>=0) and (Items[Result].Control<>AControl) do dec(Result); +end; + +function TControlSelection.Add(AControl: TControl):integer; +var NewSelectedControl:TSelectedControl; +begin + NewSelectedControl:=TSelectedControl.Create(AControl); + if GetParentForm(AControl)<>FCustomForm then Clear; + Result:=FControls.Add(NewSelectedControl); + if Count=1 then SetCustomForm; + AdjustSize; + DoChange; +end; + +procedure TControlSelection.Remove(AControl: TControl); +var i:integer; +begin + i:=IndexOf(AControl); + if i>=0 then Delete(i); +end; + +procedure TControlSelection.Delete(Index:integer); +begin + if Index<0 then exit; + Items[Index].Free; + FControls.Delete(Index); + if Count=0 then SetCustomForm; + AdjustSize; + DoChange; +end; + +procedure TControlSelection.Clear; +var i:integer; +begin + for i:=0 to FControls.Count-1 do Items[i].Free; + FControls.Clear; + FCustomForm:=nil; + AdjustSize; + DoChange; +end; + +procedure TControlSelection.Assign(AControlSelection:TControlSelection); +var i:integer; +begin + if AControlSelection=Self then exit; + Clear; + FControls.Capacity:=AControlSelection.Count; + for i:=0 to AControlSelection.Count-1 do + Add(AControlSelection[i].Control); + SetCustomForm; + AdjustSize; + DoChange; end; function TControlSelection.IsSelected(AControl: TControl): Boolean; begin - WriteLn(Format('[TControlSelection.IsSelected] %s --> index %d', [AControl.ClassName, FControlList.IndexOf(AControl)])); - Result := FControlList.IndexOf(AControl) <> -1; + Result:=(IndexOf(AControl)>=0); end; -procedure TControlSelection.MoveContent(dx, dy: Integer); -var - n: Integer; +procedure TControlSelection.MoveSelection(dx, dy: integer); +var i:integer; + g:TGrabIndex; begin - writeln('[TControlSelection.MoveContent] dx='+IntToStr(dx)+', dy='+IntToStr(dy)); - if FControlList.Count = 1 then - begin - if (TCOntrol(FControlList[0]) is TCustomForm) then exit; - TControl(FControlList[0]).SetBounds(FLeft, FTop, FWidth, FHeight); - end + if (dx=0) and (dy=0) then exit; + for i:=0 to FControls.Count-1 do + with Items[i] do + Control.SetBounds(OldLeft+dx,OldTop+dy + ,Control.Width,Control.Height); + for g:=Low(TGrabIndex) to High(TGrabIndex) do begin + FGrabbers[g].Left:=FGrabbers[g].OldLeft+dx; + FGrabbers[g].Top:=FGrabbers[g].OldTop+dy; + end; +end; + +procedure TControlSelection.SizeSelection(dx, dy: integer); +// size all controls depending on ActiveGrabber. +// if ActiveGrabber=nil then Left,Top +var i:integer; + GrabberPos:TGrabPositions; +begin + if Count=0 then exit; + if FActiveGrabber<>nil then + GrabberPos:=FActiveGrabber.Positions else - with FControlList do - for n := 0 to Count -1 do - with TControl(Items[n]) do - begin - - SetBounds(Left+dx,Top+dy,Width,Height); - //Left := Left + dx; - //Top := Top + dy; + GrabberPos:=[gpLeft,gpTop]; + if [gpTop,gpBottom] * GrabberPos = [] then dy:=0; + if [gpLeft,gpRight] * GrabberPos = [] then dx:=0; + if (dx=0) and (dy=0) then exit; + if gpLeft in GrabberPos then begin + FLeft:=FOldLeft+dx; + FWidth:=FOldWidth-dx; + end; + if gpRight in GrabberPos then begin + FWidth:=FOldWidth+dx; + end; + if gpTop in GrabberPos then begin + FTop:=FOldTop+dy; + FHeight:=FOldHeight-dy; + end; + if gpBottom in GrabberPos then begin + FHeight:=FOldHeight+dy; + end; + AdjustGrabber; + if Count=1 then begin + // single selection + Items[0].Control.SetBounds(FLeft,FTop,FWidth,FHeight); + end else if Count>1 then begin + // multi selection + if (FOldWidth<>0) and (FOldHeight<>0) then begin + for i:=0 to Count-1 do begin + Items[i].Control.SetBounds( + FOldLeft + (((Items[i].OldLeft-FOldLeft) * FWidth) div FOldWidth), + FOldTop + (((Items[i].OldTop-FOldTop) * FHeight) div FOldHeight), + Max(1,Abs((Items[i].OldWidth * FWidth) div FOldWidth)), + Max(1,Abs((Items[i].OldHeight * FHeight) div FOldHeight)) + ); end; + end; + end; + DoChange; end; -procedure TControlSelection.Remove(AControl: TControl); -var - n: Integer; +procedure TControlSelection.DrawGrabbers; +var OldBrushColor:TColor; + g:TGrabIndex; begin - with AControl do - WriteLn(Format( - '[TControlSelection.Remove] Remove %s --> X:%d, Y:%d, W:%d, H: %d' - ,[Classname, Left, Top, Width, Height])); + if (Count=0) or (FCustomForm=nil) + or (Items[0].Control is TCustomForm) then exit; + with FCustomForm.Canvas do begin + OldBrushColor:=Brush.Color; + Brush.Color:=clBlack; + for g:=Low(TGrabIndex) to High(TGrabIndex) do + FillRect(Rect(FGrabbers[g].Left,FGrabbers[g].Top + ,FGrabbers[g].Left+FGrabbers[g].Width + ,FGrabbers[g].Top+FGrabbers[g].Height)); + Brush.Color:=OldbrushColor; + end; +end; - if (FControlList.Remove(AControl) <> -1) - then begin - if FControlList.Count > 0 - then begin - for n := 0 to FControlList.Count - 1 do - AdjustSize(TControl(FControlList[n]), n = 0); - end - else FVisible := False; +function TControlSelection.GrabberAtPos(X,Y:integer):TGrabber; +var g:TGrabIndex; +begin + if FControls.Count>0 then begin + for g:=Low(TGrabIndex) to High(TGrabIndex) do + if (FGrabbers[g].Left<=x) and (FGrabbers[g].Top<=y) + and (FGrabbers[g].Left+FGrabbers[g].Width>x) + and (FGrabbers[g].Top+FGrabbers[g].Height>y) then begin + Result:=FGrabbers[g]; + exit; + end; + end; + Result:=nil; +end; - SetGrabbers; +procedure TControlSelection.DrawMarker(AControl:TControl; DC:HDC); +var OldBrushColor:TColor; + ALeft,ATop:integer; + FormOrigin,AControlOrigin:TPoint; + SaveIndex:HDC; +begin + if (Count<1) or (FCustomForm=nil) or (AControl is TCustomForm) + or (not IsSelected(AControl)) then exit; + FormOrigin:=FCustomForm.ClientOrigin; + AControlOrigin:=AControl.ClientOrigin; + // MoveWindowOrg is currently truned off in the gtk + // this is a workaround + ALeft:=0; //AControlOrigin.X-FormOrigin.X; + ATop:=0; //AControlOrigin.Y-FormOrigin.Y; + SaveIndex := SaveDC(DC); + //MoveWindowOrg(DC, 15,5); + FCustomForm.Canvas.Handle:=DC; +writeln('DrawMarker A ',FCustomForm.Name,'=' + ,FormOrigin.X,',',FormOrigin.Y + ,' Control=',AControl.Name,',',AControlOrigin.X,',',AControlOrigin.Y + ,' DC=',FCustomForm.Canvas.Handle,' ',Cardinal(Pointer(FCustomForm)) + ,' MS=',MarkerSize); + with FCustomForm.Canvas do begin + OldBrushColor:=Brush.Color; + Brush.Color:=clDKGray; +//FillRect(Rect(0,0,6,500)); + FillRect(Rect(ALeft,ATop,ALeft+MarkerSize,ATop+MarkerSize)); + FillRect(Rect(ALeft,ATop+AControl.Height-MarkerSize + ,ALeft+MarkerSize,ATop+AControl.Height)); + FillRect(Rect(ALeft+AControl.Width-MarkerSize,ATop + ,ALeft+AControl.Width,ATop+MarkerSize)); + FillRect(Rect(ALeft+AControl.Width-MarkerSize + ,ATop+AControl.Height-MarkerSize + ,ALeft+AControl.Width,ATop+AControl.Height)); + Brush.Color:=OldbrushColor; + end; + FCustomForm.Canvas.Handle:=0; + RestoreDC(DC, SaveIndex); +end; - with TSelectControl(AControl) do +procedure TControlSelection.DrawRubberband(DeleteOld:boolean; ARect:TRect); + + procedure DrawInvertFrameRect(x1,y1,x2,y2:integer); + var i:integer; + procedure InvertPixel(x,y:integer); + var c:TColor; begin - { OnMouseDown := nil; - OnMouseMove := nil; - OnMouseUp := nil;} + c:=FCustomForm.Canvas.Pixels[x,y]; + c:=c xor $ffffff; + FCustomForm.Canvas.Pixels[x,y]:=c; end; - FDragging := False; - DoChange; - end; -end; - -procedure TControlSelection.SetGrabbers; -var - GrabPos: TGrabIndex; - Grabber: TGrabber; - GrabLeft, GrabTop: Integer; -begin - WriteLn(Format( - '[TControlSelection.SetGrabbers] Selection --> X:%d, Y:%d, W:%d, H:%d' - , [FLeft, FTop, FWidth, FHeight])); - for GrabPos := Low(TGrabIndex) to High(TGrabIndex) do begin - Grabber := FGrabbers[GrabPos]; - - //if FVisible then - begin - //Write('[TControlSelection.SetGrabbers] Setting grabber ',Ord(GrabPos),' --> '); - if gpLeft in Grabber.Positions - then begin - GrabLeft := FLeft - GRAB_SIZE; - //Write('Left, '); - end - else begin - if gpRight in Grabber.Positions - then begin - //Write('Right, '); - GrabLeft := FLeft + FWidth; - end - else begin - //Write('Center, '); - GrabLeft := FLeft + (FWidth - GRAB_SIZE) div 2; - end; - end; - - if gpTop in Grabber.Positions - then begin - GrabTop := FTop - GRAB_SIZE; - //Write('Top '); - end - else begin - if gpBottom in Grabber.Positions - then begin - //Write('Bottom '); - GrabTop := FTop + FHeight; - end - else begin - //Write('Center '); - GrabTop := FTop + (FHeight - GRAB_SIZE) div 2; - end; - end; - - Grabber.SetBounds(GrabLeft,GrabTop,GRAB_SIZE,GRAB_SIZE); - - //WriteLN(Format('X:%d, Y:%d', [Grabber.Left, Grabber.Top])); + if FCustomForm=nil then exit; + if x1>x2 then begin i:=x1; x1:=x2; x2:=i; end; + if y1>y2 then begin i:=y1; y1:=y2; y2:=i; end; + i:=x1+1; + while i Value - then begin - FVisible := Value; - SetGrabbers; - end; -end; +procedure TControlSelection.SelectWithRubberBand(ACustomForm:TCustomForm); +var i:integer; + FormOrigin:TPoint; -procedure TControlSelection.SizeContent; -begin - WriteLn('[TControlSelection.SizeContent]'); - if FControlList.Count = 1 then + function ControlInRubberBand(AControl:TControl):boolean; + var ALeft,ATop,ARight,ABottom:integer; + Origin:TPoint; begin - TControl(FControlList[0]).SetBounds(FLeft, FTop, FWidth, FHeight); + Origin:=AControl.ClientOrigin; + ALeft:=Origin.X-FormOrigin.X; + ATop:=Origin.Y-FormOrigin.Y; + ARight:=ALeft+AControl.Width; + ABottom:=ATop+AControl.Height; + Result:=(ALeft=FRubberBandBounds.Left) + and (ABottom>=FRubberBandBounds.Top); end; + +// SelectWithRubberBand +begin + FormOrigin:=ACustomForm.ClientOrigin; + Clear; + for i:=0 to ACustomForm.ControlCount-1 do + if ControlInRubberBand(ACustomForm.Controls[i]) then + Add(ACustomForm.Controls[i]); end; -initialization - -CaptureGrabber:=nil; +procedure TControlSelection.SetRubberBandBounds(ARect:TRect); +begin + FRubberBandBounds:=ARect; +end; end. diff --git a/designer/designer.pp b/designer/designer.pp index 70b24f50f3..a75dd2c21e 100644 --- a/designer/designer.pp +++ b/designer/designer.pp @@ -20,12 +20,13 @@ } unit designer; -{$mode objfpc} +{$mode objfpc}{$H+} interface uses - classes, Forms, controls, lmessages, graphics, ControlSelection, CustomFormEditor,FormEditor, UnitEditor,Main; + Classes, Forms, Controls, LMessages, Graphics, ControlSelection, + CustomFormEditor, FormEditor, UnitEditor, CompReg; type TGridPoint = record @@ -33,21 +34,37 @@ type y: integer; end; + TOnGetSelectedComponentClass = procedure(Sender: TObject; + var RegisteredComponent: TRegisteredComponent) of object; + TOnSetDesigning = procedure(Sender: TObject; Component: TComponent; + Value: boolean) of object; + TOnAddComponent = procedure(Sender: TObject; Component: TComponent; + ComponentClass: TRegisteredComponent) of object; + TDesigner = class(TIDesigner) private FCustomForm: TCustomForm; FFormEditor : TFormEditor; FSourceEditor : TSourceEditor; - FMainIDE : TMainIDE; + FActiveRubberband:boolean; + FOnGetSelectedComponentClass: TOnGetSelectedComponentClass; + FOnUnselectComponentClass: TNotifyEvent; + FOnSetDesigning: TOnSetDesigning; + FOnComponentListChanged: TNotifyEvent; + FOnPropertiesChanged: TNotifyEvent; + FOnAddComponent: TOnAddComponent; + function GetIsControl: Boolean; procedure SetIsControl(Value: Boolean); protected MouseDownControl : TObject; MouseDownPos, MouseUpPos, LastMouseMovePos : TPoint; - Procedure MouseDownOnControl(Sender : TControl; Message : TLMessage); - procedure MouseMoveOnControl(Sender : TControl; var Message : TLMessage); - Procedure MouseUpOnControl(Sender : TControl; Message:TLMessage); + function Paint(Sender: TControl; Message: TLMPaint):boolean; + + Procedure MouseDownOnControl(Sender : TControl; Message : TLMMouse); + Procedure MouseMoveOnControl(Sender : TControl; var Message : TLMMouse); + Procedure MouseUpOnControl(Sender : TControl; Message:TLMMouse); Procedure KeyDown(Sender : TControl; Message:TLMKEY); Procedure KeyUP(Sender : TControl; Message:TLMKEY); @@ -58,9 +75,8 @@ type public ControlSelection : TControlSelection; - constructor Create(customform : TCustomform); + constructor Create(Customform : TCustomform); destructor Destroy; override; - Procedure AddControlCode(Control : TComponent); procedure CreateNew(FileName : string); procedure LoadFile(FileName: string); @@ -69,28 +85,39 @@ type procedure Modified; override; procedure Notification(AComponent: TComponent; Operation: TOperation); override; procedure PaintGrid; override; - procedure ValidateRename(AComponent: TComponent; const CurName, NewName: string); override; + procedure ValidateRename(AComponent: TComponent; + const CurName, NewName: shortstring); override; Procedure SelectOnlyThisComponent(AComponent:TComponent); - property IsControl: Boolean read GetIsControl write SetIsControl; property Form: TCustomForm read FCustomForm write FCustomForm; property FormEditor : TFormEditor read FFormEditor write FFormEditor; property SourceEditor : TSourceEditor read FSourceEditor write FSourceEditor; - property MainIDE : TMainIDE read FMainIDE write FMainIDE; - end; + property OnGetSelectedComponentClass: TOnGetSelectedComponentClass + read FOnGetSelectedComponentClass write FOnGetSelectedComponentClass; + property OnUnselectComponentClass: TNotifyEvent + read FOnUnselectComponentClass write FOnUnselectComponentClass; + property OnSetDesigning: TOnSetDesigning read FOnSetDesigning write FOnSetDesigning; + property OnComponentListChanged: TNotifyEvent + read FOnComponentListChanged write FOnComponentListChanged; + property OnPropertiesChanged: TNotifyEvent + read FOnPropertiesChanged write FOnPropertiesChanged; + property OnAddComponent: TOnAddComponent read FOnAddComponent write FOnAddComponent; + end; + + +implementation - implementation uses - Sysutils, Typinfo,Math; + Sysutils, Typinfo, Math, LCLLinux; const - mk_lbutton = 1; - mk_rbutton = 2; - mk_shift = 4; - mk_control = 8; + mk_lbutton = 1; + mk_rbutton = 2; + mk_shift = 4; + mk_control = 8; mk_mbutton = $10; var @@ -100,12 +127,8 @@ constructor TDesigner.Create(CustomForm : TCustomForm); begin inherited Create; FCustomForm := CustomForm; - ControlSelection := TControlSelection.Create(CustomForm); - - //the source is created when the form is created. - //the TDesigner is created in Main.pp and then TDesigner.SourceEditor := SourceNotebook.CreateFormFromUnit(CustomForm); - - + ControlSelection := TControlSelection.Create; + FActiveRubberband:=false; end; destructor TDesigner.Destroy; @@ -114,7 +137,6 @@ Begin Inherited; end; - procedure TDesigner.CreateNew(FileName : string); begin @@ -123,152 +145,213 @@ end; Procedure TDesigner.RemoveControl(Control : TComponent); Begin - Writeln('RemoveControl called'); - FSourceEditor.RemoveControlCode(Control); - Writeln('1'); - FCustomForm.RemoveControl(TCOntrol(Control)); //this send a message to notification and removes it from the controlselection - Writeln('2'); - FFormEditor.DeleteControl(Control); - Writeln('3'); + Writeln('[TDesigner.RemoveControl] ',Control.Name,':',Control.ClassName); + FSourceEditor.RemoveControlCode(Control); + Writeln('[TDesigner.RemoveControl] 1'); + FCustomForm.RemoveControl(TCOntrol(Control)); + //this send a message to notification and removes it from the controlselection + Writeln('[TDesigner.RemoveControl] 2'); + FFormEditor.DeleteControl(Control); + Writeln('[TDesigner.RemoveControl] end'); end; Procedure TDesigner.NudgeControl(Value1,Value2 : Integer); Begin -Writeln('NudgeControl'); +Writeln('[TDesigner.NudgeControl]'); ControlSelection.MoveSelection(Value1,Value2); end; Procedure TDesigner.NudgeSize(Value1,Value2 : Integer); Begin - Writeln('NudgeSize'); + Writeln('[TDesigner.NudgeSize]'); ControlSelection.SizeSelection(Value1,Value2); end; procedure TDesigner.SelectOnlyThisComponent(AComponent:TComponent); begin -Writeln('Control Added '+TCOntrol(aComponent).name); - ControlSelection.Clear; - ControlSelection.Add(TControl(AComponent)); +Writeln('Control Added ',TControl(aComponent).name); + ControlSelection.Clear; + ControlSelection.Add(TControl(AComponent)); FFormEditor.ClearSelected; // this will automatically inform the object inspector FFormEditor.AddSelected(AComponent); end; +function TDesigner.Paint(Sender: TControl; Message: TLMPaint):boolean; +begin + Result:=true; + Sender.Dispatch(Message); + if (ControlSelection.IsSelected(Sender)) then begin + writeln('*** LM_PAINT ',Sender.Name,':',Sender.ClassName,' DC=',Message.DC); + ControlSelection.DrawMarker(Sender,Message.DC); + ControlSelection.DrawGrabbers; + end; +end; -procedure TDesigner.MouseDownOnControl(Sender : TControl; Message : TLMessage); +procedure TDesigner.MouseDownOnControl(Sender : TControl; Message : TLMMouse); +var i, + MouseX,MouseY, + CompIndex:integer; + FormOrigin,SenderOrigin:TPoint; + AControlSelection:TControlSelection; + SelectedCompClass: TRegisteredComponent; Begin -// if assigned(MouseDownControl) and (MOuseDownControl <> Sender) then Exit; - Writeln('Left is '+Inttostr(TCOntrol(Sender).left)); - Writeln('Top is '+Inttostr(TCOntrol(Sender).Top)); - Writeln('***************************'); - Writeln('TDesigner.MouseDownOnControl'); - Writeln(Format('X,Y = %d,%d',[TLMMOuse(Message).pos.x,TLMMOuse(Message).pos.Y])); - Writeln(Format('Control left and top are %d,%d',[TCOntrol(sender).Left,TCOntrol(sender).Top])); - Writeln('***************************'); + if (MouseDownControl<>nil) or (getParentForm(Sender)=nil) then exit; + MouseDownControl:=Sender; + FormOrigin:=GetParentForm(Sender).ClientOrigin; + SenderOrigin:=Sender.ClientOrigin; + MouseX:=Message.Pos.X+SenderOrigin.X-FormOrigin.X; + MouseY:=Message.Pos.Y+SenderOrigin.Y-FormOrigin.Y; - if GetCaptureGrabber<>nil then exit; + MouseDownPos := Point(MouseX,MouseY); + LastMouseMovePos:=MouseDownPos; - if not assigned(MouseDownControl) then - Begin - MouseDownPos.X := TLMMOuse(Message).pos.X; - MouseDownPos.Y := TLMMOuse(Message).pos.Y; - //adjust X and Y by adding the Control corners. - MouseDownControl:=Sender; - if not (Sender is TCustomForm) then - begin - inc(MouseDownPos.X,TControl(Sender).Left); - inc(MouseDownPos.Y,TControl(Sender).Top); - end; - LastMouseMovePos:=MouseDownPos; - end; + writeln('************************************************************'); + write('MouseDownOnControl'); + write(' ',Sender.Name,':',Sender.ClassName,' Sender=',SenderOrigin.X,',',SenderOrigin.Y); + write(' Msg=',Message.Pos.X,',',Message.Pos.Y); + write(' Mouse=',MouseX,',',MouseY); + writeln(''); - if (TLMMouse(Message).keys and MK_Shift) = MK_Shift then + ControlSelection.ActiveGrabber:= + ControlSelection.GrabberAtPos(MouseDownPos.X,MouseDownPos.Y); + + if (Message.Keys and MK_Shift) = MK_Shift then Writeln('Shift down') - else + else Writeln('No Shift down'); - if (TLMMouse(Message).keys and MK_Control) = MK_Control then + if (Message.Keys and MK_Control) = MK_Control then Writeln('CTRL down') - else + else Writeln('No CTRL down'); + if Assigned(FOnGetSelectedComponentClass) then + FOnGetSelectedComponentClass(Self,SelectedCompClass) + else + SelectedCompClass:=nil; - - - Writeln('Sender is '+sender.name); - if FMainIDE.SelectedComponent = nil then - Begin //mouse pointer button pressed. - if not (Sender is TCustomForm) then begin - if (TLMMouse(Message).keys and MK_Shift) = MK_Shift then - ControlSelection.Add(sender) - else - SelectOnlyThisComponent(TComponent(Sender)); + if SelectedCompClass = nil then begin + // selection mode + if ControlSelection.ActiveGrabber=nil then begin + CompIndex:=ControlSelection.IndexOf(Sender); + if (Message.Keys and MK_SHIFT)>0 then begin + // shift key + if CompIndex<0 then begin + // not selected + // add component to selection + if (ControlSelection.Count=0) + or (not (Sender is TCustomForm)) then begin + ControlSelection.Add(Sender); + Sender.Invalidate; + if Sender.Parent<>nil then + Sender.Parent.Invalidate; + end; + end else begin + // remove from multiselection + ControlSelection.Delete(CompIndex); + Sender.Invalidate; + if Sender.Parent<>nil then + Sender.Parent.Invalidate; + end; + end else begin + if (CompIndex<0) then begin + // select only this component + AControlSelection:=TControlSelection.Create; + AControlSelection.Assign(ControlSelection); + ControlSelection.Clear; + for i:=0 to AControlSelection.Count-1 do + AControlSelection[i].Control.Invalidate; + ControlSelection.Add(Sender); + Sender.Invalidate; + if Sender.Parent<>nil then + Sender.Parent.Invalidate; + AControlSelection.Free; + end; + end; end; + ControlSelection.SaveBounds; + end else begin + // add component mode -> handled in mousemove and mouseup end; + +writeln('[TDesigner.MouseDownOnControl] END'); End; -procedure TDesigner.MouseUpOnControl(Sender : TControl; Message:TLMessage); +procedure TDesigner.MouseUpOnControl(Sender : TControl; Message:TLMMouse); var ParentCI, NewCI : TComponentInterface; - NewLeft, NewTop, NewWidth, NewHeight : Integer; -// CInterface : TComponentInterface; - CaptureGrabber:TGrabber; - Button : TMouseButton; + NewLeft, NewTop, NewWidth, NewHeight, + MouseX, MouseY, I : Integer; Shift : TShiftState; + SenderParentForm:TCustomForm; + RubberBandWasActive:boolean; + FormOrigin,SenderOrigin:TPoint; + SelectedCompClass: TRegisteredComponent; + AControlSelection: TControlSelection; Begin + SenderParentForm:=GetParentForm(Sender); + if (MouseDownControl=nil) or (SenderParentForm=nil) then exit; + ControlSelection.ActiveGrabber:=nil; + RubberBandWasActive:=FActiveRubberBand; + if FActiveRubberband then begin + FActiveRubberband:=false; + ControlSelection.DrawRubberBand(false,ControlSelection.RubberBandBounds); + end; - Writeln('***************************'); - Writeln('In TDesigner.UpOnControl'); - Writeln(Format('X,Y = %d,%d',[TLMMOuse(Message).pos.x,TLMMOuse(Message).pos.Y])); - Writeln('***************************'); - if (TLMMouse(Message).keys and MK_LButton) = MK_LButton then - Button := mbLEft - else - if (TLMMouse(Message).keys and MK_LButton) = MK_RButton then - Button := mbRight; - - Shift := []; + Shift := []; if (TLMMouse(Message).keys and MK_Shift) = MK_Shift then - shift := [ssShift]; - + Shift := [ssShift]; if (TLMMouse(Message).keys and MK_Control) = MK_Control then - shift := shift +[ssCTRL]; + Shift := Shift +[ssCTRL]; - CaptureGrabber:=GetCaptureGrabber; - if CaptureGrabber<>nil then begin - CaptureGrabber.CaptureMouseUp(TControl(Sender),Button,Shift,TLMMouse(Message).pos.X,TLMMouse(Message).pos.Y); - exit; - end; + FormOrigin:=SenderParentForm.ClientOrigin; + SenderOrigin:=Sender.ClientOrigin; + MouseX:=Message.Pos.X+SenderOrigin.X-FormOrigin.X; + MouseY:=Message.Pos.Y+SenderOrigin.Y-FormOrigin.Y; + MouseUpPos := Point(MouseX,MouseY); + dec(MouseX,MouseDownPos.X); + dec(MouseY,MouseDownPos.Y); - MouseUpPos.X := TLMMouse(Message).pos.X; - MouseUpPos.Y := TLMMouse(Message).pos.Y; - if not (Sender is TCustomForm) then begin - inc(MouseUpPos.X,TControl(Sender).Left); - inc(MouseUpPos.Y,TControl(Sender).Top); - end; - - if FMainIDE.SelectedComponent = nil then - Begin //mouse pointer button pressed. - - end + if Assigned(FOnGetSelectedComponentClass) then + FOnGetSelectedComponentClass(Self,SelectedCompClass) else - Begin //add a new control + SelectedCompClass:=nil; - FMainIDE.SetDesigning(FCustomForm,False); - ParentCI:=TComponentInterface(FFormEditor.FindComponent(TComponent(Sender))); - if (TComponent(Sender) is TWinControl) - and (not (csAcceptsControls in TWinControl(Sender).ControlStyle)) then - begin + if SelectedCompClass = nil then begin + // selection mode + if (ControlSelection.Count=1) + and (ControlSelection[0].Control is TCustomForm) then begin + // rubberband selection + if RubberBandWasActive then begin + AControlSelection:=TControlSelection.Create; + AControlSelection.Assign(ControlSelection); + ControlSelection.Clear; + for i:=0 to AControlSelection.Count-1 do + AControlSelection[i].Control.Invalidate; + AControlSelection.Free; + ControlSelection.SelectWithRubberBand(SenderParentForm); + for i:=0 to ControlSelection.Count-1 do + ControlSelection[i].Control.Invalidate; + end; + end; + end else begin + // add a new control + + if Assigned(FOnSetDesigning) then FOnSetDesigning(Self,FCustomForm,False); + ParentCI:=TComponentInterface(FFormEditor.FindComponent(Sender)); + if (Sender is TWinControl) + and (not (csAcceptsControls in TWinControl(Sender).ControlStyle)) then begin ParentCI:=TComponentInterface( FFormEditor.FindComponent(TWinControl(Sender).Parent)); end; if Assigned(ParentCI) then begin - NewLeft:=Min(MouseDownPos.X,MouseUpPos.X); - NewWidth:=Abs(MouseUpPos.X-MouseDownPos.X); + NewLeft:=Min(MouseDownPos.X,MouseUpPos.X)-(SenderOrigin.X-FormOrigin.X); + NewWidth:=Abs(MouseUpPos.X-MouseDownPos.X)-(SenderOrigin.Y-FormOrigin.Y); NewTop:=Min(MouseDownPos.Y,MouseUpPos.Y); NewHeight:=Abs(MouseUpPos.Y-MouseDownPos.Y); if Abs(NewWidth+NewHeight)<7 then begin @@ -276,29 +359,33 @@ Begin NewWidth:=0; NewHeight:=0; end; - NewCI := TComponentInterface(FFormEditor.CreateComponent(ParentCI,FMainIDE.SelectedComponent.ComponentClass + NewCI := TComponentInterface(FFormEditor.CreateComponent( + ParentCI,SelectedCompClass.ComponentClass ,NewLeft,NewTop,NewWidth,NewHeight)); NewCI.SetPropByName('Visible',True); NewCI.SetPropByName('Designing',True); - FMainIDE.SetDesigning(NewCI.Control,True); - - ObjectInspector1.FillComponentComboBox; - AddControlCode(NewCI.Control); - - SelectOnlyThisComponent(TComponent(NewCI.Control)); - Writeln('Calling ControlClick with nil from MouseUpOnControl'); - FMainIDE.ControlClick(FMainIDE.Notebook1); //this resets it to the mouse. - FMainIDE.SetDesigning(FCustomForm,True); + if Assigned(FOnSetDesigning) then + FOnSetDesigning(Self,NewCI.Control,True); + if Assigned(FOnComponentListChanged) then + FOnComponentListChanged(Self); + if Assigned(FOnAddComponent) then + FOnAddComponent(Self,NewCI.Control,SelectedCompClass); + SelectOnlyThisComponent(TComponent(NewCI.Control)); + Writeln('Calling ControlClick with nil from MouseUpOnControl'); + if not (ssCtrl in Shift) then + if Assigned(FOnUnselectComponentClass) then + // this resets it to the mouse. (= selection tool) + FOnUnselectComponentClass(Self); + if Assigned(FOnSetDesigning) then FOnSetDesigning(Self,FCustomForm,True); end; end; MouseDownControl:=nil; +writeln('[TDesigner.MouseUpOnControl] END'); end; - - -Procedure TDesigner.MouseMoveOnControl(Sender : TControl; var Message : TLMessage); +Procedure TDesigner.MouseMoveOnControl(Sender : TControl; var Message : TLMMouse); const mk_lbutton = 1; mk_rbutton = 2; @@ -306,55 +393,53 @@ const mk_control = 8; mk_mbutton = $10; var - CaptureGrabber : TGrabber; Shift : TShiftState; - X,Y : Integer; + FormOrigin, SenderOrigin:TPoint; + SenderParentForm:TCustomForm; + MouseX, MouseY :integer; Begin + if MouseDownControl=nil then exit; -// if assigned(MouseDownControl) and (MOuseDownControl <> Sender) then Exit; - Writeln('MouseMoveOnControl'); - X :=TLMMouse(Message).Pos.x; - Y := TLMMouse(Message).Pos.Y; - Writeln('MousePos'); - Writeln(Format('X,y = %d,%d',[Mouse.CursorPos.X,MOuse.CursorPos.Y])); - Writeln('X and Y are '+inttostr(x)+','+inttostr(y)); - If (sender is TControl) then Begin - Writeln('Sender is '+TControl(sender).Name); - Writeln('Left is '+Inttostr(TControl(sender).Left)); - Writeln('Width is '+Inttostr(TControl(sender).Width)); - Writeln('Top is '+Inttostr(TControl(sender).Top)); - Writeln('Height is '+Inttostr(TControl(sender).Height)); - end; - if Assigned(MouseDownControl) then Writeln('MouseDownControl is '+TCOntrol(MouseDownControl).Name); + SenderParentForm:=GetParentForm(Sender); + if SenderParentForm=nil then exit; + FormOrigin:=SenderParentForm.ClientOrigin; + SenderOrigin:=Sender.ClientOrigin; + MouseX:=Message.Pos.X+SenderOrigin.X-FormOrigin.X; + MouseY:=Message.Pos.Y+SenderOrigin.Y-FormOrigin.Y; + + if (Message.keys and MK_LButton) = MK_LButton then begin + Write('TDesigner.MouseMoveOnControl'); + Write(' Cur=',MouseX,',',MouseY); + Write(' Msg=',Message.Pos.x,',',Message.Pos.Y); + Write(' ',Sender.Name,':',Sender.ClassName,'=',Sender.Left,',',Sender.Top); + writeln(); + end; Shift := []; if (TLMMouse(Message).keys and MK_Shift) = MK_Shift then - shift := [ssShift]; - + Shift := [ssShift]; if (TLMMouse(Message).keys and MK_Control) = MK_Control then - shift := Shift + [ssCTRL]; + Shift := Shift + [ssCTRL]; - CaptureGrabber:=GetCaptureGrabber; - if CaptureGrabber<>nil then begin - CaptureGrabber.CaptureMouseMove(TControl(Sender),Shift,X,Y); + if ControlSelection.ActiveGrabber<>nil then begin + if (Message.keys and MK_LButton) = MK_LButton then begin + ControlSelection.SizeSelection(MouseX-MouseDownPos.X, MouseY-LastMouseMovePos.Y); + if Assigned(FOnPropertiesChanged) then + FOnPropertiesChanged(Self); + end; end else begin - if Assigned(MouseDownControl) then begin - if FMainIDE.SelectedComponent = nil then begin - // mouse pointer button pressed - { if not (Sender is TCustomForm) then} begin - // move selection - Writeln('moving stuff'); - { if not(X in ([0 ..(TControl(sender).Width)])) or - not(Y in ([0 ..(TControl(sender).Height)])) then - exit; } - ControlSelection.MoveSelection(X-LastMouseMovePos.X, Y-LastMouseMovePos.Y); -// ControlSelection.MoveContent(X-LastMouseMovePos.X, Y-LastMouseMovePos.Y); - - LastMouseMovePos:=Point(X,Y); - end; - end; + if (Message.keys and MK_LButton) = MK_LButton then begin + if (ControlSelection.Count>=1) + and not (ControlSelection[0].Control is TCustomForm) then begin + // move selection + ControlSelection.MoveSelection( + MouseX-MouseDownPos.X, MouseY-MouseDownPos.Y); + if Assigned(FOnPropertiesChanged) then + FOnPropertiesChanged(Self); end; end; + end; + LastMouseMovePos:=Point(MouseX,MouseY); end; { @@ -362,85 +447,62 @@ end; } { Handles the keydown messages. DEL deletes the selected controls, CTRL-UPARROR/DOWNARROW - moves the selction up one, etc. + moves the selection up one, etc. } Procedure TDesigner.KeyDown(Sender : TControl; Message:TLMKEY); var I : Integer; - Continue : Boolean; Shift : TShiftState; Begin Writeln('KEYDOWN'); -with MEssage do + with MEssage do Begin - Writeln('CHARCODE = '+inttostr(charcode)); - Writeln('KEYDATA = '+inttostr(KeyData)); + Writeln('CHARCODE = '+inttostr(charcode)); + Writeln('KEYDATA = '+inttostr(KeyData)); end; -Shift := KeyDataToShiftState(Message.KeyData); - -if Message.CharCode = 46 then //DEL KEY - begin - Continue := True; - While Continue do - Begin - Continue := False; - for I := 0 to FCustomForm.ComponentCount-1 do - Begin - Writeln('I = '+inttostr(i)); - if (FCustomForm.Components[i] is TControl) and - ControlSelection.IsSelected(TControl(FCustomForm.Components[i])) then - Begin - Continue := True; - RemoveControl(TControl(FCustomForm.Components[i])); - Break; - end; - end; - End; - SelectOnlythisComponent(FCustomForm); - - end - else -if Message.CharCode = 38 then //UP ARROW - Begin - if (ssCtrl in Shift) then - NudgeControl(0,-1) - else - if (ssShift in Shift) then - NudgeSize(0,-1); - end - else -if Message.CharCode = 40 then //DOWN ARROW - Begin - if (ssCtrl in Shift) then - NudgeControl(0,1) - else - if (ssShift in Shift) then - NudgeSize(0,1); - end - else -if Message.CharCode = 39 then //RIGHT ARROW - Begin - if (ssCtrl in Shift) then - NudgeControl(1,0) - else - if (ssShift in Shift) then - NudgeSize(1,0); - end - else -if Message.CharCode = 37 then //LEFT ARROW - Begin - if (ssCtrl in Shift) then - NudgeControl(-1,0) - else - if (ssShift in Shift) then - NudgeSize(-1,0); - end; - - - + Shift := KeyDataToShiftState(Message.KeyData); + if Message.CharCode = 46 then //DEL KEY + begin + for I := ControlSelection.Count-1 downto 0 do Begin + Writeln('I = '+inttostr(i)); + RemoveControl(ControlSelection.Items[I].Control); + End; + SelectOnlythisComponent(FCustomForm); + end + else + if Message.CharCode = 38 then //UP ARROW + Begin + if (ssCtrl in Shift) then + NudgeControl(0,-1) + else if (ssShift in Shift) then + NudgeSize(0,-1); + end + else if Message.CharCode = 40 then //DOWN ARROW + Begin + if (ssCtrl in Shift) then + NudgeControl(0,1) + else if (ssShift in Shift) then + NudgeSize(0,1); + end + else + if Message.CharCode = 39 then //RIGHT ARROW + Begin + if (ssCtrl in Shift) then + NudgeControl(1,0) + else if (ssShift in Shift) then + NudgeSize(1,0); + end + else + if Message.CharCode = 37 then //LEFT ARROW + Begin + if (ssCtrl in Shift) then + NudgeControl(-1,0) + else if (ssShift in Shift) then + NudgeSize(-1,0); + end; end; @@ -448,49 +510,34 @@ end; Procedure TDesigner.KeyUp(Sender : TControl; Message:TLMKEY); Begin Writeln('KEYUp'); -with MEssage do + with MEssage do Begin - Writeln('CHARCODE = '+inttostr(charcode)); - Writeln('KEYDATA = '+inttostr(KeyData)); + Writeln('CHARCODE = '+inttostr(charcode)); + Writeln('KEYDATA = '+inttostr(KeyData)); end; end; function TDesigner.IsDesignMsg(Sender: TControl; var Message: TLMessage): Boolean; Begin -result := false; -if ((Message.msg >= LM_MOUSEFIRST) and (Message.msg <= LM_MOUSELAST)) then -Result := true -else -if ((Message.msg >= LM_KeyFIRST) and (Message.msg <= LM_KeyLAST)) then - Begin - Writeln('KEY MESSAGE in IsDesignMsg'); - if MEssage.MSG = LM_KEYDOWN then KeyDown(Sender,TLMKey(Message)) - else - if MEssage.MSG = LM_KEYUP then KeyUP(Sender,TLMKey(Message)); - Result := true; + result := false; + if csDesigning in Sender.ComponentState then begin + + if ((Message.msg >= LM_MOUSEFIRST) and (Message.msg <= LM_MOUSELAST)) then + Result := true + else + if ((Message.msg >= LM_KeyFIRST) and (Message.msg <= LM_KeyLAST)) then + Result:=true; + + case Message.MSG of + LM_PAINT: Result:=Paint(Sender,TLMPAINT(Message)); + LM_KEYDOWN: KeyDown(Sender,TLMKey(Message)); + LM_KEYUP: KeyUP(Sender,TLMKey(Message)); + LM_LBUTTONDOWN: MouseDownOnControl(sender,TLMMouse(Message)); + LM_LBUTTONUP: MouseUpOnControl(sender,TLMMouse(Message)); + LM_MOUSEMOVE: MouseMoveOnControl(Sender, TLMMouse(Message)); end; - - -if (Message.msg=LM_LBUTTONDOWN) then - begin - MouseDownonControl(sender,message); - end -else -if (Message.msg=LM_LBUTTONUP) then - begin - MouseUPONControl(sender,message); - end -else -if Message.msg = LM_MOUSEMOVE then - MouseMoveonCOntrol(Sender, Message) - - - -{if Result then Writeln('It IS a design message') -else -Writeln('It IS NOT a design message'); - } + end; end; procedure TDesigner.LoadFile(FileName: string); @@ -503,13 +550,6 @@ Begin end; - -Procedure TDesigner.AddControlCode(Control : TComponent); -Begin -FSourceEditor.AddControlCode(Control); -end; - - procedure TDesigner.Notification(AComponent: TComponent; Operation: TOperation); Begin if Operation = opInsert then @@ -530,32 +570,32 @@ procedure TDesigner.PaintGrid; var x,y : integer; begin - with FCustomForm do - Begin - canvas.Pen.Color := clGray; - x := left; - while x <= left + width do - begin - y := Top; - while y <= top+height do - begin - //if Controlatpos(TPOINT([x,y]),True) = nil then - Canvas.Rectangle(x-left,y-top,x-left+1,y-top); - Inc(y, GridPoints.Y); - end; - Inc(x, GridPoints.X); - end; +writeln('PaintGrid DC=',FCustomForm.Canvas.Handle,' ',Cardinal(Pointer(FCustomForm))); + with FCustomForm.Canvas do begin + Pen.Color := clGray; + x := 0; + while x <= FCustomForm.Width do begin + y := 0; + while y <= FCustomForm.Height do begin + //if Controlatpos(Point(x,y),True) = nil then + MoveTo(x,y); + LineTo(x+1,y); + Inc(y, GridPoints.Y); + end; + Inc(x, GridPoints.X); end; + end; end; -procedure TDesigner.ValidateRename(AComponent: TComponent; const CurName, NewName: string); +procedure TDesigner.ValidateRename(AComponent: TComponent; + const CurName, NewName: shortstring); Begin end; function TDesigner.GetIsControl: Boolean; Begin -Result := True; + Result := True; end; procedure TDesigner.SetIsControl(Value: Boolean); diff --git a/ide/codetools.pp b/ide/codetools.pp index e8fba4ed87..6d462927c5 100644 --- a/ide/codetools.pp +++ b/ide/codetools.pp @@ -73,6 +73,15 @@ function FindResourceInCode(Source:string; AddCode:string; var Position,EndPosition:integer):boolean; function AddResourceCode(var Source:string; AddCode:string):boolean; +// form components +function FindFormClassDefinitionInSource(Source:string; FormClassName:string; + var FormClassNameStartPos, FormBodyStartPos: integer + ):boolean; +function FindFormComponentInSource(Source: string; FormBodyStartPos: integer; + ComponentName, ComponentClassName: string): integer; +function AddFormComponentToSource(var Source:string; FormBodyStartPos: integer; + ComponentName, ComponentClassName: string): boolean; + // code search function SearchCodeInSource(Source,Find:string; StartPos:integer; var EndFoundPosition:integer; CaseSensitive:boolean):integer; @@ -622,6 +631,89 @@ begin Result:=true; end; +function FindFormClassDefinitionInSource(Source:string; FormClassName:string; + var FormClassNameStartPos, FormBodyStartPos: integer + ):boolean; +var AtomEnd,AtomStart: integer; +begin + Result:=false; + if FormClassName='' then exit; + repeat + FormClassNameStartPos:=SearchCodeInSource(Source, + FormClassName+'=class(TForm)',1,FormBodyStartPos,false); + if FormClassNameStartPos<1 then exit; + AtomEnd:=FormBodyStartPos; + until ReadNextPascalAtom(Source,AtomEnd,AtomStart)<>';'; + Result:=true; +end; + +function FindFormComponentInSource(Source: string; FormBodyStartPos: integer; + ComponentName, ComponentClassName: string): integer; +var AtomStart, OldPos: integer; + Atom: string; +begin + ComponentName:=lowercase(ComponentName); + ComponentClassName:=lowercase(ComponentClassName); + Result:=FormBodyStartPos; + repeat + Atom:=lowercase(ReadNextPascalAtom(Source,Result,AtomStart)); + if (Atom='public') or (Atom='published') or (Atom='private') or (Atom='end') + or (Atom='protected') or (Atom='') then begin + Result:=-1; + exit; + end; + OldPos:=Result; + if (lowercase(ReadNextPascalAtom(Source,Result,AtomStart))=ComponentName) + and (ReadNextPascalAtom(Source,Result,AtomStart)=':') + and (lowercase(ReadNextPascalAtom(Source,Result,AtomStart))=ComponentClassName) + and (ReadNextPascalAtom(Source,Result,AtomStart)=';') then begin + Result:=OldPos; + exit; + end; + until Result>length(Source); + Result:=-1; +end; + +function AddFormComponentToSource(var Source:string; FormBodyStartPos: integer; + ComponentName, ComponentClassName: string): boolean; +var Position, AtomStart: integer; + Atom: string; + PriorSpaces, NextSpaces: string; +begin + Result:=false; + if FindFormComponentInSource(Source,FormBodyStartPos + ,ComponentName,ComponentClassName)>0 then begin + Result:=true; + exit; + end; + repeat + // find a good position to insert the component + // in front of next section and in front of procedures/functions + Position:=FormBodyStartPos; + Atom:=lowercase(ReadNextPascalAtom(Source,Position,AtomStart)); + if (Atom='procedure') or (Atom='function') or (Atom='end') or (Atom='class') + or (Atom='constructor') or (Atom='destructor') + or (Atom='public') or (Atom='private') or (Atom='protected') + or (Atom='published') or (Atom='class') or (Atom='property') then begin + // insert component definition in source + if (Atom='public') or (Atom='private') or (Atom='protected') + or (Atom='published') then begin + PriorSpaces:=' '; + NextSpaces:=' '; + end else begin + PriorSpaces:=''; + NextSpaces:=' '; + end; + Source:=copy(Source,1,AtomStart-1) + +PriorSpaces+ComponentName+': '+ComponentClassName+';'+EndOfLine + +NextSpaces+copy(Source,AtomStart,length(Source)-AtomStart+1); + Result:=true; + exit; + end; + until Position>length(Source); + Result:=false; +end; + function SearchCodeInSource(Source,Find:string; StartPos:integer; var EndFoundPosition:integer; CaseSensitive:boolean):integer; // search pascal atoms of Find in Source diff --git a/ide/compreg.pp b/ide/compreg.pp index 81b0165e3e..55c3fae109 100644 --- a/ide/compreg.pp +++ b/ide/compreg.pp @@ -31,7 +31,7 @@ type property Page:TRegisteredComponentPage read FPage; property ComponentClass:TComponentClass read FComponentClass; property IndexInPage:integer read FIndexInPage; - property UnitName:ShortString; + property UnitName:ShortString read FUnitName; constructor Create(APage:TRegisteredComponentPage; TheIndexInPage:integer; AUnitName:ShortString; AComponentClass:TComponentClass); end; diff --git a/ide/customformeditor.pp b/ide/customformeditor.pp index 05216c2a36..61ade22528 100644 --- a/ide/customformeditor.pp +++ b/ide/customformeditor.pp @@ -17,10 +17,9 @@ * * ***************************************************************************/ } -{$H+} unit CustomFormEditor; -{$mode objfpc} +{$mode objfpc}{$H+} interface @@ -47,27 +46,27 @@ each control that's dropped onto the form protected Function GetPPropInfobyIndex(Index : Integer) : PPropInfo; - Function GetPPropInfobyName(Name : String) : PPropInfo; + Function GetPPropInfobyName(Name : ShortString) : PPropInfo; public constructor Create; destructor Destroy; override; - Function GetComponentType : String; override; + Function GetComponentType : ShortString; override; Function GetComponentHandle : LongInt; override; Function GetParent : TIComponentInterface; override; Function IsTControl : Boolean; override; Function GetPropCount : Integer; override; Function GetPropType(Index : Integer) : TTypeKind; override; Function GetPropTypeInfo(Index : Integer) : PTypeInfo; - Function GetPropName(Index : Integer) : String; override; - Function GetPropTypeName(Index : Integer) : String; override; - Function GetPropTypebyName(Name : String) : TTypeKind; override; + Function GetPropName(Index : Integer) : ShortString; override; + Function GetPropTypeName(Index : Integer) : ShortString; override; + Function GetPropTypebyName(Name : ShortString) : TTypeKind; override; Function GetPropValue(Index : Integer; var Value) : Boolean; override; - Function GetPropValuebyName(Name: String; var Value) : Boolean; override; + Function GetPropValuebyName(Name: ShortString; var Value) : Boolean; override; Function SetProp(Index : Integer; const Value) : Boolean; override; - Function SetPropbyName(Name : String; const Value) : Boolean; override; + Function SetPropbyName(Name : ShortString; const Value) : Boolean; override; Function GetControlCount: Integer; override; @@ -105,7 +104,7 @@ TCustomFormEditor Procedure DeleteControl(Value : TComponent); Function Filename : String; override; Function FormModified : Boolean; override; - Function FindComponentByName(const Name : String) : TIComponentInterface; override; + Function FindComponentByName(const Name : ShortString) : TIComponentInterface; override; Function FindComponent(AComponent: TComponent): TIComponentInterface; override; Function GetFormComponent : TIComponentInterface; override; // Function CreateComponent(CI : TIComponentInterface; TypeName : String; @@ -115,7 +114,8 @@ TCustomFormEditor TypeClass : TComponentClass; X,Y,W,H : Integer): TIComponentInterface; override; Function NewFormFromLFM(_Filename : String): TCustomform; Procedure ClearSelected; - property SelectedComponents : TComponentSelectionList read FSelectedComponents write FSelectedComponents; + property SelectedComponents : TComponentSelectionList + read FSelectedComponents write FSelectedComponents; property Obj_Inspector : TObjectInspector read FObj_Inspector write FObj_Inspector; end; @@ -156,7 +156,7 @@ writeln('Index = '+inttostr(PRI^.index)); tkAString, tkWString : Begin Writeln('String...'); - SetStrProp(FControl,PRI,String(Value)); + SetStrProp(FControl,PRI,ShortString(Value)); Result := True; end; tkInteger, @@ -195,7 +195,7 @@ Result := True; tkAString, tkWString : Begin Writeln('Get String...'); - String(Value) := GetStrProp(FControl,PRI); + ShortString(Value) := GetStrProp(FControl,PRI); Writeln('The string returned is '+String(value)); Writeln('*Get String...'); end; @@ -243,7 +243,7 @@ Begin Freemem(PP); end; -Function TComponentInterface.GetPPropInfoByName(Name:String): PPropInfo; +Function TComponentInterface.GetPPropInfoByName(Name:ShortString): PPropInfo; var PT : PTypeData; PP : PPropList; @@ -268,7 +268,7 @@ Begin Freemem(PP); end; -Function TComponentInterface.GetComponentType : String; +Function TComponentInterface.GetComponentType : ShortString; Begin Result:=FControl.ClassName; end; @@ -340,11 +340,11 @@ end; {This returns "Integer" or "Boolean"} -Function TComponentInterface.GetPropTypeName(Index : Integer) : String; +Function TComponentInterface.GetPropTypeName(Index : Integer) : ShortString; var -PT : PTypeData; -PP : PPropList; -PI : PTypeInfo; + PT : PTypeData; + PP : PPropList; + PI : PTypeInfo; Begin PI:=FControl.ClassInfo; PT:=GetTypeData(PI); @@ -359,7 +359,7 @@ end; {This returns "Left" "Align" "Visible"} -Function TComponentInterface.GetPropName(Index : Integer) : String; +Function TComponentInterface.GetPropName(Index : Integer) : ShortString; var PT : PTypeData; PP : PPropList; @@ -377,7 +377,7 @@ Begin freemem(PP); end; -Function TComponentInterface.GetPropTypebyName(Name : String) : TTypeKind; +Function TComponentInterface.GetPropTypebyName(Name : ShortString) : TTypeKind; var PT : PTypeData; PP : PPropList; @@ -411,7 +411,7 @@ PP := GetPPropInfoByIndex(Index); Result := FGetProp(PP,Value); end; -Function TComponentInterface.GetPropValuebyName(Name: String; var Value) : Boolean; +Function TComponentInterface.GetPropValuebyName(Name: ShortString; var Value) : Boolean; var PRI : PPropInfo; Begin @@ -435,7 +435,7 @@ Begin end; -Function TComponentInterface.SetPropbyName(Name : String; const Value) : Boolean; +Function TComponentInterface.SetPropbyName(Name : ShortString; const Value) : Boolean; var PRI : PPropInfo; Begin @@ -563,7 +563,8 @@ Begin Result := FModified; end; -Function TCustomFormEditor.FindComponentByName(const Name : String) : TIComponentInterface; +Function TCustomFormEditor.FindComponentByName( + const Name : ShortString) : TIComponentInterface; Var Num : Integer; Begin @@ -593,7 +594,7 @@ Begin end; Function TCustomFormEditor.CreateComponent(ParentCI : TIComponentInterface; -TypeClass : TComponentClass; X,Y,W,H : Integer): TIComponentInterface; + TypeClass : TComponentClass; X,Y,W,H : Integer): TIComponentInterface; Var Temp : TComponentInterface; TempName : String; @@ -615,9 +616,9 @@ Begin else Begin //this should be a form - NewFormIndex := JITFormList.AddNewJITForm; - if NewFormIndex >= 0 then - Temp.FControl := JITFormList[NewFormIndex]; + NewFormIndex := JITFormList.AddNewJITForm; + if NewFormIndex >= 0 then + Temp.FControl := JITFormList[NewFormIndex]; end; if Assigned(ParentCI) then @@ -638,21 +639,20 @@ Begin end; end; - if ParentCI <> nil then - Begin + if ParentCI <> nil then Begin Writeln('ParentCI <> nil'); TempName := Temp.FControl.ClassName; delete(TempName,1,1); writeln('TempName is '''+TempName+''''); Num := 0; Found := True; - While Found do - Begin + While Found do Begin Found := False; inc(num); for I := 0 to FComponentInterfaceList.Count-1 do begin - DummyComponent:=TComponent(TComponentInterface(FComponentInterfaceList.Items[i]).FControl); + DummyComponent:=TComponent(TComponentInterface( + FComponentInterfaceList.Items[i]).FControl); if UpCase(DummyComponent.Name)=UpCase(TempName+IntToStr(Num)) then begin Found := True; @@ -662,7 +662,7 @@ Begin end; Temp.FControl.Name := TempName+IntToStr(Num); Writeln('TempName + num = '+TempName+Inttostr(num)); - end; + end; if (Temp.FControl is TControl) then Begin diff --git a/ide/main.pp b/ide/main.pp index 9bbf53e90e..9961b11a91 100644 --- a/ide/main.pp +++ b/ide/main.pp @@ -114,7 +114,7 @@ type itmEnvEditorOptions: TMenuItem; CheckBox1 : TCheckBox; - Notebook1 : TNotebook; + ComponentNotebook : TNotebook; cmdTest: TButton; cmdTest2: TButton; Label2 : TLabel; @@ -205,6 +205,7 @@ type function DoViewUnitsAndForms(OnlyForms: boolean): TModalResult; // project(s) + property Project: TProject read fProject write fProject; function DoNewProject(NewProjectType:TProjectType):TModalResult; function DoSaveProject(SaveAs:boolean):TModalResult; function DoCloseProject:TModalResult; @@ -237,9 +238,18 @@ type procedure FormPaint(Sender : TObject); procedure LoadFormFromFile(Value : String); + // form editor and designer property SelectedComponent : TRegisteredComponent read FSelectedComponent write FSelectedComponent; - property Project: TProject read fProject write fProject; + procedure OnDesignerGetSelectedComponentClass(Sender: TObject; + var RegisteredComponent: TRegisteredComponent); + procedure OnDesignerUnselectComponentClass(Sender: TObject); + procedure OnDesignerSetDesigning(Sender: TObject; Component: TComponent; + Value: boolean); + procedure OnDesignerComponentListChanged(Sender: TObject); + procedure OnDesignerPropertiesChanged(Sender: TObject); + procedure OnDesignerAddComponent(Sender: TObject; Component: TComponent; + ComponentClass: TRegisteredComponent); procedure SaveDesktopSettings(TheEnvironmentOptions: TEnvironmentOptions); procedure LoadDesktopSettings(TheEnvironmentOptions: TEnvironmentOptions); @@ -345,15 +355,16 @@ begin Bitmap1 := TBitmap.Create; Bitmap1.Handle := CreatePixmapIndirect(@IMGOK_Check, ColorToRGB(clBtnFace)); - Notebook1 := TNotebook.Create(Self); - Notebook1.Parent := Self; - Notebook1.Align := alBottom; - Notebook1.Left := 1; -// Notebook1.Top :=50+ mnuBarMain.Top+MnuBarMain.Height + 2; - Notebook1.Top :=50+ 2; - Notebook1.Width := ClientWidth; - Notebook1.Height := 100; //ClientHeight - Notebook1.Top; - + ComponentNotebook := TNotebook.Create(Self); + with ComponentNotebook do begin + Parent := Self; + Align := alBottom; + Left := 1; +// ComponentNotebook.Top :=50+ MnuBarMain.Top+MnuBarMain.Height + 2; + Top :=50+ 2; + Width := Self.ClientWidth; + Height := 100; //Self.ClientHeight - ComponentNotebook.Top; + end; SelectionPointerPixmap:=LoadSpeedBtnPixMap('tmouse'); PageCount := 0; @@ -363,12 +374,12 @@ begin if RegCompPage.Name <> '' then Begin if (pagecount = 0) then - Notebook1.Pages.Strings[pagecount] := RegCompPage.Name - else Notebook1.Pages.Add(RegCompPage.Name); + ComponentNotebook.Pages.Strings[pagecount] := RegCompPage.Name + else ComponentNotebook.Pages.Add(RegCompPage.Name); GlobalMouseSpeedButton := TSpeedButton.Create(Self); with GlobalMouseSpeedButton do Begin - Parent := Notebook1.Page[PageCount]; + Parent := ComponentNotebook.Page[PageCount]; Enabled := True; Width := 25; Height := 25; @@ -386,7 +397,7 @@ begin IDEComponent := TIDEComponent.Create; IdeComponent.RegisteredComponent := RegComp; Writeln('Name is '+RegComp.ComponentClass.ClassName); - IDEComponent._SpeedButton(Self,Notebook1.Page[PageCount]); + IDEComponent._SpeedButton(Self,ComponentNotebook.Page[PageCount]); IDEComponent.SpeedButton.OnClick := @ControlClick; IDEComponent.SpeedButton.Hint := RegComp.ComponentClass.ClassName; IDEComponent.SpeedButton.Name := IDEComponent.SpeedButton.Hint; @@ -395,10 +406,10 @@ begin inc(PageCount); end; end; - Notebook1.PageIndex := 0; // Set it to the first page - Notebook1.Show; - Notebook1.OnPageChanged := @ControlClick; - Notebook1.Name := 'Notebook1'; + ComponentNotebook.PageIndex := 0; // Set it to the first page + ComponentNotebook.Show; + ComponentNotebook.OnPageChanged := @ControlClick; + ComponentNotebook.Name := 'ComponentNotebook'; ViewUnitsSpeedBtn := TSpeedButton.Create(Self); with ViewUnitsSpeedBtn do @@ -631,7 +642,7 @@ end; procedure TMainIDE.OIOnAddAvailableComponent(AComponent:TComponent; var Allowed:boolean); begin - Allowed:=(not (AComponent is TGrabber)); + //Allowed:=(not (AComponent is TGrabber)); end; procedure TMainIDE.OIOnSelectComponent(AComponent:TComponent); @@ -1054,13 +1065,13 @@ begin := False else begin Temp := nil; - for i := 0 to Notebook1.Page[Notebook1.Pageindex].ControlCount-1 do + for i := 0 to ComponentNotebook.Page[ComponentNotebook.Pageindex].ControlCount-1 do begin if CompareText( - TControl(Notebook1.Page[Notebook1.Pageindex].Controls[I]).Name - ,'GlobalMouseSpeedButton'+inttostr(Notebook1.Pageindex)) = 0 then + TControl(ComponentNotebook.Page[ComponentNotebook.Pageindex].Controls[I]).Name + ,'GlobalMouseSpeedButton'+inttostr(ComponentNotebook.Pageindex)) = 0 then begin - temp := TControl(Notebook1.Page[Notebook1.Pageindex].Controls[i]); + temp := TControl(ComponentNotebook.Page[ComponentNotebook.Pageindex].Controls[i]); Break; end; end; @@ -1068,7 +1079,7 @@ begin TSpeedButton(Temp).down := False else Writeln('*****************ERROR - Control ', - 'GlobalMouseSpeedButton',inttostr(Notebook1.Pageindex),' not found'); + 'GlobalMouseSpeedButton',inttostr(ComponentNotebook.Pageindex),' not found'); end; if IDECOmp <> nil then Begin //draw this button down @@ -1077,13 +1088,13 @@ begin end else begin SelectedComponent := nil; Temp := nil; - for i := 0 to Notebook1.Page[Notebook1.Pageindex].ControlCount-1 do + for i := 0 to ComponentNotebook.Page[ComponentNotebook.Pageindex].ControlCount-1 do begin if CompareText( - TControl(Notebook1.Page[Notebook1.Pageindex].Controls[I]).Name - ,'GlobalMouseSpeedButton'+inttostr(Notebook1.Pageindex)) = 0 then + TControl(ComponentNotebook.Page[ComponentNotebook.Pageindex].Controls[I]).Name + ,'GlobalMouseSpeedButton'+inttostr(ComponentNotebook.Pageindex)) = 0 then begin - temp := TControl(Notebook1.Page[Notebook1.Pageindex].Controls[i]); + temp := TControl(ComponentNotebook.Page[ComponentNotebook.Pageindex].Controls[i]); Break; end; end; @@ -1091,7 +1102,7 @@ begin TSpeedButton(Temp).down := True else Writeln('*****************ERROR - Control ' - +'GlobalMouseSpeedButton'+inttostr(Notebook1.Pageindex)+' not found'); + +'GlobalMouseSpeedButton'+inttostr(ComponentNotebook.Pageindex)+' not found'); end; end else @@ -1104,13 +1115,13 @@ begin := False; SelectedComponent := nil; Temp := nil; - for i := 0 to Notebook1.Page[Notebook1.Pageindex].ControlCount-1 do + for i := 0 to ComponentNotebook.Page[ComponentNotebook.Pageindex].ControlCount-1 do begin if CompareText( - TControl(Notebook1.Page[Notebook1.Pageindex].Controls[I]).Name - ,'GlobalMouseSpeedButton'+inttostr(Notebook1.Pageindex)) = 0 then + TControl(ComponentNotebook.Page[ComponentNotebook.Pageindex].Controls[I]).Name + ,'GlobalMouseSpeedButton'+inttostr(ComponentNotebook.Pageindex)) = 0 then begin - temp := TControl(Notebook1.Page[Notebook1.Pageindex].Controls[i]); + temp := TControl(ComponentNotebook.Page[ComponentNotebook.Pageindex].Controls[i]); Break; end; end; @@ -1118,7 +1129,7 @@ begin TSpeedButton(Temp).down := True else Writeln('*****************ERROR - Control ' - +'GlobalMouseSpeedButton'+inttostr(Notebook1.Pageindex)+' not found'); + +'GlobalMouseSpeedButton'+inttostr(ComponentNotebook.Pageindex)+' not found'); end; Writeln('Exiting ControlClick'); end; @@ -1295,8 +1306,15 @@ end; Procedure TMainIDE.SetDefaultsforForm(aForm : TCustomForm); Begin aForm.Designer := TDesigner.Create(aForm); - TDesigner(aForm.Designer).MainIDE := Self; - TDesigner(aForm.Designer).FormEditor := FormEditor1; + with TDesigner(aForm.Designer) do begin + FormEditor := FormEditor1; + OnGetSelectedComponentClass:=@OnDesignerGetSelectedComponentClass; + OnUnselectComponentClass:=@OnDesignerUnselectComponentClass; + OnSetDesigning:=@OnDesignerSetDesigning; + OnComponentListChanged:=@OnDesignerComponentListChanged; + OnPropertiesChanged:=@OnDesignerPropertiesChanged; + OnAddComponent:=@OnDesignerAddComponent; + end; end; @@ -2683,6 +2701,92 @@ begin end; end; +procedure TMainIDE.OnDesignerGetSelectedComponentClass(Sender: TObject; + var RegisteredComponent: TRegisteredComponent); +begin + RegisteredComponent:=SelectedComponent; +end; + +procedure TMainIDE.OnDesignerUnselectComponentClass(Sender: TObject); +begin + ControlClick(ComponentNoteBook); +end; + +procedure TMainIDE.OnDesignerSetDesigning(Sender: TObject; + Component: TComponent; Value: boolean); +begin + SetDesigning(Component,Value); +end; + +procedure TMainIDE.OnDesignerComponentListChanged(Sender: TObject); +begin + ObjectInspector1.FillComponentComboBox; +end; + +procedure TMainIDE.OnDesignerPropertiesChanged(Sender: TObject); +begin + ObjectInspector1.RefreshPropertyValues; +end; + +procedure TMainIDE.OnDesignerAddComponent(Sender: TObject; + Component: TComponent; ComponentClass: TRegisteredComponent); +var i: integer; + ActiveForm: TCustomForm; + ActiveUnitInfo: TUnitInfo; + SrcTxt: string; + SrcTxtChanged: boolean; + ActiveSrcEdit: TSourceEditor; + FormClassName: string; + FormClassNameStartPos, FormBodyStartPos: integer; +begin + ActiveForm:=TDesigner(Sender).Form; + if ActiveForm=nil then begin + writeln('[TMainIDE.OnDesignerAddComponent] Error: TDesigner without a form'); + halt; + end; + // find source for form + i:=Project.UnitCount-1; + while (i>=0) do begin + if (Project.Units[i].Loaded) + and (Project.Units[i].Form=ActiveForm) then break; + dec(i); + end; + if i<0 then begin + writeln('[TMainIDE.OnDesignerAddComponent] Error: form without source'); + halt; + end; + ActiveUnitInfo:=Project.Units[i]; + SrcTxt:=ActiveUnitInfo.Source.Text; + SrcTxtChanged:=false; + // add needed unit to source + SrcTxtChanged:=SrcTxtChanged + or AddToInterfaceUsesSection(SrcTxt,ComponentClass.UnitName,''); + // add component definition to form source + FormClassName:=ActiveForm.ClassName; + if FindFormClassDefinitionInSource(SrcTxt,FormClassName, + FormClassNameStartPos, FormBodyStartPos) then begin + if AddFormComponentToSource(SrcTxt,FormBodyStartPos, + Component.Name, Component.ClassName) then begin + SrcTxtChanged:=true; + end else begin + Application.MessageBox('No insert point in source for the new component found.' + ,'Code tool failure',mb_ok); + end; + end else begin + // the form is not mentioned in the source? + // ignore silently + end; + // update source + if SrcTxtChanged then begin + ActiveUnitInfo.Source.Text:=SrcTxt; + ActiveUnitInfo.Modified:=true; + ActiveSrcEdit:=SourceNoteBook.FindSourceEditorWithPageIndex( + ActiveUnitInfo.EditorIndex); + ActiveSrcEdit.EditorComponent.Lines.Text:=SrcTxt; + ActiveSrcEdit.EditorComponent.Modified:=true; + end; +end; + initialization {$I images/laz_images.lrs} @@ -2695,8 +2799,8 @@ end. { ============================================================================= $Log$ - Revision 1.73 2001/03/12 09:34:52 lazarus - MG: added transfermacros, renamed dlgmessage.pp to msgview.pp + Revision 1.74 2001/03/12 18:57:31 lazarus + MG: new designer and controlselection code Revision 1.68 2001/03/03 11:06:15 lazarus added project support, codetools diff --git a/ide/uniteditor.pp b/ide/uniteditor.pp index 7976c48fd5..f9219b4cdc 100644 --- a/ide/uniteditor.pp +++ b/ide/uniteditor.pp @@ -1536,7 +1536,7 @@ begin end; // load active breakpoint image Pixmap1:=TPixMap.Create; - //Pixmap1.TransparentColor:=clBtnFace; + Pixmap1.TransparentColor:=clBtnFace; if not LoadPixmapRes('ActiveBreakPoint',Pixmap1) then LoadPixmapRes('default',Pixmap1); MarksImgList.Add(Pixmap1,nil);