diff options
Diffstat (limited to 'gui/edit.inc')
-rw-r--r-- | gui/edit.inc | 375 |
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} + |