diff --git a/components/customdrawn/customdrawn_common.pas b/components/customdrawn/customdrawn_common.pas index 9892d27fc2..22c13cddb0 100644 --- a/components/customdrawn/customdrawn_common.pas +++ b/components/customdrawn/customdrawn_common.pas @@ -55,6 +55,8 @@ type // TCDEdit procedure DrawEditBackground(ADest: TCanvas; ADestPos: TPoint; ASize: TSize; AState: TCDControlState; AStateEx: TCDEditStateEx); override; + procedure DrawEditFrame(ADest: TCanvas; ADestPos: TPoint; ASize: TSize; + AState: TCDControlState; AStateEx: TCDEditStateEx); override; procedure DrawCaret(ADest: TCanvas; ADestPos: TPoint; ASize: TSize; AState: TCDControlState; AStateEx: TCDEditStateEx); override; procedure DrawEdit(ADest: TCanvas; ADestPos: TPoint; ASize: TSize; @@ -137,7 +139,7 @@ end; function TCDDrawerCommon.GetMeasures(AMeasureID: Integer): Integer; begin case AMeasureID of - TCDEDIT_LEFT_TEXT_SPACING: Result := 4; + TCDEDIT_LEFT_TEXT_SPACING: Result := 6; TCDEDIT_RIGHT_TEXT_SPACING: Result := 3; TCDEDIT_TOP_TEXT_SPACING: Result := 3; TCDEDIT_BOTTOM_TEXT_SPACING: Result := 3; @@ -612,9 +614,14 @@ begin ADest.Pen.Color := WIN2000_FRAME_WHITE; ADest.Pen.Style := psSolid; ADest.Rectangle(0, 0, ASize.cx, ASize.cy); +end; +procedure TCDDrawerCommon.DrawEditFrame(ADest: TCanvas; ADestPos: TPoint; + ASize: TSize; AState: TCDControlState; AStateEx: TCDEditStateEx); +begin // The Frame, except the lower-bottom which is white anyway // outter top-right + ADest.Pen.Style := psSolid; ADest.Pen.Color := WIN2000_FRAME_GRAY; ADest.MoveTo(0, ASize.cy-1); ADest.LineTo(0, 0); @@ -644,8 +651,9 @@ begin lCaptionHeight := GetMeasuresEx(ADest, TCDCONTROL_CAPTION_HEIGHT, AState, AStateEx); lTextTopSpacing := GetMeasures(TCDEDIT_TOP_TEXT_SPACING); - lTmpText := UTF8Copy(lControlText, 1, AStateEx.CaretPos.X-AStateEx.VisibleTextStart.X+1); - lCaretPixelPos := ADest.TextWidth(lTmpText) + 3; + lTmpText := UTF8Copy(lControlText, AStateEx.VisibleTextStart.X, AStateEx.CaretPos.X-AStateEx.VisibleTextStart.X+1); + lCaretPixelPos := ADest.TextWidth(lTmpText) + GetMeasures(TCDEDIT_LEFT_TEXT_SPACING) + + AStateEx.LeftTextMargin; ADest.Pen.Color := clBlack; ADest.Pen.Style := psSolid; ADest.Line(lCaretPixelPos, lTextTopSpacing, lCaretPixelPos, lTextTopSpacing+lCaptionHeight); @@ -672,7 +680,7 @@ begin lTextTopSpacing := GetMeasures(TCDEDIT_TOP_TEXT_SPACING); lTextBottomSpacing := GetMeasures(TCDEDIT_BOTTOM_TEXT_SPACING); - // The text without selection + // The text ADest.Pen.Style := psClear; if AStateEx.SelLength = 0 then begin @@ -684,14 +692,19 @@ begin begin lSelLeftPos := AStateEx.SelStart.X; if AStateEx.SelLength < 0 then lSelLeftPos := lSelLeftPos + AStateEx.SelLength; + lSelLeftPos := lSelLeftPos + AStateEx.VisibleTextStart.X-1; + lSelRightPos := AStateEx.SelStart.X; if AStateEx.SelLength > 0 then lSelRightPos := lSelRightPos + AStateEx.SelLength; + lSelRightPos := lSelRightPos + AStateEx.VisibleTextStart.X-1; + lSelLength := AStateEx.SelLength; if lSelLength < 0 then lSelLength := lSelLength * -1; + lSelLength := lSelLength - (AStateEx.VisibleTextStart.X-1); // Text left of the selection lVisibleText := UTF8Copy(lControlText, AStateEx.VisibleTextStart.X, lSelLeftPos-AStateEx.VisibleTextStart.X+1); - ADest.TextOut(4, lTextTopSpacing, lVisibleText); + ADest.TextOut(lTextLeftSpacing, lTextTopSpacing, lVisibleText); lSelLeftPixelPos := ADest.TextWidth(lVisibleText)+lTextLeftSpacing; // The selection background @@ -716,6 +729,9 @@ begin // And the caret DrawCaret(ADest, ADestPos, ASize, AState, AStateEx); + + // In the end the frame, because it must be on top of everything + DrawEditFrame(ADest, ADestPos, ASize, AState, AStateEx); end; procedure TCDDrawerCommon.DrawCheckBoxSquare(ADest: TCanvas; ADestPos: TPoint; diff --git a/components/customdrawn/customdrawn_wince.pas b/components/customdrawn/customdrawn_wince.pas index 7c55c41137..d7955f0524 100644 --- a/components/customdrawn/customdrawn_wince.pas +++ b/components/customdrawn/customdrawn_wince.pas @@ -34,7 +34,7 @@ type procedure DrawButton(ADest: TCanvas; ADestPos: TPoint; ASize: TSize; AState: TCDControlState; AStateEx: TCDButtonStateEx); override; // TCDEdit - procedure DrawEditBackground(ADest: TCanvas; ADestPos: TPoint; ASize: TSize; + procedure DrawEditFrame(ADest: TCanvas; ADestPos: TPoint; ASize: TSize; AState: TCDControlState; AStateEx: TCDEditStateEx); override; procedure DrawCaret(ADest: TCanvas; ADestPos: TPoint; ASize: TSize; AState: TCDControlState; AStateEx: TCDEditStateEx); override; @@ -121,12 +121,11 @@ begin (ASize.cy - ADest.TextHeight(Str)) div 2, Str); end; -procedure TCDDrawerWinCE.DrawEditBackground(ADest: TCanvas; ADestPos: TPoint; +procedure TCDDrawerWinCE.DrawEditFrame(ADest: TCanvas; ADestPos: TPoint; ASize: TSize; AState: TCDControlState; AStateEx: TCDEditStateEx); begin - // The background - ADest.Brush.Color := clWhite; - ADest.Brush.Style := bsSolid; + // The frame + ADest.Brush.Style := bsClear; ADest.Pen.Color := clBlack; ADest.Pen.Style := psSolid; ADest.Rectangle(0, 0, ASize.cx, ASize.cy); diff --git a/components/customdrawn/customdrawn_winxp.pas b/components/customdrawn/customdrawn_winxp.pas index e2e5e9f030..e9a6cb8bff 100644 --- a/components/customdrawn/customdrawn_winxp.pas +++ b/components/customdrawn/customdrawn_winxp.pas @@ -41,7 +41,7 @@ type procedure DrawButton(ADest: TCanvas; ADestPos: TPoint; ASize: TSize; AState: TCDControlState; AStateEx: TCDButtonStateEx); override; // TCDEdit - procedure DrawEditBackground(ADest: TCanvas; ADestPos: TPoint; ASize: TSize; + procedure DrawEditFrame(ADest: TCanvas; ADestPos: TPoint; ASize: TSize; AState: TCDControlState; AStateEx: TCDEditStateEx); override; // TCDCheckBox procedure DrawCheckBoxSquare(ADest: TCanvas; ADestPos: TPoint; ASize: TSize; @@ -176,12 +176,11 @@ begin (ASize.cy - ADest.TextHeight(Str)) div 2, Str); end; -procedure TCDDrawerWinXP.DrawEditBackground(ADest: TCanvas; ADestPos: TPoint; +procedure TCDDrawerWinXP.DrawEditFrame(ADest: TCanvas; ADestPos: TPoint; ASize: TSize; AState: TCDControlState; AStateEx: TCDEditStateEx); begin - // The background - ADest.Brush.Color := clWhite; - ADest.Brush.Style := bsSolid; + // The frame + ADest.Brush.Style := bsClear; ADest.Pen.Color := WINXP_FRAME_BLUE; ADest.Pen.Style := psSolid; ADest.Rectangle(0, 0, ASize.cx, ASize.cy); diff --git a/components/customdrawn/customdrawncontrols.pas b/components/customdrawn/customdrawncontrols.pas index 6288c9befc..81597ac55b 100644 --- a/components/customdrawn/customdrawncontrols.pas +++ b/components/customdrawn/customdrawncontrols.pas @@ -146,6 +146,7 @@ type property Enabled; property Font; property Glyph: TBitmap read FGlyph write SetGlyph; +// property IsToggleBox: Boolean read FGlyph write SetGlyph; property OnChangeBounds; property OnClick; property OnContextPopup; @@ -181,11 +182,15 @@ type DragDropStarted: boolean; FCaretTimer: TTimer; FEditState: TCDEditStateEx; // Points to the same object as FStateEx, so don't Free! + function GetLeftTextMargin: Integer; + function GetRightTextMargin: Integer; procedure HandleCaretTimer(Sender: TObject); procedure DoDeleteSelection; procedure DoClearSelection; procedure DoManageVisibleTextStart; function GetText: string; + procedure SetLeftTextMargin(AValue: Integer); + procedure SetRightTextMargin(AValue: Integer); procedure SetText(AValue: string); function MousePosToCaretPos(X, Y: Integer): TPoint; function IsSomethingSelected: Boolean; @@ -208,6 +213,8 @@ type public constructor Create(AOwner: TComponent); override; destructor Destroy; override; + property LeftTextMargin: Integer read GetLeftTextMargin write SetLeftTextMargin; + property RightTextMargin: Integer read GetRightTextMargin write SetRightTextMargin; published property Align; property Anchors; @@ -1036,6 +1043,20 @@ begin Result := Caption; end; +procedure TCDEdit.SetLeftTextMargin(AValue: Integer); +begin + if FEditState.LeftTextMargin = AValue then Exit; + FEditState.LeftTextMargin := AValue; + Invalidate; +end; + +procedure TCDEdit.SetRightTextMargin(AValue: Integer); +begin + if FEditState.RightTextMargin = AValue then Exit; + FEditState.RightTextMargin := AValue; + Invalidate; +end; + function TCDEdit.GetControlId: TCDControlID; begin Result := cidEdit; @@ -1059,6 +1080,16 @@ begin Invalidate; end; +function TCDEdit.GetLeftTextMargin: Integer; +begin + Result := FEditState.LeftTextMargin; +end; + +function TCDEdit.GetRightTextMargin: Integer; +begin + Result := FEditState.RightTextMargin; +end; + procedure TCDEdit.DoDeleteSelection; var lSelLeftPos, lSelRightPos, lSelLength: Integer; @@ -1111,7 +1142,7 @@ begin - FDrawer.GetMeasures(TCDEDIT_LEFT_TEXT_SPACING) - FDrawer.GetMeasures(TCDEDIT_RIGHT_TEXT_SPACING); lVisibleTextCharCount := Canvas.TextFitInfo(lText, lAvailableWidth); - FEditState.VisibleTextStart.X := Max(FEditState.CaretPos.X-lVisibleTextCharCount, FEditState.VisibleTextStart.X); + FEditState.VisibleTextStart.X := Max(FEditState.CaretPos.X-lVisibleTextCharCount+1, FEditState.VisibleTextStart.X); end; procedure TCDEdit.SetText(AValue: string); @@ -1241,6 +1272,42 @@ begin DoManageVisibleTextStart(); FEditState.CaretIsVisible := True; Invalidate; + end + // if we are not moving, at least deselect + else if ([ssShift] <> Shift) then + begin + FEditState.SelLength := 0; + Invalidate; + end; + end; + VK_HOME: + begin + if (FEditState.CaretPos.X > 0) then + begin + // Selecting to the left + if [ssShift] = Shift then + begin + if FEditState.SelLength = 0 then + begin + FEditState.SelStart.X := FEditState.CaretPos.X; + FEditState.SelLength := -1 * FEditState.CaretPos.X; + end + else + FEditState.SelLength := -1 * FEditState.SelStart.X; + end + // Normal move to the left + else FEditState.SelLength := 0; + + FEditState.CaretPos.X := 0; + DoManageVisibleTextStart(); + FEditState.CaretIsVisible := True; + Invalidate; + end + // if we are not moving, at least deselect + else if (FEditState.SelLength <> 0) and ([ssShift] <> Shift) then + begin + FEditState.SelLength := 0; + Invalidate; end; end; VK_RIGHT: @@ -1260,6 +1327,38 @@ begin DoManageVisibleTextStart(); FEditState.CaretIsVisible := True; Invalidate; + end + // if we are not moving, at least deselect + else if ([ssShift] <> Shift) then + begin + FEditState.SelLength := 0; + Invalidate; + end; + end; + VK_END: + begin + if FEditState.CaretPos.X < lOldTextLength then + begin + // Selecting to the right + if [ssShift] = Shift then + begin + if FEditState.SelLength = 0 then + FEditState.SelStart.X := FEditState.CaretPos.X; + FEditState.SelLength := lOldTextLength - FEditState.SelStart.X; + end + // Normal move to the right + else FEditState.SelLength := 0; + + FEditState.CaretPos.X := lOldTextLength; + DoManageVisibleTextStart(); + FEditState.CaretIsVisible := True; + Invalidate; + end + // if we are not moving, at least deselect + else if (FEditState.SelLength <> 0) and ([ssShift] <> Shift) then + begin + FEditState.SelLength := 0; + Invalidate; end; end; diff --git a/components/customdrawn/customdrawndrawers.pas b/components/customdrawn/customdrawndrawers.pas index 984fb55969..9d62e7803c 100644 --- a/components/customdrawn/customdrawndrawers.pas +++ b/components/customdrawn/customdrawndrawers.pas @@ -148,6 +148,8 @@ type SelLength: Integer; // zero means no selection. Negative numbers selection to the left from the start and positive ones to the right VisibleTextStart: TPoint; // X is 1-based EventArrived: Boolean; // Added by event handlers and used by the caret so that it stops blinking while events are incoming + // customizable extra margins, zero is the base value + LeftTextMargin, RightTextMargin: Integer; end; TCDPositionedCStateEx = class(TCDControlStateEx) @@ -288,6 +290,8 @@ type // TCDEdit procedure DrawEditBackground(ADest: TCanvas; ADestPos: TPoint; ASize: TSize; AState: TCDControlState; AStateEx: TCDEditStateEx); virtual; abstract; + procedure DrawEditFrame(ADest: TCanvas; ADestPos: TPoint; ASize: TSize; + AState: TCDControlState; AStateEx: TCDEditStateEx); virtual; abstract; procedure DrawCaret(ADest: TCanvas; ADestPos: TPoint; ASize: TSize; AState: TCDControlState; AStateEx: TCDEditStateEx); virtual; abstract; procedure DrawEdit(ADest: TCanvas; ADestPos: TPoint; ASize: TSize;