My two cents:
For a long time, I've been trying to have only those units in the interface section which are abolutely needed, and to put all others into the implementation section. However, this may lead to careless design of the functionality in the units and their dependencies because circular unit references are hidden. And circular unit references are bad, they should be removed rather than hidden since when a project becomes more and more complex it will be very difficult to fix this.
Example from your editor:
You have the main form (unit1 - why don't you call it "uMainForm" or so?). And you have another unit (unit2 - I would call it "uSettingsForm") with checkboxes to control the appearance of the statusbar in the main form. This configuration is bad because unit2 needs to have unit1 in its uses clause. In my opinion, secondary forms should never use the main unit because this leads to a circular reference (because the main unit unavoidably needs to use the secondary forms, too, in order to be able to open them). Putting unit2 into the implementation section makes the project compile again, but it only hides this issue without solving the real problem.
For a correct solution ("correct" in my opinion) I would add another unit only containing settings values (and other declarations), no visual controls:
unit uSettings;
type
TSettings = record
ShowFullPathInCaption: Boolean;
ShowDate: Boolean;
ShowClock: Boolean;
EnableBackups: Boolean;
end;
var
Settings: TSettings = (
ShowFullPathInCaption: true;
ShowDate: true;
ShowClick: true;
EnableBackups: true
);
implementation
end.
Now both unit1 and unit2 will use this new unit: unit2 is the visual control to modify these settings, and unit1 will read the settings and update the statusbar. It is no longer needed that Form2 knows Form1.
There is one problem, though: How is Form1 notified that Form2 has changed the settings? For this, it is often helpful to introduce an event fired by Form2 and handled by Form1:
unit unit2;
uses
uSettings;
type
TForm2 = class(TForm)
procedure FormClose(Sender: TObject);
private
FOnSettingsChanged: TNotifyEvent;
...
public
...
property OnSettingsChanged: TNotifyEvent;
end;
procedure TForm2.FormClose(Sender: TObject);
begin
// Copy the changed settings into the Settings variable.
Settings.ShowFullPathInCaption := Checkbox1.Checked;
// etc.
// Now the event OnSettingsChanged is fired. The main form has a handler for this event (in its own unit) and this way
// it is notified of the changes without Form2 having to know Form1 explictely.
if Assigned(FOnSettingsChanged) then FOnSettingsChanged(self);
end;
unit unit1;
interface
uses
uSettings, unit2;
...
// This event is fired when Form2 is closed
procedure TForm1.SettingsChanged(Sender: TObject);
begin
// Read the Settings elements and show/hide the statusbar panels correspondingly
end;
// FORM2 SHOW
procedure TForm1.MenuItem3Click(Sender: TObject);
begin
Form2.OnSettingsChanged := @SettingsChanged; //Prepares Form1 so that it is notified when the settings have changed in Form2
Form2.Show;
end;