Skip to content

Commit 905b126

Browse files
committed
fix: DPI related scale glitches, mainly on completion proposal
Refs #2534
1 parent 3e678bc commit 905b126

8 files changed

Lines changed: 63 additions & 62 deletions

File tree

source/connections.pas

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1685,8 +1685,8 @@ procedure Tconnform.splitterMainMoved(Sender: TObject);
16851685
// Resize bottom right buttons
16861686
HorizSpace := PageControlDetails.Width - 2 * BorderWidth;
16871687
ButtonWidth := Round(HorizSpace / 3);
1688-
ButtonWidth := Max(ButtonWidth, ScaleSize(50));
1689-
ButtonWidth := Min(ButtonWidth, ScaleSize(100));
1688+
ButtonWidth := Max(ButtonWidth, ScaleFromDesign(50));
1689+
ButtonWidth := Min(ButtonWidth, ScaleFromDesign(100));
16901690
btnMore.Width := ButtonWidth;
16911691
btnCancel.Width := ButtonWidth;
16921692
btnOpen.Width := ButtonWidth;

source/data_sorting.pas

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,12 @@ procedure TfrmDataSorting.DisplaySortingControls(Sender: TObject);
9393
Components[i].Free;
9494
end;
9595

96-
Margin := ScaleSize(3);
97-
MarginBig := ScaleSize(Margin * 2);
98-
Width1 := ScaleSize(15);
99-
Width2 := ScaleSize(160);
100-
Width3 := ScaleSize(23);
101-
Width4 := ScaleSize(23);
96+
Margin := ScaleFromDesign(3);
97+
MarginBig := ScaleFromDesign(Margin * 2);
98+
Width1 := ScaleFromDesign(15);
99+
Width2 := ScaleFromDesign(160);
100+
Width3 := ScaleFromDesign(23);
101+
Width4 := ScaleFromDesign(23);
102102

103103
// Set initial width to avoid resizing form to 0
104104
TopPos := pnlBevel.BorderWidth + MarginBig;

source/extra_controls.pas

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ interface
88
Classes, SysUtils, Forms, Types, StdCtrls, Clipbrd, apphelpers,
99
Graphics, Dialogs, ImgList, ComCtrls, Generics.Defaults,
1010
ExtCtrls, laz.VirtualTrees, RegExpr, Controls, EditBtn, Menus,
11-
LCLIntf, Math;
11+
LCLIntf, Math, LCLType;
1212

