View Issue Details

IDProjectCategoryView StatusLast Update
0027053LazarusCustom Drawnpublic2015-04-29 12:25
ReportertintinuxAssigned ToFelipe Monteiro de Carvalho 
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
PlatformAllOSAllOS VersionAny
Product Version1.2.7 (SVN)Product Build 
Target VersionFixed in Version1.5 (SVN) 
Summary0027053: CDEdit has currently no Text property
DescriptionIn the current implementation TCDEdit has not the Text property.

This property is used a lot with TEdit, and if we want to move to CustomDrawn controls there is a lot of changes to make in existing sources.

Since TCDEdit can be "multiline" (not a good idea IMHO), we must be compatible also with TMemo.
Steps To ReproduceYou can test with the small attached project.
Additional InformationThere are a lot of other properties missing, and also several things are not working, particularly with multiline=true.

This is for me a first attempt to propose changes to CustomDrawn. This one was very easy, maybe I will go on with others later.
TagsCDEdit Text CustomDrawn
Fixed in Revision27053
LazTarget-
WidgetsetCustomDrawn
Attached Files
  • TestCDEdit.zip (2,228 bytes)
  • customdrawn_common.pas.diff (1,049 bytes)
    --- customdrawn_common_old.pas
    +++ customdrawn_common.pas
    @@ -832,7 +832,7 @@
       lLineHeight := Min(ASize.cy-lTextBottomSpacing, lLineHeight);
       lLineTop := lTextTopSpacing + AStateEx.CaretPos.Y * lLineHeight;
     
    -  lTmpText := UTF8Copy(lControlText, AStateEx.VisibleTextStart.X, AStateEx.CaretPos.X-AStateEx.VisibleTextStart.X+1);
    +  lTmpText :=  VisibleText(UTF8Copy(lControlText, AStateEx.VisibleTextStart.X, AStateEx.CaretPos.X-AStateEx.VisibleTextStart.X+1), AStateEx.PasswordChar);
       lCaretPixelPos := ADest.TextWidth(lTmpText) + GetMeasures(TCDEDIT_LEFT_TEXT_SPACING)
         + AStateEx.LeftTextMargin;
       ADest.Pen.Color := clBlack;
    @@ -888,7 +888,7 @@
       // Now draw each line
       for i := 0 to lVisibleLinesCount - 1 do
       begin
    -    lControlText := AStateEx.Lines.Strings[AStateEx.VisibleTextStart.Y+i];
    +    lControlText := VisibleText(AStateEx.Lines.Strings[AStateEx.VisibleTextStart.Y+i], aStateEx.PasswordChar );
         lControlTextLen := UTF8Length(lControlText);
         lLineTop := lTextTopSpacing + i * lLineHeight;
     
    
  • customdrawncontrols.pas.diff (3,715 bytes)
    --- customdrawncontrols_old.pas
    +++ customdrawncontrols.pas
    @@ -203,7 +203,9 @@
         function GetCaretPos: TPoint;
         function GetLeftTextMargin: Integer;
         function GetMultiLine: Boolean;
    +    function GetPasswordChar: Char;
         function GetRightTextMargin: Integer;
    +    function GetText: string;
         procedure HandleCaretTimer(Sender: TObject);
         procedure DoDeleteSelection;
         procedure DoClearSelection;
    @@ -212,9 +214,11 @@
         procedure SetLeftTextMargin(AValue: Integer);
         procedure SetLines(AValue: TStrings);
         procedure SetMultiLine(AValue: Boolean);
    +    procedure SetPasswordChar(AValue: Char);
         procedure SetRightTextMargin(AValue: Integer);
         function MousePosToCaretPos(X, Y: Integer): TPoint;
         function IsSomethingSelected: Boolean;
    +    procedure SetText(AValue: string);
       protected
         FEditState: TCDEditStateEx; // Points to the same object as FStateEx, so don't Free!
         function GetControlId: TCDControlID; override;
    @@ -257,8 +261,10 @@
         property Enabled;
         property Lines: TStrings read FLines write SetLines;
         property MultiLine: Boolean read GetMultiLine write SetMultiLine default False;
    +    property PasswordChar: Char read GetPasswordChar write SetPasswordChar default #0;
         property ReadOnly: Boolean read FReadOnly write FReadOnly default False;
         property TabStop default True;
    +    property Text : string read GetText write SetText stored false; // Lines are stored
         property OnChange: TNotifyEvent read FOnChange write FOnChange;
       end;
     
    @@ -1417,6 +1423,13 @@
       Invalidate;
     end;
     
    +procedure TCDEdit.SetPasswordChar(AValue: Char);
    +begin
    +  if AValue=FEditState.PasswordChar then Exit;
    +  FEditState.PasswordChar := AValue;
    +  Invalidate;
    +end;
    +
     procedure TCDEdit.SetRightTextMargin(AValue: Integer);
     begin
       if FEditState.RightTextMargin = AValue then Exit;
    @@ -1474,9 +1487,26 @@
       Result := FEditState.MultiLine;
     end;
     
    +function TCDEdit.GetPasswordChar: Char;
    +begin
    +  Result := FEditState.PasswordChar;
    +end;
    +
     function TCDEdit.GetRightTextMargin: Integer;
     begin
       Result := FEditState.RightTextMargin;
    +end;
    +
    +function TCDEdit.GetText: string;
    +
    +begin
    +  if Multiline then
    +    result := Lines.Text
    +  else
    +    if Lines.Count = 0 then
    +      result := ''
    +    else
    +      result := Lines[0];
     end;
     
     procedure TCDEdit.DoDeleteSelection;
    @@ -1581,7 +1611,7 @@
       // Find the best X position
       Canvas.Font := Font;
       lVisibleStr := FLines.Strings[Result.Y];
    -  lVisibleStr := UTF8Copy(lVisibleStr, FEditState.VisibleTextStart.X, Length(lVisibleStr));
    +  lVisibleStr := VisibleText( UTF8Copy(lVisibleStr, FEditState.VisibleTextStart.X, Length(lVisibleStr)), FEditState.PasswordChar );
       lStrLen := UTF8Length(lVisibleStr);
       lPos := FDrawer.GetMeasures(TCDEDIT_LEFT_TEXT_SPACING);
       for i := 0 to lStrLen do
    @@ -1614,6 +1644,12 @@
     function TCDEdit.IsSomethingSelected: Boolean;
     begin
       Result := FEditState.SelLength <> 0;
    +end;
    +
    +procedure TCDEdit.SetText(AValue: string);
    +
    +begin
    +  Lines.Text := aValue;
     end;
     
     procedure TCDEdit.DoEnter;
    @@ -1862,7 +1898,11 @@
         lKeyWasProcessed := False;
       end; // case
     
    -  if lKeyWasProcessed then FEditState.EventArrived := True;
    +  if lKeyWasProcessed then
    +  begin
    +    FEditState.EventArrived := True;
    +    Key := 0 ;
    +  end;
     end;
     
     procedure TCDEdit.KeyUp(var Key: word; Shift: TShiftState);
    @@ -1969,6 +2009,7 @@
       FLines := TStringList.Create;
       FEditState.VisibleTextStart := Point(1, 0);
       FEditState.Lines := FLines;
    +  FEditState.PasswordChar := #0;
     
       // Caret code
       FCaretTimer := TTimer.Create(Self);
    
  • customdrawndrawers.pas.diff (1,198 bytes)
    --- customdrawndrawers_old.pas
    +++ customdrawndrawers.pas
    @@ -157,6 +157,7 @@
         LeftTextMargin, RightTextMargin: Integer;
         // For the combo box for example
         ExtraButtonState: TCDControlState;
    +    PasswordChar: Char;
       end;
     
       TCDPanelStateEx = class(TCDControlStateEx)
    @@ -393,10 +394,14 @@
     function GetDefaultDrawer: TCDDrawer;
     function GetDrawer(AStyle: TCDDrawStyle): TCDDrawer;
     
    +function VisibleText ( const aVisibleText : TCaption; const aPasswordChar : char ): TCaption ;
    +
     var
       DefaultStyle: TCDDrawStyle = dsCommon; // For now default to the most complete one, later per platform
     
     implementation
    +
    +uses LazUTF8 ;
     
     var
       RegisteredDrawers: array[TCDDrawStyle] of TCDDrawer
    @@ -676,6 +681,16 @@
       end;
     end;
     
    +// before display the string is replaced by passwordchar if it is not equal to #0
    +function VisibleText ( const aVisibleText : TCaption; const aPasswordChar : char ): TCaption ;
    +
    +begin
    +  if aPasswordChar = #0 then
    +    result := aVisibleText
    +  else
    +    result := StringOfChar( aPasswordChar, UTF8Length(aVisibleText) );
    +end;
    +
     finalization
       // Free all drawers
       for i := 0 to CDDRAWSTYLE_COUNT-1 do
    
  • CustomDrawn.zip (2,578 bytes)

