Mattias Gaertner schrieb:
BTW the SimpleLayout should *not* remember the bounds of *docked* forms,
instead it should retain their *undocked* bounds, for use when such a
form is undocked later.
That's just my preference: When a form is undocked it should not move.
You can send me a patch to make this optional.
In the preparation of this patch I found a problem with the Source
editor forms - they seem to have bad (default) values in
UndockWidth/Height :-(
I didn't know where to send the patch, so I'll attach it to this
message, for all interested readers. Above fix is made conditional, so
that it can be tested easily.
The attached patch addresses the
handling of multi-monitor coordinates:
- Screen coordinates and bounds (forms.pp, screen.inc)
- allow for negative coordinates in Options Window
- and in CustomCoordinatesAreValid
and using the new methods:
- using Screen.FitToMonitor instead of agnostic checks
and a minor fix:
- properly handle negative Width/Height in GetDefaultBounds
Tested on Win32 with no docking packages installed.
DoDi
Index: ide/frames/window_options.lfm
===================================================================
--- ide/frames/window_options.lfm (revision 31122)
+++ ide/frames/window_options.lfm (working copy)
@@ -12,9 +12,9 @@
AnchorSideTop.Control = Owner
AnchorSideRight.Side = asrBottom
Left = 0
- Height = 22
+ Height = 19
Top = 0
- Width = 227
+ Width = 181
Caption = 'SingleTaskBarButtonCheckBox'
Enabled = False
TabOrder = 0
@@ -25,9 +25,9 @@
AnchorSideTop.Side = asrBottom
AnchorSideRight.Side = asrBottom
Left = 0
- Height = 22
- Top = 22
- Width = 187
+ Height = 19
+ Top = 19
+ Width = 151
Caption = 'HideIDEOnRunCheckBox'
TabOrder = 1
end
@@ -40,14 +40,14 @@
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 0
- Height = 357
- Top = 116
+ Height = 372
+ Top = 101
Width = 566
Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Top = 6
Caption = 'WindowPositionsGroupBox'
- ClientHeight = 336
- ClientWidth = 558
+ ClientHeight = 354
+ ClientWidth = 562
TabOrder = 2
object Bevel1: TBevel
AnchorSideLeft.Control = WindowPositionsGroupBox
@@ -55,7 +55,7 @@
AnchorSideTop.Side = asrCenter
Left = 6
Height = 3
- Top = 169
+ Top = 168
Width = 50
BorderSpacing.Left = 6
end
@@ -66,10 +66,10 @@
AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = WindowPositionsGroupBox
AnchorSideRight.Side = asrBottom
- Left = 215
+ Left = 178
Height = 3
- Top = 169
- Width = 337
+ Top = 168
+ Width = 378
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 6
BorderSpacing.Right = 6
@@ -79,9 +79,9 @@
AnchorSideTop.Control = WindowPositionsListBox
AnchorSideTop.Side = asrBottom
Left = 70
- Height = 18
+ Height = 16
Top = 161
- Width = 139
+ Width = 102
BorderSpacing.Left = 70
BorderSpacing.Top = 6
Caption = 'lblWindowCaption'
@@ -93,10 +93,10 @@
AnchorSideTop.Control = LeftEdit
AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = LeftEdit
- Left = 278
- Height = 18
- Top = 189
- Width = 61
+ Left = 294
+ Height = 16
+ Top = 186
+ Width = 49
Anchors = [akTop, akRight]
BorderSpacing.Right = 3
Caption = 'LeftLabel'
@@ -106,10 +106,10 @@
AnchorSideTop.Control = TopEdit
AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = TopEdit
- Left = 281
- Height = 18
- Top = 222
- Width = 58
+ Left = 293
+ Height = 16
+ Top = 215
+ Width = 50
Anchors = [akTop, akRight]
BorderSpacing.Right = 3
Caption = 'TopLabel'
@@ -119,10 +119,10 @@
AnchorSideTop.Control = WidthEdit
AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = WidthEdit
- Left = 400
- Height = 18
- Top = 189
- Width = 74
+ Left = 417
+ Height = 16
+ Top = 186
+ Width = 61
Anchors = [akTop, akRight]
BorderSpacing.Right = 3
Caption = 'WidthLabel'
@@ -132,10 +132,10 @@
AnchorSideTop.Control = HeightEdit
AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = HeightEdit
- Left = 395
- Height = 18
- Top = 222
- Width = 79
+ Left = 413
+ Height = 16
+ Top = 215
+ Width = 65
Anchors = [akTop, akRight]
BorderSpacing.Right = 3
Caption = 'HeightLabel'
@@ -149,7 +149,7 @@
Left = 6
Height = 149
Top = 6
- Width = 546
+ Width = 550
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Around = 6
ItemHeight = 0
@@ -161,80 +161,79 @@
AnchorSideTop.Control = lblWindowCaption
AnchorSideTop.Side = asrBottom
Left = 6
- Height = 22
- Top = 185
- Width = 288
+ Height = 19
+ Top = 183
+ Width = 233
BorderSpacing.Around = 6
Caption = 'UseWindowManagerSettingRadioButton'
Checked = True
- State = cbChecked
TabOrder = 1
+ TabStop = True
end
object DefaultRadioButton: TRadioButton
AnchorSideLeft.Control = WindowPositionsGroupBox
AnchorSideTop.Control = UseWindowManagerSettingRadioButton
AnchorSideTop.Side = asrBottom
Left = 6
- Height = 22
- Top = 213
- Width = 156
+ Height = 19
+ Top = 208
+ Width = 124
BorderSpacing.Around = 6
Caption = 'DefaultRadioButton'
TabOrder = 2
- TabStop = False
end
object RestoreWindowGeometryRadioButton: TRadioButton
AnchorSideLeft.Control = WindowPositionsGroupBox
AnchorSideTop.Control = DefaultRadioButton
AnchorSideTop.Side = asrBottom
Left = 6
- Height = 22
- Top = 241
- Width = 274
+ Height = 19
+ Top = 233
+ Width = 221
BorderSpacing.Around = 6
Caption = 'RestoreWindowGeometryRadioButton'
TabOrder = 3
- TabStop = False
end
object CustomPositionRadioButton: TRadioButton
AnchorSideLeft.Control = WindowPositionsGroupBox
AnchorSideTop.Control = RestoreWindowGeometryRadioButton
AnchorSideTop.Side = asrBottom
Left = 6
- Height = 22
- Top = 269
- Width = 210
+ Height = 19
+ Top = 258
+ Width = 171
BorderSpacing.Around = 6
Caption = 'CustomPositionRadioButton'
TabOrder = 4
- TabStop = False
end
object LeftEdit: TSpinEdit
AnchorSideTop.Control = lblWindowCaption
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = WidthEdit
- Left = 342
- Height = 27
- Top = 185
+ Left = 346
+ Height = 23
+ Top = 183
Width = 75
Anchors = [akTop, akRight]
BorderSpacing.Top = 6
BorderSpacing.Right = 60
MaxValue = 4096
+ MinValue = -4096
TabOrder = 5
end
object TopEdit: TSpinEdit
AnchorSideTop.Control = LeftEdit
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = HeightEdit
- Left = 342
- Height = 27
- Top = 218
+ Left = 346
+ Height = 23
+ Top = 212
Width = 75
Anchors = [akTop, akRight]
BorderSpacing.Top = 6
BorderSpacing.Right = 60
MaxValue = 4096
+ MinValue = -4096
TabOrder = 6
end
object WidthEdit: TSpinEdit
@@ -242,39 +241,43 @@
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = WindowPositionsGroupBox
AnchorSideRight.Side = asrBottom
- Left = 477
- Height = 27
- Top = 185
+ Left = 481
+ Height = 23
+ Top = 183
Width = 75
Anchors = [akTop, akRight]
BorderSpacing.Top = 6
BorderSpacing.Right = 6
MaxValue = 4096
+ MinValue = 100
TabOrder = 7
+ Value = 100
end
object HeightEdit: TSpinEdit
AnchorSideTop.Control = WidthEdit
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = WindowPositionsGroupBox
AnchorSideRight.Side = asrBottom
- Left = 477
- Height = 27
- Top = 218
+ Left = 481
+ Height = 23
+ Top = 212
Width = 75
Anchors = [akTop, akRight]
BorderSpacing.Top = 6
BorderSpacing.Right = 6
MaxValue = 4096
+ MinValue = 100
TabOrder = 8
+ Value = 100
end
object GetWindowPositionButton: TButton
AnchorSideTop.Control = TopEdit
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = ApplyButton
- Left = 260
- Height = 27
- Top = 251
- Width = 188
+ Left = 290
+ Height = 25
+ Top = 241
+ Width = 167
Anchors = [akTop, akRight]
AutoSize = True
BorderSpacing.Around = 6
@@ -288,10 +291,10 @@
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = WindowPositionsGroupBox
AnchorSideRight.Side = asrBottom
- Left = 454
- Height = 27
- Top = 251
- Width = 98
+ Left = 463
+ Height = 25
+ Top = 241
+ Width = 93
Anchors = [akTop, akRight]
AutoSize = True
BorderSpacing.Around = 6
@@ -306,9 +309,9 @@
AnchorSideTop.Control = HideIDEOnRunCheckBox
AnchorSideTop.Side = asrBottom
Left = 0
- Height = 22
- Top = 44
- Width = 222
+ Height = 19
+ Top = 38
+ Width = 176
Caption = 'HideMessagesIconsCheckBox'
TabOrder = 3
end
@@ -317,9 +320,9 @@
AnchorSideTop.Control = HideMessagesIconsCheckBox
AnchorSideTop.Side = asrBottom
Left = 0
- Height = 22
- Top = 66
- Width = 235
+ Height = 19
+ Top = 57
+ Width = 186
Caption = 'TitleStartsWithProjectCheckBox'
ParentShowHint = False
ShowHint = True
@@ -330,9 +333,9 @@
AnchorSideTop.Control = TitleStartsWithProjectCheckBox
AnchorSideTop.Side = asrBottom
Left = 0
- Height = 22
- Top = 88
- Width = 218
+ Height = 19
+ Top = 76
+ Width = 173
Caption = 'ProjectDirInIdeTitleCheckBox'
ParentShowHint = False
ShowHint = True
Index: ideintf/idewindowintf.pas
===================================================================
--- ideintf/idewindowintf.pas (revision 31122)
+++ ideintf/idewindowintf.pas (working copy)
@@ -749,7 +749,7 @@
function TSimpleWindowLayout.CustomCoordinatesAreValid: boolean;
begin
- Result:=(Width>0) and (Height>0) and (Left>10-Width) and (Top>10-Height);
+ Result:=(Width>0) and (Height>0); //top and left can be negative
end;
procedure TSimpleWindowLayout.CloseForm;
@@ -828,8 +828,13 @@
p:=Point(0,0);
Left:=Form.Left+p.X;
Top:=Form.Top+p.Y;
+ {$IFDEF new}
+ Width:=Form.UndockWidth;
+ Height:=Form.UndockHeight;
+ {$ELSE}
Width:=Form.Width;
Height:=Form.Height;
+ {$ENDIF}
end;
end;
@@ -1053,20 +1058,7 @@
if NewBounds.Bottom-NewBounds.Top<60 then
NewBounds.Bottom:=NewBounds.Top+60;
// move to visible area
- if NewBounds.Right<60 then
- OffsetRect(NewBounds,60-NewBounds.Right,0);
- if NewBounds.Bottom<60 then
- OffsetRect(NewBounds,0,60-NewBounds.Bottom);
- if NewBounds.Left>Screen.DesktopWidth-60 then begin
- i:=(Screen.DesktopWidth-60)-NewBounds.Left;
- NewBounds.Left := Screen.DesktopWidth-60;
- NewBounds.Right := NewBounds.Right + i;
- end;
- if NewBounds.Top>Screen.DesktopHeight-60 then begin
- i:=(Screen.DesktopHeight-60)-NewBounds.Top;
- NewBounds.Top := Screen.DesktopHeight-60;
- NewBounds.Bottom := NewBounds.Bottom + i;
- end;
+ NewBounds := Screen.FitToMonitor(NewBounds);
// set bounds (do not use SetRestoredBounds - that flickers with
the current LCL implementation)
AForm.SetBounds(NewBounds.Left,NewBounds.Top,
NewBounds.Right-NewBounds.Left,
@@ -1148,11 +1140,7 @@
{$IFDEF VerboseIDEDocking}
debugln(['TSimpleWindowLayoutList.ApplyAndShow ',DbgSName(AForm),'
NewBounds=',dbgs(NewBounds)]);
{$ENDIF}
- NewBounds.Left:=Min(10000,Max(-10000,NewBounds.Left));
- NewBounds.Top:=Min(10000,Max(-10000,NewBounds.Top));
- NewBounds.Right:=Max(NewBounds.Left+100,NewBounds.Right);
- NewBounds.Bottom:=Max(NewBounds.Top+100,NewBounds.Bottom);
- AForm.BoundsRect:=NewBounds;
+ AForm.BoundsRect:= Screen.FitToMonitor(NewBounds);
end;
finally
if (AForm.WindowState in [wsNormal,wsMaximized]) and BringToFront then
@@ -1279,7 +1267,7 @@
else
aRight:=StrToIntDef(Right,0);
if aRight<0 then
- aRight:=Screen.Width-aRight
+ aRight:=Screen.Width+aRight //is < 0!
else if (Right<>'') and (Right[1]='+') then
inc(aRight,DefBounds.Left);
DefBounds.Right:=aRight;
@@ -1291,7 +1279,7 @@
else
aBottom:=StrToIntDef(Bottom,0);
if aBottom<0 then
- aBottom:=Screen.Height-aBottom
+ aBottom:=Screen.Height+aBottom //is < 0!
else if (Bottom<>'') and (Bottom[1]='+') then
inc(aBottom,DefBounds.Top);
DefBounds.Bottom:=aBottom;
Index: lcl/forms.pp
===================================================================
--- lcl/forms.pp (revision 31122)
+++ lcl/forms.pp (working copy)
@@ -912,6 +912,7 @@
FActiveControl: TWinControl;
FActiveCustomForm: TCustomForm;
FActiveForm: TForm;
+ FBoundsRect: TRect;
FCursor: TCursor;
FCursorMap: TMap;
FCustomForms: TFPList;
@@ -952,6 +953,7 @@
function GetMonitor(Index: Integer): TMonitor;
function GetMonitorCount: Integer;
function GetPrimaryMonitor: TMonitor;
+ function GetBoundsRect: TRect;
function GetWidth : Integer;
procedure AddForm(AForm: TCustomForm);
procedure RemoveForm(AForm: TCustomForm);
@@ -1016,6 +1018,9 @@
function DisableForms(SkipForm: TCustomForm; DisabledList: TList = nil):
TList;
procedure EnableForms(var AFormList: TList);
+ function FitInto(const src, dst: TRect): TRect;
+ function FitToScreen(const src: TRect): TRect;
+ function FitToMonitor(const src: TRect): TRect;
function MonitorFromPoint(const Point: TPoint;
MonitorDefault: TMonitorDefaultTo = mdNearest): TMonitor;
function MonitorFromRect(const Rect: TRect;
@@ -1026,6 +1031,7 @@
property ActiveControl: TWinControl read FActiveControl;
property ActiveCustomForm: TCustomForm read FActiveCustomForm;
property ActiveForm: TForm read FActiveForm;
+ property BoundsRect: TRect read GetBoundsRect;
property Cursor: TCursor read FCursor write SetCursor;
property Cursors[Index: Integer]: HCURSOR read GetCursors write SetCursors;
property CustomFormCount: Integer read GetCustomFormCount;
Index: lcl/include/screen.inc
===================================================================
--- lcl/include/screen.inc (revision 31122)
+++ lcl/include/screen.inc (working copy)
@@ -419,6 +419,52 @@
FreeAndNil(AFormList);
end;
+function TScreen.FitInto(const src, dst: TRect): TRect;
+begin
+(* Adjust src to fit into dst.
+ Keep src extent if possible.
+*)
+ if src.Right > dst.Right then begin
+ //shift left
+ Result.Right := dst.Right;
+ Result.Left := Max(dst.Left, Result.Right - (src.Right - src.Left));
+ end else if src.Left < dst.Left then begin
+ //shift right
+ Result.Left := src.Left;
+ Result.Right := Min(dst.Right, Result.Left + (src.Right - src.Left));
+ end else begin
+ Result.Left := src.Left;
+ Result.Right:= src.Right;
+ end;
+ if src.Bottom > dst.Bottom then begin
+ //shift up
+ Result.Bottom := dst.Bottom;
+ Result.Top := Max(dst.Top, Result.Bottom - (src.Bottom - src.Top));
+ end else if src.Top < dst.Top then begin
+ //shift down
+ Result.Top := dst.Top;
+ Result.Bottom := Min(dst.Bottom, Result.Top + (src.Bottom - src.Top));
+ end else begin
+ Result.Top := src.Top;
+ Result.Bottom := src.Bottom;
+ end;
+end;
+
+function TScreen.FitToScreen(const src: TRect): TRect;
+begin
+ Result := FitInto(src, BoundsRect);
+end;
+
+function TScreen.FitToMonitor(const src: TRect): TRect;
+var
+ m: TMonitor;
+begin
+ m := MonitorFromPoint(src.TopLeft);
+ if m = nil then
+ m := Monitors[0];
+ Result := FitInto(src, m.BoundsRect);
+end;
+
function TScreen.MonitorFromPoint(const Point: TPoint;
MonitorDefault: TMonitorDefaultTo): TMonitor;
var
@@ -745,6 +791,27 @@
Result := nil;
end;
+function TScreen.GetBoundsRect: TRect;
+var
+ i: integer;
+ m: TMonitor;
+ r: TRect;
+begin
+ if FBoundsRect.Right = 0 then begin
+ FBoundsRect := Monitors[0].BoundsRect;
+ for i := 1 to MonitorCount - 1 do begin
+ //merge monitor bounds
+ r := Monitors[i].BoundsRect;
+ if r.Top < FBoundsRect.Top then FBoundsRect.Top := r.Top;
+ if r.Bottom > FBoundsRect.Bottom then FBoundsRect.Bottom := r.Bottom;
+ if r.Left < FBoundsRect.Left then FBoundsRect.Left := r.Left;
+ if r.Right > FBoundsRect.Right then FBoundsRect.Right := r.Right;
+ end;
+ //todo: exclude TaskBar
+ end;
+ Result := FBoundsRect;
+end;
+
function TScreen.GetSystemFont: TFont;
begin
if (FSystemFont = nil) then
--
_______________________________________________
Lazarus mailing list
[email protected]
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus