You've already forked lazarus-ccr
Industrial: Add basic TCharDefs property editor and TLCDDisplay component editor (not yet complete).
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8312 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -100,6 +100,14 @@
|
||||
<Filename Value="source\indlcddisplay.pas"/>
|
||||
<UnitName Value="indLCDDisplay"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<Filename Value="source\indlcddisplay_editor.pas"/>
|
||||
<UnitName Value="indlcddisplay_editor"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<Filename Value="source\indlcddisplay_editorform.pas"/>
|
||||
<UnitName Value="indLCDDisplay_EditorForm"/>
|
||||
</Item>
|
||||
</Files>
|
||||
<LazDoc Paths="D:\Prog_Lazarus\svn\lazarus-ccr\components\industrialstuff\fpdoc"/>
|
||||
<RequiredPkgs>
|
||||
|
@ -10,7 +10,8 @@ interface
|
||||
uses
|
||||
IndLed, Sensors, AllIndustrialRegister, LedNumber, indGnouMeter, AdvLed,
|
||||
indcyBaseLed, indcyClasses, indcyGraphics, indcyTypes, A3nalogGauge, MKnob,
|
||||
switches, indSliders, indLCDDisplay, LazarusPackageIntf;
|
||||
switches, indSliders, indLCDDisplay, indlcddisplay_editor,
|
||||
indLCDDisplay_EditorForm, LazarusPackageIntf;
|
||||
|
||||
implementation
|
||||
|
||||
|
@ -12,7 +12,8 @@ interface
|
||||
|
||||
uses
|
||||
Classes, LResources, AdvLed, IndLed, LedNumber, Sensors, indGnouMeter,
|
||||
A3nalogGauge, MKnob, Switches, indSliders, indLCDDisplay;
|
||||
A3nalogGauge, MKnob, Switches, indSliders,
|
||||
indLCDDisplay, indLCDDisplay_Editor;
|
||||
|
||||
procedure Register;
|
||||
|
||||
@ -20,15 +21,19 @@ implementation
|
||||
|
||||
{$R industrial_icons.res}
|
||||
|
||||
uses
|
||||
PropEdits, ComponentEditors;
|
||||
|
||||
//==========================================================
|
||||
procedure Register;
|
||||
begin
|
||||
RegisterComponents ('Industrial',[
|
||||
RegisterComponents('Industrial',[
|
||||
TAdvLed, TIndLed, TLedNumber, TStopLightSensor,
|
||||
TAnalogSensor, TA3nalogGauge, TindGnouMeter,
|
||||
TmKnob, TOnOffSwitch, TMultiSlider, TLCDDisplay
|
||||
]);
|
||||
|
||||
RegisterPropertyEditor(TypeInfo(TCharDefs), TLCDDisplay, 'CharDefs', TLCDDisplayCharDefsPropertyEditor);
|
||||
RegisterComponentEditor(TLCDDisplay, TLCDDisplayComponentEditor);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -51,6 +51,7 @@ type
|
||||
constructor Create(ADisplay: TLCDDisplay);
|
||||
destructor Destroy; override;
|
||||
procedure Add(AChar: String; ADotRows: TDotRows);
|
||||
procedure Assign(ASource: TPersistent); override;
|
||||
procedure Clear;
|
||||
procedure Delete(AChar: String);
|
||||
procedure LoadFromFile(const AFileName: String);
|
||||
@ -261,6 +262,21 @@ begin
|
||||
FCharList.Add(AChar, ADotRows);
|
||||
end;
|
||||
|
||||
procedure TCharDefs.Assign(ASource: TPersistent);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
if (ASource is TCharDefs) then
|
||||
begin
|
||||
FColCount := TCharDefs(ASource).ColCount;
|
||||
FRowCount := TCharDefs(ASource).RowCount;
|
||||
Clear;
|
||||
for i := 0 to TCharDefs(ASource).Count-1 do
|
||||
Add(TCharDefs(ASource).CharByIndex[i], TCharDefs(ASource).DotRowsByIndex[i]);
|
||||
end else
|
||||
inherited;
|
||||
end;
|
||||
|
||||
{ Clears all characters and their dot matrices. }
|
||||
procedure TCharDefs.Clear;
|
||||
begin
|
||||
|
192
components/industrialstuff/source/indlcddisplay_editor.pas
Normal file
192
components/industrialstuff/source/indlcddisplay_editor.pas
Normal file
@ -0,0 +1,192 @@
|
||||
unit indlcddisplay_editor;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses lazlogger,
|
||||
Classes, SysUtils, PropEdits, ComponentEditors,
|
||||
indLCDDisplay;
|
||||
|
||||
type
|
||||
TLCDDisplayCharDefsPropertyEditor = class(TPersistentPropertyEditor)
|
||||
public
|
||||
procedure Edit; override;
|
||||
procedure ExecuteVerb(Index: Integer); override;
|
||||
function GetAttributes: TPropertyAttributes; override;
|
||||
function GetVerb(Index: Integer): string; override;
|
||||
function GetVerbCount: Integer; override;
|
||||
function LCDDisplay: TLCDDisplay;
|
||||
end;
|
||||
|
||||
TLCDDisplayComponentEditor = class(TDefaultComponentEditor)
|
||||
public
|
||||
procedure EditLines;
|
||||
procedure ExecuteVerb(Index: Integer);
|
||||
function GetVerb(Index: Integer): string; override;
|
||||
function GetVerbCount: Integer; override;
|
||||
function LCDDisplay: TLCDDisplay;
|
||||
end;
|
||||
|
||||
procedure EditCharDefs(ALCDDisplay: TLCDDisplay);
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
Dialogs, indLCDDisplay_EditorForm;
|
||||
|
||||
{ Opens the char def editor. }
|
||||
procedure EditCharDefs(ALCDDisplay: TLCDDisplay);
|
||||
var
|
||||
F: TLCDCharDefsEditor;
|
||||
begin
|
||||
F := TLCDCharDefsEditor.Create(nil);
|
||||
try
|
||||
F.LCDDisplay := TLCDDisplay(ALCDDisplay);
|
||||
F.ShowModal; // Cancel has been handled by the editor form.
|
||||
finally
|
||||
F.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Loads the char defs of the specified LCDDisplay from an xml file. }
|
||||
procedure LoadCharDefsFromFile(ALCDDisplay: TLCDDisplay);
|
||||
var
|
||||
dlg: TOpenDialog;
|
||||
begin
|
||||
dlg := TOpenDialog.Create(nil);
|
||||
try
|
||||
dlg.FileName := '';
|
||||
dlg.Filter := 'XML files (*.xml)|*.xml';
|
||||
if dlg.Execute then
|
||||
begin
|
||||
ALCDDisplay.CharDefs.LoadFromFile(dlg.FileName);
|
||||
ALCDDisplay.Invalidate;
|
||||
end;
|
||||
finally
|
||||
dlg.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Saves the chardefs of the specified LCDDisplay to an xml file. }
|
||||
procedure SaveCharDefsToFile(ALCDDisplay: TLCDDisplay);
|
||||
var
|
||||
dlg: TOpenDialog;
|
||||
begin
|
||||
dlg := TSaveDialog.Create(nil);
|
||||
try
|
||||
dlg.FileName := '';
|
||||
dlg.Filter := 'XML files (*.xml)|*.xml';
|
||||
if dlg.Execute then
|
||||
ALCDDisplay.CharDefs.SaveToFile(dlg.FileName);
|
||||
finally
|
||||
dlg.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{ TLCDDisplayCharDefsPropertyEditor }
|
||||
|
||||
{ Opens the chardefs editor. }
|
||||
procedure TLCDDisplayCharDefsPropertyEditor.Edit;
|
||||
begin
|
||||
EditCharDefs(LCDDisplay);
|
||||
end;
|
||||
|
||||
{ Executes the routines assigned to the CharDefs context menu }
|
||||
procedure TLCDDisplayCharDefsPropertyEditor.ExecuteVerb(Index: Integer);
|
||||
begin
|
||||
case Index of
|
||||
0: Edit;
|
||||
1: LoadCharDefsFromFile(LCDDisplay);
|
||||
2: SaveCharDefsToFile(LCDDisplay);
|
||||
end;
|
||||
end;
|
||||
|
||||
{ The property editor should open the CharDefs editor. }
|
||||
function TLCDDisplayCharDefsPropertyEditor.GetAttributes: TPropertyAttributes;
|
||||
begin
|
||||
Result := inherited GetAttributes + [paDialog];
|
||||
end;
|
||||
|
||||
{ Determines how many items will be added to the CharDefs context menu. }
|
||||
function TLCDDisplayCharDefsPropertyEditor.GetVerbCount: Integer;
|
||||
begin
|
||||
Result := 3;
|
||||
end;
|
||||
|
||||
{ Determines the menu item text for CharDefs context menu. }
|
||||
function TLCDDisplayCharDefsPropertyEditor.GetVerb(Index: Integer): string;
|
||||
begin
|
||||
case Index of
|
||||
0: Result := 'Edit...';
|
||||
1: Result := 'Load from file...';
|
||||
2: Result := 'Save to file...';
|
||||
end;
|
||||
end;
|
||||
|
||||
function TLCDDisplayCharDefsPropertyEditor.LCDDisplay: TLCDDisplay;
|
||||
begin
|
||||
Result := TLCDDisplay(GetComponent(0));
|
||||
end;
|
||||
|
||||
{ TLCDDisplayComponentEditor }
|
||||
|
||||
procedure TLCDDisplayComponentEditor.EditLines;
|
||||
begin
|
||||
{
|
||||
F := TStringsPropEditorForm.Create(nil);
|
||||
dlg :=
|
||||
Old := TStrings(GetObjectValue);
|
||||
TheDialog := CreateDlg(Old);
|
||||
try
|
||||
if (TheDialog.ShowModal = mrOK) then begin
|
||||
New := TheDialog.ListBox.Items;
|
||||
AssignItems(Old, TheDialog.ListBox.Items);
|
||||
SetPtrValue(New);
|
||||
end;
|
||||
finally
|
||||
TheDialog.Free;
|
||||
end;
|
||||
}
|
||||
end;
|
||||
|
||||
procedure TLCDDisplayComponentEditor.ExecuteVerb(Index: Integer);
|
||||
begin
|
||||
if LCDDisplay = nil then
|
||||
DebugLn('LCDDisplay = nil')
|
||||
else
|
||||
DebugLn(LCDDisplay.ClassName);
|
||||
|
||||
case Index of
|
||||
0: EditLines;
|
||||
1: EditCharDefs(LCDDisplay);
|
||||
2: LoadCharDefsFromFile(LCDDisplay);
|
||||
3: SaveCharDefsToFile(LCDDisplay);
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Determines how many items will be added to the LCDDisplay context menu. }
|
||||
function TLCDDisplayComponentEditor.GetVerbCount: Integer;
|
||||
begin
|
||||
Result := 4;
|
||||
end;
|
||||
|
||||
{ Determines the menu item text for LCDDisplay context menu. }
|
||||
function TLCDDisplayComponentEditor.GetVerb(Index: Integer): string;
|
||||
begin
|
||||
case Index of
|
||||
0: Result := 'Text...';
|
||||
1: Result := 'Edit character defs...';
|
||||
2: Result := 'Load character defs from file...';
|
||||
3: Result := 'Save character defs to file...';
|
||||
end;
|
||||
end;
|
||||
|
||||
function TLCDDisplayComponentEditor.LCDDisplay: TLCDDisplay;
|
||||
begin
|
||||
Result := TLCDDisplay(GetComponent);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -0,0 +1,95 @@
|
||||
object LCDCharDefsEditor: TLCDCharDefsEditor
|
||||
Left = 415
|
||||
Height = 338
|
||||
Top = 175
|
||||
Width = 506
|
||||
AutoSize = True
|
||||
Caption = 'LCDCharDefsEditor'
|
||||
ClientHeight = 338
|
||||
ClientWidth = 506
|
||||
OnActivate = FormActivate
|
||||
OnCloseQuery = FormCloseQuery
|
||||
OnDestroy = FormDestroy
|
||||
LCLVersion = '2.3.0.0'
|
||||
object ButtonPanel: TButtonPanel
|
||||
Left = 6
|
||||
Height = 34
|
||||
Top = 298
|
||||
Width = 494
|
||||
OKButton.Name = 'OKButton'
|
||||
OKButton.DefaultCaption = True
|
||||
HelpButton.Name = 'HelpButton'
|
||||
HelpButton.DefaultCaption = True
|
||||
CloseButton.Name = 'CloseButton'
|
||||
CloseButton.DefaultCaption = True
|
||||
CancelButton.Name = 'CancelButton'
|
||||
CancelButton.DefaultCaption = True
|
||||
TabOrder = 3
|
||||
ShowButtons = [pbOK, pbCancel]
|
||||
end
|
||||
object btnDelete: TButton
|
||||
AnchorSideLeft.Control = dgEditor
|
||||
AnchorSideLeft.Side = asrBottom
|
||||
AnchorSideTop.Control = dgEditor
|
||||
Left = 224
|
||||
Height = 25
|
||||
Top = 64
|
||||
Width = 75
|
||||
BorderSpacing.Left = 12
|
||||
BorderSpacing.Right = 12
|
||||
Caption = 'Delete'
|
||||
OnClick = btnDeleteClick
|
||||
TabOrder = 2
|
||||
end
|
||||
object dgEditor: TDrawGrid
|
||||
AnchorSideLeft.Control = Owner
|
||||
AnchorSideTop.Control = cbCharSelector
|
||||
AnchorSideTop.Side = asrBottom
|
||||
Left = 12
|
||||
Height = 192
|
||||
Top = 64
|
||||
Width = 200
|
||||
BorderSpacing.Left = 12
|
||||
BorderSpacing.Top = 12
|
||||
BorderSpacing.Bottom = 6
|
||||
BorderStyle = bsNone
|
||||
ColCount = 1
|
||||
DefaultColWidth = 22
|
||||
ExtendedSelect = False
|
||||
FixedCols = 0
|
||||
FixedRows = 0
|
||||
RowCount = 1
|
||||
ScrollBars = ssNone
|
||||
TabOrder = 1
|
||||
OnPrepareCanvas = dgEditorPrepareCanvas
|
||||
end
|
||||
object Label1: TLabel
|
||||
AnchorSideLeft.Control = Owner
|
||||
AnchorSideTop.Control = Owner
|
||||
Left = 12
|
||||
Height = 15
|
||||
Top = 12
|
||||
Width = 105
|
||||
BorderSpacing.Left = 12
|
||||
BorderSpacing.Top = 12
|
||||
Caption = 'Available characters'
|
||||
end
|
||||
object cbCharSelector: TComboBox
|
||||
AnchorSideLeft.Control = Label1
|
||||
AnchorSideTop.Control = Label1
|
||||
AnchorSideTop.Side = asrBottom
|
||||
Left = 12
|
||||
Height = 23
|
||||
Top = 29
|
||||
Width = 114
|
||||
AutoCompleteText = [cbactEndOfLineComplete, cbactSearchCaseSensitive, cbactSearchAscending]
|
||||
BorderSpacing.Top = 2
|
||||
ItemHeight = 15
|
||||
MaxLength = 1
|
||||
OnChange = cbCharSelectorChange
|
||||
OnKeyDown = cbCharSelectorKeyDown
|
||||
OnKeyUp = cbCharSelectorKeyUp
|
||||
TabOrder = 0
|
||||
Text = 'cbCharSelector'
|
||||
end
|
||||
end
|
192
components/industrialstuff/source/indlcddisplay_editorform.pas
Normal file
192
components/industrialstuff/source/indlcddisplay_editorform.pas
Normal file
@ -0,0 +1,192 @@
|
||||
unit indLCDDisplay_EditorForm;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ButtonPanel,
|
||||
Grids, indLCDDisplay;
|
||||
|
||||
type
|
||||
|
||||
{ TLCDCharDefsEditor }
|
||||
|
||||
TLCDCharDefsEditor = class(TForm)
|
||||
btnDelete: TButton;
|
||||
ButtonPanel: TButtonPanel;
|
||||
cbCharSelector: TComboBox;
|
||||
dgEditor: TDrawGrid;
|
||||
Label1: TLabel;
|
||||
procedure btnDeleteClick(Sender: TObject);
|
||||
procedure cbCharSelectorChange(Sender: TObject);
|
||||
procedure cbCharSelectorKeyDown(Sender: TObject; var Key: Word;
|
||||
Shift: TShiftState);
|
||||
procedure cbCharSelectorKeyUp(Sender: TObject; var Key: Word;
|
||||
Shift: TShiftState);
|
||||
procedure dgEditorPrepareCanvas(sender: TObject; aCol, aRow: Integer;
|
||||
aState: TGridDrawState);
|
||||
procedure FormActivate(Sender: TObject);
|
||||
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
|
||||
procedure FormDestroy(Sender: TObject);
|
||||
private
|
||||
FLCDDisplay: TLCDDisplay;
|
||||
FSavedCharDefs: TCharDefs;
|
||||
procedure SetLCDDisplay(AValue: TLCDDisplay);
|
||||
procedure PopulateCharSelector;
|
||||
procedure SaveCharDefs;
|
||||
function SelectedChar: String;
|
||||
function SelectedDotMatrix: TDotRows;
|
||||
procedure SetupEditorGrid;
|
||||
|
||||
public
|
||||
property LCDDisplay: TLCDDisplay read FLCDDisplay write SetLCDDisplay;
|
||||
|
||||
end;
|
||||
|
||||
var
|
||||
LCDCharDefsEditor: TLCDCharDefsEditor;
|
||||
|
||||
implementation
|
||||
|
||||
{$R *.lfm}
|
||||
|
||||
uses
|
||||
Math;
|
||||
|
||||
procedure TLCDCharDefsEditor.PopulateCharSelector;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
cbCharSelector.DropdownCount := 24;
|
||||
cbCharSelector.Items.BeginUpdate;
|
||||
try
|
||||
cbCharSelector.Clear;
|
||||
for i := 0 to FLCDDisplay.CharDefs.Count-1 do
|
||||
cbCharSelector.Items.Add(FLCDDisplay.CharDefs.CharByIndex[i]);
|
||||
finally
|
||||
cbCharSelector.Items.EndUpdate;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ This is just a sample allowing me to test the property editor... }
|
||||
procedure TLCDCharDefsEditor.btnDeleteClick(Sender: TObject);
|
||||
var
|
||||
ch: String;
|
||||
begin
|
||||
ch := SelectedChar;
|
||||
if ch <> '' then
|
||||
begin
|
||||
FLCDDisplay.CharDefs.Delete(ch);
|
||||
FLCDDisplay.Invalidate;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLCDCharDefsEditor.cbCharSelectorChange(Sender: TObject);
|
||||
begin
|
||||
dgEditor.Invalidate;
|
||||
end;
|
||||
|
||||
procedure TLCDCharDefsEditor.cbCharSelectorKeyDown(Sender: TObject;
|
||||
var Key: Word; Shift: TShiftState);
|
||||
begin
|
||||
// cbCharSelector.Text := '';
|
||||
end;
|
||||
|
||||
procedure TLCDCharDefsEditor.cbCharSelectorKeyUp(Sender: TObject;
|
||||
var Key: Word; Shift: TShiftState);
|
||||
begin
|
||||
cbCharSelector.SelectAll;
|
||||
end;
|
||||
|
||||
procedure TLCDCharDefsEditor.dgEditorPrepareCanvas(sender: TObject;
|
||||
aCol, aRow: Integer; aState: TGridDrawState);
|
||||
var
|
||||
dotrows: TDotRows;
|
||||
r, c: Integer;
|
||||
dotSet: Boolean;
|
||||
begin
|
||||
dotRows := SelectedDotMatrix;
|
||||
if dotRows = nil then
|
||||
exit;
|
||||
|
||||
r := ARow;
|
||||
c := dgEditor.ColCount - 1 - ACol;
|
||||
dotSet := dotRows[r] and (1 shl c) <> 0;
|
||||
if dotSet then
|
||||
dgEditor.Canvas.Brush.Color := clBlack;
|
||||
end;
|
||||
|
||||
procedure TLCDCharDefsEditor.FormActivate(Sender: TObject);
|
||||
begin
|
||||
Constraints.MinHeight := dgEditor.Top + dgEditor.Height + ButtonPanel.Height + 2*ButtonPanel.BorderSpacing.Around;
|
||||
Constraints.MinWidth := Max(
|
||||
ButtonPanel.OKButton.Left + ButtonPanel.OKButton.Width + ButtonPanel.BorderSpacing.Around,
|
||||
btnDelete.Left + btnDelete.Width + btnDelete.BorderSpacing.Right
|
||||
);
|
||||
end;
|
||||
|
||||
{ When the form is not closed by the OK button, we must restored the saved,
|
||||
original char defs of the FLCDDisplay. }
|
||||
procedure TLCDCharDefsEditor.FormCloseQuery(Sender: TObject;
|
||||
var CanClose: Boolean);
|
||||
begin
|
||||
if CanClose and (ModalResult <> mrOK) then
|
||||
begin
|
||||
FLCDDisplay.CharDefs.Assign(FSavedCharDefs);
|
||||
FLCDDisplay.Invalidate;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLCDCharDefsEditor.FormDestroy(Sender: TObject);
|
||||
begin
|
||||
FreeAndNil(FSavedCharDefs);
|
||||
end;
|
||||
|
||||
{ Save the char defs so that they can be restored if the form is not closed by OK. }
|
||||
procedure TLCDCharDefsEditor.SaveCharDefs;
|
||||
begin
|
||||
FSavedCharDefs.Free;
|
||||
FSavedCharDefs := TCharDefs.Create(nil);
|
||||
FSavedCharDefs.Assign(FLCDDisplay.CharDefs);
|
||||
end;
|
||||
|
||||
{ Returns the currently selected character. Note that this is a string because
|
||||
we have to deal with UTF8 where a code-point can consist of up to 4 bytes. }
|
||||
function TLCDCharDefsEditor.SelectedChar: String;
|
||||
begin
|
||||
Result := cbCharSelector.Text;
|
||||
end;
|
||||
|
||||
function TLCDCharDefsEditor.SelectedDotMatrix: TDotRows;
|
||||
var
|
||||
ch: String;
|
||||
begin
|
||||
ch := SelectedChar;
|
||||
if ch <> '' then
|
||||
Result := FLCDDisplay.CharDefs.DotRows[ch]
|
||||
else
|
||||
Result := nil;
|
||||
end;
|
||||
|
||||
procedure TLCDCharDefsEditor.SetLCDDisplay(AValue: TLCDDisplay);
|
||||
begin
|
||||
FLCDDisplay := AValue;
|
||||
SaveCharDefs;
|
||||
PopulateCharSelector;
|
||||
SetupEditorGrid;
|
||||
end;
|
||||
|
||||
{ Reads the size of the dot matrix from FLCDDisplay and use it to define the
|
||||
number of rows and columns in the editor grid. }
|
||||
procedure TLCDCharDefsEditor.SetupEditorGrid;
|
||||
begin
|
||||
dgEditor.RowCount := FLCDDisplay.DotRowCount;
|
||||
dgEditor.ColCount := FLCDDisplay.DotColCount;
|
||||
dgEditor.ClientWidth := dgEditor.ColCount * dgEditor.DefaultColWidth;
|
||||
dgEditor.ClientHeight := dgEditor.RowCount * dgEditor.DefaultRowHeight;
|
||||
dgEditor.Constraints.MinWidth := dgEditor.Width;
|
||||
dgEditor.Constraints.MinHeight := dgEditor.Height;
|
||||
end;
|
||||
end.
|
||||
|
Reference in New Issue
Block a user