Activities

tintinux

2014-11-18 19:14

reporter  

TestCDEdit.zip (2,228 bytes)

tintinux

2014-11-28 15:48

reporter  

customdrawn_common.pas.diff (1,049 bytes)
--- customdrawn_common_old.pas
+++ customdrawn_common.pas
@@ -832,7 +832,7 @@
   lLineHeight := Min(ASize.cy-lTextBottomSpacing, lLineHeight);
   lLineTop := lTextTopSpacing + AStateEx.CaretPos.Y * lLineHeight;
 
-  lTmpText := UTF8Copy(lControlText, AStateEx.VisibleTextStart.X, AStateEx.CaretPos.X-AStateEx.VisibleTextStart.X+1);
+  lTmpText :=  VisibleText(UTF8Copy(lControlText, AStateEx.VisibleTextStart.X, AStateEx.CaretPos.X-AStateEx.VisibleTextStart.X+1), AStateEx.PasswordChar);
   lCaretPixelPos := ADest.TextWidth(lTmpText) + GetMeasures(TCDEDIT_LEFT_TEXT_SPACING)
     + AStateEx.LeftTextMargin;
   ADest.Pen.Color := clBlack;
@@ -888,7 +888,7 @@
   // Now draw each line
   for i := 0 to lVisibleLinesCount - 1 do
   begin
