I am developing a new WYSIWYG editor for components that are not inherited from TWinControl nor TControl.
It is fine (can resize, move, change property via Object Inspector and also drop a new component from Components Palette),
until I found that is not all Lazarus's feature worked properly for non-LCL componets.
For example: the Paste command always places copied component at root ( its should placed inside the current selected component)
, and drag-drop within Component Tree also disallowed.
AFAIK, the problem is because my component-editor rely only at TDesignerMediator, but TDesignerMediator was not involved on every Lazarus activities.
What I want is let TDesignerMediator decide what should going right when Lazarus is editing a non-LCL components.
For example, there is no chance to involve TDesignerMediator in \lazarus_trunk\components\identf\componenttreeview.pas line:403 :
procedure TComponentTreeView.DragOver(Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
var
...
begin
AcceptContainer := False;
AcceptControl := True;
..
if Assigned(ParentNode) and Assigned(ParentNode.Data) then
begin
AnObject := TObject(ParentNode.Data);
if (AnObject is TWinControl) then
begin
if ControlAcceptsStreamableChildComponent(TWinControl(AControl),
TComponentClass(AnObject.ClassType),aLookupRoot)
then begin
AContainer := TPersistent(AnObject);
//DebugLn(['TComponentTreeView.DragOver AContainer=',DbgSName(AContainer)]);
AcceptContainer := True;
end;
end
else
if (AnObject is TCollection) then
begin
// it is allowed to move container items inside the container
AContainer := TPersistent(AnObject);
AcceptContainer := True;
end;
end;
if AcceptContainer then
begin
Node := GetFirstMultiSelected;
while Assigned(Node) and AcceptControl do
begin
AnObject := TObject(Node.Data);
// don't allow to move ancestor components
if (AnObject is TComponent) and
(csAncestor in TComponent(AnObject).ComponentState) then break;
if (AnObject is TControl) then
begin
if AnObject = AContainer then break;
if not (AContainer is TWinControl) then break;
// check if new parent allows this control class
if not TWinControl(AContainer).CheckChildClassAllowed(AnObject.ClassType, False) then
break;
// check if one of the parent of the container is the control itself
if AControl.IsParentOf(TWinControl(AContainer)) then break;
// do not move children of a restricted parent to another parent
// e.g. TPage of TPageControl
if (AControl.Parent <> nil) and (AControl.Parent <> AContainer) and
(not (csAcceptsControls in AControl.Parent.ControlStyle)) then
break;
end
else
if (AnObject is TCollectionItem) then
begin
if AnObject = AContainer then break;
if not (AContainer is TCollection) then
break;
if TCollectionItem(AnObject).Collection <> TCollection(AContainer) then
break;
end;
Node := Node.GetNextMultiSelected;
end;
AcceptControl := (Node = nil);
end;
Accept := AcceptContainer and AcceptControl;
inherited DragOver(Source, X, Y, State, Accept);
Accept := AcceptContainer and AcceptControl and ((OnDragOver=nil) or Accept);
end;
See? there is no chance for non-TControl to decide what should go right.
There are many other sample that is similar situation in several different folder (\ide, \components\identf, \designer, )
So, my question is : How to involve/call/access the DesignerMediator "at any unit" (I mean there are different folders)? .
I guess it will start with current selected component, but really have no idea. Thanks You