summaryrefslogtreecommitdiff
path: root/gui/edit.inc
diff options
context:
space:
mode:
Diffstat (limited to 'gui/edit.inc')
-rw-r--r--gui/edit.inc375
1 files changed, 375 insertions, 0 deletions
diff --git a/gui/edit.inc b/gui/edit.inc
new file mode 100644
index 00000000..3542de5f
--- /dev/null
+++ b/gui/edit.inc
@@ -0,0 +1,375 @@
+{
+ fpGUI - Free Pascal Graphical User Interface
+ Copyright (C) 2000 - 2001 by
+ Areca Systems GmbH / Sebastian Guenther
+ Copyright (C) 2006 by Graeme Geldenhuys
+ member of the fpGUI development team.
+
+ Edit class declarations
+
+ See the file COPYING.fpGUI, included in this distribution,
+ for details about the copyright.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+
+
+{%mainunit fpgui.pp}
+
+{$IFDEF read_interface}
+
+ { TCustomEdit }
+
+ TCustomEdit = class(TWidget)
+ private
+ FFontColor: TColor;
+ FSelStart: integer;
+ FSelOffset: integer;
+ FCursorPos: Integer;
+ FPasswordChar: Char;
+ FOnChange: TNotifyEvent;
+ procedure SetFontColor(const AValue: TColor);
+ procedure SetPasswordChar(APasswordChar: Char);
+ procedure SetCursorPos(ACursorPos: Integer);
+ procedure DoMousePressed(pEvent: TMousePressedEventObj);
+ protected
+ procedure Paint(Canvas: TFCanvas); override;
+ function ProcessEvent(Event: TEventObj): Boolean; override;
+ procedure CalcSizes; override;
+ procedure EvKeyPressed(Key: Word; Shift: TShiftState); override;
+ procedure EvKeyChar(KeyChar: Char); override;
+ procedure EvTextChanged; override;
+ property CanExpandWidth default True;
+ property Cursor default crIBeam;
+ property PasswordChar: Char read FPasswordChar write SetPasswordChar default #0;
+ property CursorPos: Integer read FCursorPos write SetCursorPos;
+ property OnChange: TNotifyEvent read FOnChange write FOnChange;
+ property FontColor: TColor read FFontColor write SetFontColor;
+ procedure SetText(const AText: String); override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ constructor Create(const pText: string; pOwner: TComponent); overload;
+ end;
+
+
+ TEdit = class(TCustomEdit)
+ published
+ property CanExpandWidth;
+ property Enabled;
+ property PasswordChar;
+ property Text;
+ property OnChange;
+ property FontColor;
+ end;
+
+{$ENDIF read_interface}
+
+
+
+{$IFDEF read_implementation}
+
+// ===================================================================
+// TCustomEdit
+// ===================================================================
+
+constructor TCustomEdit.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ WidgetStyle := WidgetStyle + [wsCaptureMouse, wsClickable, wsOpaque];
+ FCanExpandWidth := True;
+ FCursor := crIBeam;
+ FFontColor := clWindowText;
+ FCursorPos := 0;
+end;
+
+
+constructor TCustomEdit.Create(const pText: string; pOwner: TComponent);
+begin
+ Create(pOwner);
+ Text := pText;
+end;
+
+
+procedure TCustomEdit.Paint(Canvas: TFCanvas);
+var
+ Borders: TRect;
+ s: String;
+ x: Integer;
+ ItemRect: TRect;
+ ItemFlags: TItemFlags;
+begin
+ ItemFlags := [];
+ Borders := Style.GetEditBoxBorders;
+
+ Style.DrawEditBox(Canvas, Rect(0, 0, BoundsSize.cx, BoundsSize.cy));
+
+ if not Canvas.IntersectClipRect(Rect(Borders.Left + 1, Borders.Top + 1,
+ BoundsSize.cx - Borders.Right - 1, BoundsSize.cy - Borders.Bottom - 1)) then
+ exit;
+
+ if wsEnabled in WidgetState then
+ Canvas.SetColor(Style.GetUIColor(FFontColor))
+ else
+ Canvas.SetColor(Style.GetUIColor(clGrayText));
+
+ if PasswordChar = #0 then
+ s := PChar(Text)
+ else
+ begin
+ SetLength(s, Length(Text));
+ if Length(Text) > 0 then
+ FillChar(s[1], Length(Text), PasswordChar);
+ end;
+
+
+ // drawing selection
+ if (FSelOffset <> 0) then
+ begin
+ if (wsHasFocus in WidgetState) and FindForm.IsActive then
+ begin
+ Include(ItemFlags, ifFocused);
+ Include(ItemFlags, ifSelected);
+ end;
+
+ ItemRect.Left := Canvas.TextWidth(Copy(s, 1, CursorPos - FSelOffset));
+ ItemRect.Top := 0;
+ ItemRect.Right := Canvas.TextWidth(Copy(s, 1, CursorPos));
+ ItemRect.Bottom := Height;
+{
+ ItemRect := Rect(0, 0, Width, Height);
+ ItemRect.TopLeft := ItemRect.TopLeft + 1;
+ ItemRect.BottomRight := ItemRect.BottomRight - 2;
+}
+// InflateRect(ItemRect, -1, -1);
+
+// Style.SetUIColor(Canvas, clWindowText);
+
+ {$Note Start here: Refine the selection rect}
+ Style.DrawItemBefore(Canvas, ItemRect, ItemFlags);
+ Style.DrawText(Canvas, (Borders.TopLeft + Point(1, 1)), s, WidgetState);
+ Style.DrawItemAfter(Canvas, ItemRect, ItemFlags);
+ end
+ else
+ Canvas.TextOut(Borders.TopLeft + Point(1, 1), s);
+
+
+ if wsHasFocus in WidgetState then
+ begin
+ Canvas.SetColor(Style.GetUIColor(clWindowText));
+ x := Borders.Left + 1 + Canvas.TextWidth(Copy(s, 1, CursorPos));
+ Canvas.DrawLine(Point(x, Borders.Top), Point(x, BoundsSize.cy - Borders.Bottom));
+ end;
+end;
+
+
+function TCustomEdit.ProcessEvent(Event: TEventObj): Boolean;
+begin
+ if Event.InheritsFrom(TMousePressedEventObj) then
+ begin
+// Result := True;
+ DoMousePressed(TMousePressedEventObj(Event));
+// Writeln('>>> TMousePressedEventObj in ' + Classname);
+ end;
+ Result := inherited ProcessEvent(Event);
+end;
+
+
+procedure TCustomEdit.EvKeyPressed(Key: Word; Shift: TShiftState);
+begin
+ if Shift * [ssShift, ssAlt, ssCtrl, ssMeta, ssSuper, ssHyper, ssAltGr] = [] then
+ begin
+// Writeln('1');
+ case Key of
+ keyLeft, keyUp:
+ if CursorPos > 0 then
+ CursorPos := CursorPos - 1;
+ keyRight, keyDown:
+ if CursorPos < Length(Text) then
+ CursorPos := CursorPos + 1;
+ keyHome:
+ CursorPos := 0;
+ keyEnd:
+ CursorPos := Length(Text);
+ else
+ inherited EvKeyPressed(Key, Shift);
+ end;
+ end
+{ else if Shift * [ssShift, ssAlt, ssCtrl, ssMeta, ssSuper, ssHyper, ssAltGr] = [ssShift] then
+ begin
+ Writeln('2');
+ case Key of
+ keyHome:
+ begin
+ FSelOffset := CursorPos;
+ CursorPos := 0;
+ end;
+ keyEnd:
+ begin
+ FSelOffset := CursorPos;
+ CursorPos := Length(Text);
+ end;
+ else
+ EvKeyPressed(Key, Shift);
+ end;
+ end
+}
+ else
+ inherited EvKeyPressed(Key, Shift);
+end;
+
+
+procedure TCustomEdit.EvKeyChar(KeyChar: Char);
+begin
+ case KeyChar of
+ #8: { Backspace }
+ if CursorPos > 0 then
+ begin
+ Text := Copy(Text, 1, CursorPos - 1) + Copy(Text, CursorPos + 1, Length(Text));
+ CursorPos := CursorPos - 1;
+ end;
+ #127: { Del }
+ if CursorPos < Length(Text) then
+ begin
+ Text := Copy(Text, 1, CursorPos) + Copy(Text, CursorPos + 2, Length(Text));
+ Redraw;
+ end;
+ #32..#126, #128..#255:
+ begin
+ Text := Copy(Text, 1, CursorPos) + KeyChar + Copy(Text, CursorPos + 1, Length(Text));
+ CursorPos := CursorPos + 1;
+ end;
+ else
+ inherited EvKeyChar(KeyChar);
+ end;
+end;
+
+
+procedure TCustomEdit.CalcSizes;
+var
+ Borders: TRect;
+begin
+ Borders := Style.GetEditBoxBorders;
+ FMinSize := gfxbase.Size(50, Borders.Top + Borders.Bottom +
+ FindForm.Wnd.Canvas.FontCellHeight + 2);
+end;
+
+
+procedure TCustomEdit.EvTextChanged;
+begin
+ Redraw;
+ if Assigned(OnChange) then
+ OnChange(Self);
+end;
+
+
+procedure TCustomEdit.SetText(const AText: String);
+begin
+ FSelOffset := 0;
+ inherited SetText(AText);
+end;
+
+
+procedure TCustomEdit.SetPasswordChar(APasswordChar: Char);
+begin
+ if APasswordChar <> PasswordChar then
+ begin
+ FPasswordChar := APasswordChar;
+ Redraw;
+ end;
+end;
+
+
+procedure TCustomEdit.SetFontColor(const AValue: TColor);
+begin
+ if FFontColor = AValue then exit;
+ FFontColor := AValue;
+end;
+
+
+procedure TCustomEdit.SetCursorPos(ACursorPos: Integer);
+begin
+ if ACursorPos <> CursorPos then
+ begin
+ FCursorPos := ACursorPos;
+ Redraw;
+ end;
+end;
+
+
+procedure TCustomEdit.DoMousePressed(pEvent: TMousePressedEventObj);
+var
+ Borders: TRect;
+ cp: integer;
+ cpx: integer;
+ lSideMargin: integer;
+ n: integer;
+ cx: integer;
+ lText: string;
+
+ // replicates pStrValue a set of pRepCount times.
+ function lReplicate(const pStrValue : string; pRepCount : Word) : string;
+ var
+ pResult, pValue: PChar;
+ lenValue: cardinal;
+ begin
+ if (pRepCount = 0) or (Pointer(pStrValue) = nil) then
+ exit;
+
+ lenValue := Length(pStrValue);
+ SetLength(Result, lenValue * pRepCount);
+ pResult := Pointer(Result);
+ pValue := Pointer(pStrValue);
+
+ while pRepCount <> 0 do
+ begin
+ Move(pValue^, pResult^, lenValue);
+ Inc(pResult, lenValue);
+ Dec(pRepCount);
+ end;
+ end;
+
+begin
+ if (pEvent.Button = mbLeft) then
+ begin
+ // searching for the appropriate character position
+ Borders := Style.GetEditBoxBorders;
+ lSideMargin := Borders.Left + 1;
+ cp := CursorPos;
+
+ // Make sure we work with the correct displayed text
+ if FPasswordChar = #0 then
+ lText := Text
+ else
+ lText := lReplicate(FPasswordChar, Length(Text));
+
+ cpx := FindForm.Wnd.Canvas.TextWidth(Copy(lText, 1, CursorPos)) + lSideMargin;
+
+ for n := 0 to Length(Text) do
+ begin
+ cx := FindForm.Wnd.Canvas.TextWidth(Copy(lText, 1, n)) + lSideMargin;
+ if abs(cx - pEvent.Position.x) < abs(cpx - pEvent.Position.x) then
+ begin
+ cpx := cx;
+ cp := n;
+ end;
+ end;
+
+ FCursorPos := cp;
+
+ if (ssShift in pEvent.Shift) then
+ begin
+ FSelOffset := FCursorPos - FSelStart;
+ end
+ else
+ begin
+ FSelStart := cp;
+ FSelOffset := 0;
+ end;
+ end;
+end;
+
+{$ENDIF read_implementation}
+