-    lControlText := AStateEx.Lines.Strings[AStateEx.VisibleTextStart.Y+i];
+    lControlText := VisibleText(AStateEx.Lines.Strings[AStateEx.VisibleTextStart.Y+i], aStateEx.PasswordChar );
     lControlTextLen := UTF8Length(lControlText);
     lLineTop := lTextTopSpacing + i * lLineHeight;
 

tintinux

2014-11-28 15:49

reporter  

customdrawncontrols.pas.diff (3,715 bytes)
--- customdrawncontrols_old.pas
+++ customdrawncontrols.pas
@@ -203,7 +203,9 @@
     function GetCaretPos: TPoint;
     function GetLeftTextMargin: Integer;
     function GetMultiLine: Boolean;
+    function GetPasswordChar: Char;
     function GetRightTextMargin: Integer;
+    function GetText: string;
     procedure HandleCaretTimer(Sender: TObject);
     procedure DoDeleteSelection;
     procedure DoClearSelection;
@@ -212,9 +214,11 @@
     procedure SetLeftTextMargin(AValue: Integer);
     procedure SetLines(AValue: TStrings);
     procedure SetMultiLine(AValue: Boolean);
+    procedure SetPasswordChar(AValue: Char);
     procedure SetRightTextMargin(AValue: Integer);
     function MousePosToCaretPos(X, Y: Integer): TPoint;
     function IsSomethingSelected: Boolean;
+    procedure SetText(AValue: string);
   protected
     FEditState: TCDEditStateEx; // Points to the same object as FStateEx, so don't Free!
     function GetControlId: TCDControlID; override;
@@ -257,8 +261,10 @@
     property Enabled;
     property Lines: TStrings read FLines write SetLines;
     property MultiLine: Boolean read GetMultiLine write SetMultiLine default False;