1313
type
1414
// Form with a sizegrip in the lower right corner, without the need for a statusbar
@@ -23,8 +23,9 @@ TExtForm = class(TForm)
2323
class procedure InheritFont(AFont: TFont);
2424
class procedure SaveListSetup(List: TLazVirtualStringTree);
2525
class procedure RestoreListSetup(List: TLazVirtualStringTree);
26-
function ScaleSize(x: Extended): Integer; overload;
27-
class function ScaleSize(x: Extended; Control: TControl): Integer; overload;
26+
class function GetCurrentPPI(Control: TControl): Integer;
27+
function ScaleFromDesign(x: Extended): Integer; overload;
28+
class function ScaleFromDesign(x: Extended; Control: TControl): Integer; overload;
2829
// Returns a PPI-aware width of a space character
2930
function Space(Multiply: Integer=1): Integer;
3031
class procedure PageControlTabHighlight(PageControl: TPageControl);
@@ -270,21 +271,46 @@ procedure TExtForm.FilterNodesByEdit(Edit: TEditButton; Tree: TLazVirtualStringT
270271
end;
271272

272273

273-
function TExtForm.ScaleSize(x: Extended): Integer;
274+
class function TExtForm.GetCurrentPPI(Control: TControl): Integer;
275+
var
276+
P: TPoint;
277+
Mon: TMonitor;
278+
begin
279+
P := Control.ClientToScreen(Point(0, 0));
280+
Mon := Screen.MonitorFromPoint(P, mdNearest);
281+
Result := Mon.PixelsPerInch;
282+
end;
283+
284+
285+
function TExtForm.ScaleFromDesign(x: Extended): Integer;
274286
begin
275-
// Shorthand for dpi scaling hardcoded width/height values of controls
276-
Result := ScaleSize(x, Self);
287+
// Shorthand for DPI upscaling hardcoded width/height values of controls
288+
Result := ScaleFromDesign(x, Self);
277289
end;
278290

279-
class function TExtForm.ScaleSize(x: Extended; Control: TControl): Integer;
291+
class function TExtForm.ScaleFromDesign(x: Extended; Control: TControl): Integer;
292+
var
293+
frm: TCustomForm;
280294
begin
281295
// Same as above for callers without a form
282-
Result := Control.Scale96ToForm(Round(x));
296+
if Control is TCustomForm then
297+
frm := TCustomForm(Control)
298+
else
299+
frm := GetParentForm(Control);
300+
if frm = nil then
301+
Result := Round(x)
302+
else
303+
Result := Round(x * GetCurrentPPI(Control) / frm.DesignTimePPI);
283304
end;
284305

285306
function TExtForm.Space(Multiply: Integer=1): Integer;
307+
var
308+
CurPpi: Integer;
286309
begin
287310
Result := Canvas.TextWidth(' ') * Multiply;
311+
CurPpi := GetCurrentPPI(Self);
312+
if CurPpi <> Canvas.Font.PixelsPerInch then
313+
Result := MulDiv(Result, CurPpi, Canvas.Font.PixelsPerInch);
288314
end;
289315

290316

@@ -344,7 +370,7 @@ procedure TExtComboBox.Change;
344370
HintText := Items[ItemIndex];
345371
HintWidth := Canvas.TextWidth(HintText);
346372
if HintWidth > Width then begin
347-
Padding := TExtForm.ScaleSize(10, Self);
373+
Padding := TExtForm.ScaleFromDesign(10, Self);
348374
HintRect := Rect(
349375
P.X + Padding,
350376
P.Y + Padding * 2,

source/grideditlinks.pas

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,7 +1038,7 @@ constructor TSetEditorLink.Create(Tree: TVirtualStringTree; AllowEdit: Boolean;
10381038
FPanel.Hide;
10391039
FPanel.Parent := FParentForm;
10401040
FPanel.ParentBackground := False;
1041-
FPanel.Height := TExtForm.ScaleSize(150, FParentForm);
1041+
FPanel.Height := TExtForm.ScaleFromDesign(150, FParentForm);
10421042
FPanel.OnExit := DoEndEdit;
10431043

10441044
FCheckList := TCheckListBox.Create(FPanel);
@@ -1129,7 +1129,7 @@ procedure TSetEditorLink.SetBounds(R: TRect); stdcall;
11291129

11301130
FBtnOk.Width := (FPanel.Width - 3*margin) div 2;
11311131
FBtnOk.Left := margin;
1132-
FBtnOk.Height := TExtForm.ScaleSize(24, FParentForm);
1132+
FBtnOk.Height := TExtForm.ScaleFromDesign(24, FParentForm);
11331133
FBtnOk.Top := FPanel.Height - 2*margin - FBtnOk.Height;
11341134
FBtnOk.Enabled := FAllowEdit;
11351135

@@ -1198,7 +1198,7 @@ constructor TInplaceEditorLink.Create(Tree: TVirtualStringTree; AllowEdit: Boole
11981198
FButton.AnchorSideBottom.Control := FPanel;
11991199
FButton.AnchorSideBottom.Side := asrBottom;
12001200
FButton.Anchors := [akTop, akRight, akBottom];
1201-
FButton.Constraints.MaxWidth := TExtForm.ScaleSize(20, FPanel);
1201+
FButton.Constraints.MaxWidth := TExtForm.ScaleFromDesign(20, FPanel);
12021202
FButton.TabStop := False;
12031203
FButton.Caption := '...';
12041204
FButton.Hint := _('Edit text in popup editor ...');
@@ -1316,7 +1316,7 @@ constructor TColumnDefaultEditorLink.Create(Tree: TVirtualStringTree; AllowEdit:
13161316
inherited;
13171317

13181318
// Margin between controls and to edge of panel
1319-
m := TExtForm.ScaleSize(5, FParentForm);
1319+
m := TExtForm.ScaleFromDesign(5, FParentForm);
13201320

13211321
FPanel := TPanel.Create(FParentForm);
13221322
FPanel.Hide;
@@ -1414,7 +1414,7 @@ constructor TColumnDefaultEditorLink.Create(Tree: TVirtualStringTree; AllowEdit:
14141414

14151415
FBtnOk := TButton.Create(FPanel);
14161416
FBtnOk.Parent := FPanel;
1417-
FBtnOk.Width := TExtForm.ScaleSize(60, FParentForm);
1417+
FBtnOk.Width := TExtForm.ScaleFromDesign(60, FParentForm);
14181418
FBtnOk.Top := FRadioAutoInc.Top + FRadioAutoInc.Height + m;
14191419
FBtnOk.Left := FPanel.Width - 3*m - 2*FBtnOk.Width - 2*FPanel.BorderWidth;
14201420
FBtnOk.OnClick := BtnOkClick;

source/main.lfm

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20351,7 +20351,6 @@ object MainForm: TMainForm
2035120351
Position = 0
2035220352
LinesInWindow = 6
2035320353
OnSearchPosition = SynCompletionProposalSearchPosition
20354-
OnPositionChanged = SynCompletionProposalChange
2035520354
SelectedColor = clHighlight
2035620355
CaseSensitive = False
2035720356
Width = 350

source/main.pas

Lines changed: 13 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,7 +1226,6 @@ TMainForm = class(TExtForm)
12261226
procedure menuCopyColumnNamesClick(Sender: TObject);
12271227
procedure menuCloseTabOnDblClickClick(Sender: TObject);
12281228
procedure TimerRefreshTimer(Sender: TObject);
1229-
procedure SynCompletionProposalChange(Sender: TObject);
12301229
procedure SynMemoQuerySpecialLineColors(Sender: TObject; Line: Integer;
12311230
var Special: Boolean; var FG, BG: TColor);
12321231
procedure SynMemoSQLLogSpecialLineColors(Sender: TObject; Line: Integer;
@@ -1802,8 +1801,8 @@ procedure TMainForm.FormDestroy(Sender: TObject);
18021801
AppSettings.WriteString(asDelimiter, FDelimiter);
18031802
AppSettings.WriteInt(asQuerymemoheight, ScaleFormToDesign(pnlQueryMemo.Height));
18041803
AppSettings.WriteInt(asQueryhelperswidth, ScaleFormToDesign(pnlQueryHelpers.Width));
1805-
AppSettings.WriteInt(asCompletionProposalWidth, ScaleFormToDesign(SynCompletionProposal.TheForm.Width));
1806-
AppSettings.WriteInt(asCompletionProposalNbLinesInWindow, SynCompletionProposal.LinesInWindow);
1804+
AppSettings.WriteInt(asCompletionProposalWidth, SynCompletionProposal.TheForm.ScaleFormToDesign(SynCompletionProposal.TheForm.Width));
1805+
AppSettings.WriteInt(asCompletionProposalNbLinesInWindow, SynCompletionProposal.TheForm.ScaleFormToDesign(SynCompletionProposal.LinesInWindow));
18071806
AppSettings.WriteInt(asDbtreewidth, ScaleFormToDesign(pnlLeft.width));
18081807
AppSettings.WriteBool(asGroupTreeObjects, actGroupObjects.Checked);
18091808
AppSettings.WriteInt(asDataPreviewHeight, ScaleFormToDesign(pnlPreview.Height));
@@ -2075,11 +2074,8 @@ procedure TMainForm.FormCreate(Sender: TObject);
20752074
end;
20762075

20772076
// Completion proposal window
2078-
// The proposal form gets scaled a second time when it shows its form with Scaled=True.
2079-
// We already store and restore the dimensions DPI aware.
2080-
{SynCompletionProposal.Form.Scaled := False;}
2081-
SynCompletionProposal.TheForm.Width := Max(AppSettings.ReadInt(asCompletionProposalWidth), 50);
2082-
SynCompletionProposal.LinesInWindow := AppSettings.ReadInt(asCompletionProposalNbLinesInWindow);
2077+
SynCompletionProposal.TheForm.Width := Min(Max(AppSettings.ReadInt(asCompletionProposalWidth), 50), 350);
2078+
SynCompletionProposal.LinesInWindow := Min(AppSettings.ReadInt(asCompletionProposalNbLinesInWindow), 10);
20832079
FProposalItems := TProposalItemList.Create;
20842080
FProposalTriggeredByDot := False;
20852081

@@ -3598,22 +3594,26 @@ function TMainForm.SynCompletionProposalMeasureItem(const AKey: string;
35983594
var
35993595
i, X, Y: Integer;
36003596
Item: TProposalItem;
3597+
ItemWidth: Integer;
36013598
begin
36023599
// Calculate how much vertical and horizontal space the control reserves for this row
36033600
FProposalLeftWidth := 0;
36043601

36053602
ACanvas.Font.Style := [];
36063603
for i := 0 to SynCompletionProposal.ItemList.Count - 1 do begin
36073604
Item := FProposalItems[SynCompletionProposal.IndexFromVisibleIndex(i)];
3608-
FProposalLeftWidth := Max(FProposalLeftWidth, ACanvas.TextWidth(Item.LeftText));
3605+
ItemWidth := ACanvas.TextWidth(Item.LeftText);
3606+
// Canvas is not yet scaled to the current PPI
3607+
ItemWidth := MulDiv(ItemWidth, Monitor.PixelsPerInch, ACanvas.Font.PixelsPerInch);
3608+
FProposalLeftWidth := Max(FProposalLeftWidth, ItemWidth);
36093609
end;
36103610

36113611
Item := FProposalItems[SynCompletionProposal.IndexFromVisibleIndex(Index)];
3612-
X := Space + ImageListMain.WidthForPPI[16, PixelsPerInch]
3612+
X := Space + ImageListMain.WidthForPPI[16, ACanvas.Font.PixelsPerInch]
36133613
+ Space + FProposalLeftWidth
36143614
+ Space(2) + ACanvas.TextWidth(Item.CenterText)
36153615
+ IfThen(Item.RightText.IsEmpty, 0, Space(2) + ACanvas.TextWidth(Item.RightText));
3616-
Y := Max(ImageListMain.HeightForPPI[16, PixelsPerInch] + 2, ACanvas.TextHeight('Wy')) + Space;
3616+
Y := Max(ImageListMain.HeightForPPI[16, ACanvas.Font.PixelsPerInch] + 2, ACanvas.TextHeight('Wy')) + Space;
36173617
Result := Point(X, Y);
36183618
end;
36193619

@@ -3626,11 +3626,11 @@ function TMainForm.SynCompletionProposalPaintItem(const AKey: string;
36263626
It := FProposalItems[SynCompletionProposal.IndexFromVisibleIndex(Index)];
36273627

36283628
if (It.ImageIndex >= 0) and (It.ImageIndex < ImageListMain.Count) then
3629-
ImageListMain.Draw(ACanvas, X + Space, Y + 1, It.ImageIndex, True);
3629+
ImageListMain.DrawForControl(ACanvas, X + Space, Y + 1, It.ImageIndex, ImageListMain.Width, SynCompletionProposal.TheForm, True);
36303630

36313631
ACanvas.Brush.Style := bsClear;
36323632

3633-
X1 := X + Space + ImageListMain.WidthForPPI[16, PixelsPerInch] + Space;
3633+
X1 := X + Space + ImageListMain.WidthForPPI[16, ACanvas.Font.PixelsPerInch] + Space;
36343634
ACanvas.Font.Style := [];
36353635
ACanvas.Font.Color := IfThen(Selected, clHighlightText, It.LeftColor);
36363636
ACanvas.TextOut(X1, Y + 1, It.LeftText);
@@ -6808,30 +6808,6 @@ procedure TMainForm.KillProcess(Sender: TObject);
68086808
end;
68096809

68106810

6811-
procedure TMainForm.SynCompletionProposalChange(Sender: TObject);
6812-
{var
6813-
Proposal: TSynCompletion;
6814-
SelectedFuncName: String;
6815-
SQLFunc: TSQLFunction;}
6816-
begin
6817-
{Proposal := Sender as TSynCompletionProposal;
6818-
if (AIndex >= 0) and (AIndex < Proposal.ItemList.Count) then begin
6819-
Proposal.Title := Proposal.InsertItem(AIndex);
6820-
// Show function description in hint panel
6821-
ShowStatusMsg('', 0);
6822-
SelectedFuncName := RegExprGetMatch('...
6823-
if not SelectedFuncName.IsEmpty then begin
6824-
for SQLFunc in ActiveConnection.SQLFunctions do begin
6825-
if SQLFunc.Name.ToUpper = SelectedFuncName.ToUpper then begin
6826-
ShowStatusMsg(SQLFunc.Description.Replace(SLineBreak, ' '), 0);
6827-
Break;
6828-
end;
6829-
end;
6830-
end;
6831-
end;}
6832-
end;
6833-
6834-
68356811
{ Proposal about to insert a String into synmemo }
68366812
procedure TMainForm.SynCompletionProposalCodeCompletion(var Value: string;
68376813
SourceValue: string; var SourceStart, SourceEnd: TPoint; KeyChar: TUTF8Char;

source/table_editor.pas

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ procedure TfrmTableEditor.Init(Obj: TDBObject);
342342
FLoaded := False;
343343

344344
// Fix control width and position, broken when opening a second table. See issue #1959
345-
//comboCollation.Left := lblCollation.Left + TExtForm.ScaleSize(150, Self);
345+
//comboCollation.Left := lblCollation.Left + TExtForm.ScaleFromDesign(150, Self);
346346
//comboCollation.Width := comboRowFormat.Width;
347347
comboCollation.Items := DBObject.Connection.CollationList;
348348
//chkCharsetConvert.Left := comboCollation.Left + comboCollation.Width + 10;

source/trigger_editor.pas

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ procedure TfrmTriggerEditor.SynCompletionProposalStatementExecute(Sender: TObjec
273273
// Propose column names from referencing table
274274
{Proposal := Sender as TSynCompletion;
275275
Proposal.Font.Assign(Font);
276-
Proposal.ItemHeight := TExtForm.ScaleSize(PROPOSAL_ITEM_HEIGHT, Self);
276+
Proposal.ItemHeight := TExtForm.ScaleFromDesign(PROPOSAL_ITEM_HEIGHT, Self);
277277
Token := UpperCase(Proposal.PreviousToken);
278278
Proposal.InsertList.Clear;
279279
Proposal.ItemList.Clear;

0 commit comments

Comments
 (0)