+    property PasswordChar: Char read GetPasswordChar write SetPasswordChar default #0;
     property ReadOnly: Boolean read FReadOnly write FReadOnly default False;
     property TabStop default True;
+    property Text : string read GetText write SetText stored false; // Lines are stored
     property OnChange: TNotifyEvent read FOnChange write FOnChange;
   end;
 
@@ -1417,6 +1423,13 @@
   Invalidate;
 end;
 
+procedure TCDEdit.SetPasswordChar(AValue: Char);
+begin
+  if AValue=FEditState.PasswordChar then Exit;
+  FEditState.PasswordChar := AValue;
+  Invalidate;
+end;
+
 procedure TCDEdit.SetRightTextMargin(AValue: Integer);
 begin
   if FEditState.RightTextMargin = AValue then Exit;
@@ -1474,9 +1487,26 @@
   Result := FEditState.MultiLine;
 end;
 
+function TCDEdit.GetPasswordChar: Char;
+begin
+  Result := FEditState.PasswordChar;
+end;
+
 function TCDEdit.GetRightTextMargin: Integer;
 begin
   Result := FEditState.RightTextMargin;
+end;
+
+function TCDEdit.GetText: string;
+
+begin
+  if Multiline then
+    result := Lines.Text
+  else
+    if Lines.Count = 0 then
+      result := ''
+    else
+      result := Lines[0];
 end;
 
 procedure TCDEdit.DoDeleteSelection;
@@ -1581,7 +1611,7 @@
   // Find the best X position
   Canvas.Font := Font;
   lVisibleStr := FLines.Strings[Result.Y];
-  lVisibleStr := UTF8Copy(lVisibleStr, FEditState.VisibleTextStart.X, Length(lVisibleStr));
+  lVisibleStr := VisibleText( UTF8Copy(lVisibleStr, FEditState.VisibleTextStart.X, Length(lVisibleStr)), FEditState.PasswordChar );
   lStrLen := UTF8Length(lVisibleStr);
   lPos := FDrawer.GetMeasures(TCDEDIT_LEFT_TEXT_SPACING);
   for i := 0 to lStrLen do
@@ -1614,6 +1644,12 @@
 function TCDEdit.IsSomethingSelected: Boolean;
 begin
   Result := FEditState.SelLength <> 0;
+end;
+
+procedure TCDEdit.SetText(AValue: string);
+
+begin
+  Lines.Text := aValue;
 end;
 
 procedure TCDEdit.DoEnter;
@@ -1862,7 +1898,11 @@
     lKeyWasProcessed := False;
   end; // case
 
-  if lKeyWasProcessed then FEditState.EventArrived := True;
+  if lKeyWasProcessed then
+  begin
+    FEditState.EventArrived := True;
+    Key := 0 ;
+  end;
 end;
 
 procedure TCDEdit.KeyUp(var Key: word; Shift: TShiftState);
@@ -1969,6 +2009,7 @@
   FLines := TStringList.Create;
   FEditState.VisibleTextStart := Point(1, 0);
   FEditState.Lines := FLines;
+  FEditState.PasswordChar := #0;
 
   // Caret code
   FCaretTimer := TTimer.Create(Self);

tintinux

2014-11-28 15:49

reporter  

customdrawndrawers.pas.diff (1,198 bytes)
--- customdrawndrawers_old.pas
+++ customdrawndrawers.pas
@@ -157,6 +157,7 @@
     LeftTextMargin, RightTextMargin: Integer;
     // For the combo box for example
     ExtraButtonState: TCDControlState;
+    PasswordChar: Char;
   end;
 
   TCDPanelStateEx = class(TCDControlStateEx)
@@ -393,10 +394,14 @@
 function GetDefaultDrawer: TCDDrawer;
 function GetDrawer(AStyle: TCDDrawStyle): TCDDrawer;
 
+function VisibleText ( const aVisibleText : TCaption; const aPasswordChar : char ): TCaption ;
+
 var
   DefaultStyle: TCDDrawStyle = dsCommon; // For now default to the most complete one, later per platform
 
 implementation
+
+uses LazUTF8 ;
 
 var
   RegisteredDrawers: array[TCDDrawStyle] of TCDDrawer
@@ -676,6 +681,16 @@
   end;
 end;
 
+// before display the string is replaced by passwordchar if it is not equal to #0
+function VisibleText ( const aVisibleText : TCaption; const aPasswordChar : char ): TCaption ;
+
+begin
+  if aPasswordChar = #0 then
+    result := aVisibleText
+  else
+    result := StringOfChar( aPasswordChar, UTF8Length(aVisibleText) );
+end;
+
 finalization
   // Free all drawers
   for i := 0 to CDDRAWSTYLE_COUNT-1 do

tintinux

2014-11-28 15:49

reporter  

CustomDrawn.zip (2,578 bytes)

tintinux

2014-11-28 16:00

reporter   ~0079446

*** UPDATE ***

I have uploaded 3 diff files for 3 units, and cdedit_text.diff can be deleted.

In addition to the new TCDEdit.Text property, this add also a new TCDEdit.PasswordChar property to allow entering password in the same way as TEdit.

The Keys Left, Right Home and End are now working as in TEdit, no more jumping to the next edit.

There is also an updated test program to check the PasswordChar property. This replace the file TestCDEdit.zip which can be deleted.

It was tested in Windows 32bits and Linux GTK2 64bits and 32 bits. I have no other system available currently.

Juha Manninen

2014-11-29 07:04

developer   ~0079468

I deleted cdedit_text.diff.

Anton

2014-12-02 21:47

reporter   ~0079577

TCDEdit.Text should be Lines.Text, not only Lines[0] (Memo compatability)

tintinux

2015-01-09 08:42

reporter   ~0080237

@Anton : No, Text must not be Lines.Text when Multiline=False, otherwise we get CRLF at the end, and it is not compatible with TEdit.

Text can be equal to Lines.Text only when Multiline is true.

IMHO, it will be confusing for others to have merged TEdit and TMemo. Distinct TCDMemo and TCDEDit would be simpler.

Felipe Monteiro de Carvalho

2015-04-29 12:25

developer   ~0083322

Thanks, I applied with some changes.

Issue History

Date Modified Username Field Change
2014-11-18 19:13 tintinux New Issue
2014-11-18 19:13 tintinux File Added: cdedit_text.diff
2014-11-18 19:14 tintinux File Added: TestCDEdit.zip
2014-11-18 19:15 tintinux Tag Attached: CDEdit Text CustomDrawn
2014-11-28 15:48 tintinux File Added: customdrawn_common.pas.diff
2014-11-28 15:49 tintinux File Added: customdrawncontrols.pas.diff
2014-11-28 15:49 tintinux File Added: customdrawndrawers.pas.diff
2014-11-28 15:49 tintinux File Added: CustomDrawn.zip
2014-11-28 16:00 tintinux Note Added: 0079446
2014-11-29 07:03 Juha Manninen File Deleted: cdedit_text.diff
2014-11-29 07:04 Juha Manninen Note Added: 0079468
2014-12-02 21:47 Anton Note Added: 0079577
2014-12-27 17:45 Felipe Monteiro de Carvalho Assigned To => Felipe Monteiro de Carvalho
2014-12-27 17:45 Felipe Monteiro de Carvalho Status new => assigned
2015-01-09 08:42 tintinux Note Added: 0080237
2015-04-29 12:25 Felipe Monteiro de Carvalho Fixed in Revision => 27053
2015-04-29 12:25 Felipe Monteiro de Carvalho LazTarget => -
2015-04-29 12:25 Felipe Monteiro de Carvalho Note Added: 0083322
2015-04-29 12:25 Felipe Monteiro de Carvalho Status assigned => resolved
2015-04-29 12:25 Felipe Monteiro de Carvalho Fixed in Version => 1.5 (SVN)
2015-04-29 12:25 Felipe Monteiro de Carvalho Resolution open => fixed