summaryrefslogtreecommitdiff
path: root/uidesigner/vfdprops.pas
diff options
context:
space:
mode:
Diffstat (limited to 'uidesigner/vfdprops.pas')
-rw-r--r--uidesigner/vfdprops.pas696
1 files changed, 696 insertions, 0 deletions
diff --git a/uidesigner/vfdprops.pas b/uidesigner/vfdprops.pas
new file mode 100644
index 00000000..a46b73c5
--- /dev/null
+++ b/uidesigner/vfdprops.pas
@@ -0,0 +1,696 @@
+{
+ fpGUI - Free Pascal GUI Toolkit
+
+ Copyright (C) 2006 - 2008 See the file AUTHORS.txt, included in this
+ distribution, for details of the copyright.
+
+ See the file COPYING.modifiedLGPL, included in this distribution,
+ for details about redistributing fpGUI.
+
+ 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.
+
+ Description:
+ Property editors.
+}
+
+unit vfdprops;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes,
+ SysUtils,
+ gfxbase,
+ gfx_widget,
+ vfdwidgetclass,
+ gui_edit,
+ gui_button,
+ gui_combobox;
+
+type
+
+ TPropertyString = class(TVFDWidgetProperty)
+ public
+ function ParseSourceLine(wg: TfpgWidget; const line: string): boolean; override;
+ function GetPropertySource(wg: TfpgWidget; const ident: string): string; override;
+ function GetValueText(wg: TfpgWidget): string; override;
+ function CreateEditor(AOwner: TComponent): TVFDPropertyEditor; override;
+ end;
+
+
+ TPropertyInteger = class(TVFDWidgetProperty)
+ public
+ function ParseSourceLine(wg: TfpgWidget; const line: string): boolean; override;
+ function GetPropertySource(wg: TfpgWidget; const ident: string): string; override;
+ function GetValueText(wg: TfpgWidget): string; override;
+ function CreateEditor(AOwner: TComponent): TVFDPropertyEditor; override;
+ end;
+
+
+ TPropertyEnum = class(TVFDWidgetProperty)
+ public
+ function ParseSourceLine(wg: TfpgWidget; const line: string): boolean; override;
+ function GetPropertySource(wg: TfpgWidget; const ident: string): string; override;
+ function GetValueText(wg: TfpgWidget): string; override;
+ function CreateEditor(AOwner: TComponent): TVFDPropertyEditor; override;
+ end;
+
+
+ TPropertyStringList = class(TVFDWidgetProperty)
+ public
+ function ParseSourceLine(wg: TfpgWidget; const line: string): boolean; override;
+ function GetPropertySource(wg: TfpgWidget; const ident: string): string; override;
+ function GetValueText(wg: TfpgWidget): string; override;
+ function CreateEditor(AOwner: TComponent): TVFDPropertyEditor; override;
+ procedure OnExternalEdit(wg: TfpgWidget); override;
+ end;
+
+
+ TPropertyBoolean = class(TVFDWidgetProperty)
+ public
+ function ParseSourceLine(wg: TfpgWidget; const line: string): boolean; override;
+ function GetPropertySource(wg: TfpgWidget; const ident: string): string; override;
+ function GetValueText(wg: TfpgWidget): string; override;
+ function CreateEditor(AOwner: TComponent): TVFDPropertyEditor; override;
+ end;
+
+
+ TPropertyFontDesc = class(TPropertyString)
+ function CreateEditor(AOwner: TComponent): TVFDPropertyEditor; override;
+ procedure OnExternalEdit(wg: TfpgWidget); override;
+ end;
+
+
+ TGPEType = (gptInteger, gptString);
+
+
+ TGeneralPropertyEditor = class(TVFDPropertyEditor)
+ private
+ FOrigValue: string;
+ procedure EditExit(Sender: TObject);
+ procedure EditKeyPressed(Sender: TObject; var KeyCode: word;
+ var ShiftState: TShiftState; var Consumed: boolean);
+ public
+ etype: TGPEType;
+ edit: TfpgEdit;
+ procedure CreateLayout; override;
+ procedure LoadValue(wg: TfpgWidget); override;
+ procedure StoreValue(wg: TfpgWidget); override;
+ procedure LoadIntValue(wg: TfpgWidget);
+ procedure StoreIntValue(wg: TfpgWidget);
+ procedure LoadStrValue(wg: TfpgWidget);
+ procedure StoreStrValue(wg: TfpgWidget);
+ end;
+
+
+ TChoicePropertyEditor = class(TVFDPropertyEditor)
+ public
+ chl: TfpgComboBox;
+ procedure CreateLayout; override;
+ procedure LoadValue(wg: TfpgWidget); override;
+ procedure StoreValue(wg: TfpgWidget); override;
+ end;
+
+
+ TBooleanPropertyEditor = class(TChoicePropertyEditor)
+ public
+ procedure LoadValue(wg: TfpgWidget); override;
+ procedure StoreValue(wg: TfpgWidget); override;
+ end;
+
+
+ TExternalPropertyEditor = class(TVFDPropertyEditor)
+ protected
+ procedure HandlePaint; override;
+ public
+ btnEdit: TfpgButton;
+ Widget: TfpgWidget;
+ procedure CreateLayout; override;
+ procedure LoadValue(wg: TfpgWidget); override;
+ procedure StoreValue(wg: TfpgWidget); override;
+ procedure OnEditClick(Sender: TObject);
+ end;
+
+
+procedure EditStringList(sl: TStringList);
+procedure GetEnumPropValueList(wg: TObject; const APropName: string; sl: TStringList);
+
+const
+ DefUndoOnPropExit = False;
+
+var
+ UndoOnPropExit: Boolean = DefUndoOnPropExit;
+
+implementation
+
+uses
+ TypInfo,
+ vfdformparser,
+ vfdeditors,
+ fpgfx,
+ gui_dialogs;
+
+
+procedure EditStringList(sl: TStringList);
+var
+ frm: TItemEditorForm;
+begin
+ frm := TItemEditorForm.Create(nil);
+ try
+ frm.edItems.Lines.Assign(sl);
+ if frm.ShowModal = 1 then
+ sl.Assign(frm.edItems.Lines);
+ finally
+ frm.Free;
+ end;
+end;
+
+procedure GetEnumPropValueList(wg: TObject; const APropName: string; sl: TStringList);
+var
+ lPropInfo: PPropInfo;
+ s: string;
+ lTypeData: PTypeData;
+ n: integer;
+begin
+ lPropInfo := GetPropInfo(wg, APropName);
+ lTypeData := GetTypeData(lPropInfo^.PropType);
+
+ sl.BeginUpdate;
+ try
+ sl.Clear;
+ for n := lTypeData^.MinValue to lTypeData^.MaxValue do
+ begin
+ s := GetEnumName(lPropInfo^.PropType, n);
+ sl.Add(s);
+ end;
+ finally
+ sl.EndUpdate;
+ end;
+end;
+
+{ TPropertyString }
+
+function TPropertyString.CreateEditor(AOwner: TComponent): TVFDPropertyEditor;
+begin
+ Result := TGeneralPropertyEditor.Create(AOwner, self);
+ with TGeneralPropertyEditor(Result) do
+ etype := gptString;
+end;
+
+function TPropertyString.GetPropertySource(wg: TfpgWidget; const ident: string): string;
+begin
+ Result := ident + Name + ' := ' + QuotedStr(GetStrProp(wg, Name)) + ';' + LineEnding;
+end;
+
+function TPropertyString.GetValueText(wg: TfpgWidget): string;
+begin
+ Result := GetStrProp(wg, Name);
+end;
+
+function TPropertyString.ParseSourceLine(wg: TfpgWidget; const line: string): boolean;
+var
+ s, sval: string;
+begin
+ s := line;
+ Result := False;
+ if UpperCase(GetIdentifier(s)) <> UpperCase(Name) then
+ Exit;
+
+ Result := CheckSymbol(s, ':=');
+ if Result then
+ begin
+ sval := GetStringValue(s);
+ Result := CheckSymbol(s, ';');
+ end;
+
+ if Result then
+ SetStrProp(wg, Name, sval);
+end;
+
+
+{ TPropertyInteger }
+
+function TPropertyInteger.CreateEditor(AOwner: TComponent): TVFDPropertyEditor;
+begin
+ Result := TGeneralPropertyEditor.Create(AOwner, self);
+ with TGeneralPropertyEditor(Result) do
+ etype := gptInteger;
+end;
+
+function TPropertyInteger.GetPropertySource(wg: TfpgWidget; const ident: string): string;
+var
+ PropInfo: PPropInfo;
+begin
+ PropInfo := GetPropInfo(wg.ClassType, Name);
+ if PropInfo^.Default <> GetOrdProp(wg, Name) then
+ Result := ident + Name + ' := ' + IntToStr(GetOrdProp(wg, Name)) + ';' + LineEnding
+ else
+ Result := '';
+end;
+
+function TPropertyInteger.GetValueText(wg: TfpgWidget): string;
+begin
+ Result := IntToStr(GetOrdProp(wg, Name));
+end;
+
+function TPropertyInteger.ParseSourceLine(wg: TfpgWidget; const line: string): boolean;
+var
+ s: string;
+ ival: integer;
+begin
+ s := line;
+ Result := False;
+ if UpperCase(GetIdentifier(s)) <> UpperCase(Name) then
+ Exit;
+
+ Result := CheckSymbol(s, ':=');
+ if Result then
+ begin
+ ival := GetIntValue(s);
+ Result := CheckSymbol(s, ';');
+ end
+ else
+ ival := 0;
+
+ if Result then
+ SetOrdProp(wg, Name, ival);
+end;
+
+{ TGeneralPropertyEditor }
+
+procedure TGeneralPropertyEditor.EditExit(Sender: TObject);
+begin
+ if FOrigValue <> edit.Text then
+ if UndoOnPropExit then
+ edit.Text := FOrigvalue
+ else
+ begin
+ UpdateProperty(nil);
+ FOrigValue := edit.Text;
+ end;
+end;
+
+procedure TGeneralPropertyEditor.EditKeyPressed(Sender: TObject;
+ var KeyCode: word; var ShiftState: TShiftState; var Consumed: boolean);
+begin
+ if (KeyCode = keyReturn) or (KeyCode = keyPEnter) then
+ begin
+ UpdateProperty(nil);
+ FOrigValue := edit.Text;
+ end
+ else if (keycode=keyEscape) then
+ begin
+ edit.Text := FOrigValue;
+ end
+ else
+ inherited;
+end;
+
+procedure TGeneralPropertyEditor.CreateLayout;
+begin
+ Anchors := [anTop, anLeft, anRight];
+ Edit := TfpgEdit.Create(self);
+ Edit.SetPosition(0, 0, Width, Height);
+ Edit.Anchors := Anchors;
+// Edit.OnChange := @UpdateProperty;
+ Edit.OnKeyPress := @EditKeyPressed;
+ Edit.OnExit :=@EditExit;
+ Edit.Visible := True;
+end;
+
+procedure TGeneralPropertyEditor.LoadIntValue(wg: TfpgWidget);
+begin
+ edit.Text := IntToStr(GetOrdProp(wg, prop.Name));
+end;
+
+procedure TGeneralPropertyEditor.LoadStrValue(wg: TfpgWidget);
+var
+ s: string;
+begin
+ s := GetStrProp(wg, prop.Name);
+ if etype = gptString then
+ edit.Text := s;
+end;
+
+procedure TGeneralPropertyEditor.LoadValue(wg: TfpgWidget);
+begin
+ case etype of
+ gptInteger:
+ LoadIntValue(wg);
+ else
+ LoadStrValue(wg);
+ end;
+ FOrigValue := edit.Text;
+end;
+
+procedure TGeneralPropertyEditor.StoreIntValue(wg: TfpgWidget);
+var
+ i: integer;
+begin
+ try
+ i := StrToInt(edit.Text);
+ SetOrdProp(wg, Prop.Name, i);
+ except
+ // error
+ end;
+end;
+
+procedure TGeneralPropertyEditor.StoreStrValue(wg: TfpgWidget);
+var
+ s: string;
+begin
+ if etype = gptString then
+ s := edit.Text;
+ SetStrProp(wg, prop.Name, s);
+end;
+
+procedure TGeneralPropertyEditor.StoreValue(wg: TfpgWidget);
+begin
+ case etype of
+ gptInteger: StoreIntValue(wg);
+ else
+ StoreStrValue(wg);
+ end;
+end;
+
+{ TPropertyStringList }
+
+function TPropertyStringList.CreateEditor(AOwner: TComponent): TVFDPropertyEditor;
+begin
+ Result := TExternalPropertyEditor.Create(AOwner, self);
+end;
+
+function TPropertyStringList.GetPropertySource(wg: TfpgWidget; const ident: string): string;
+var
+ sl: TStringList;
+ f: integer;
+begin
+ sl := TStringList(GetObjectProp(wg, Name, TStrings));
+ if not Assigned(sl) then
+ raise Exception.Create('Failed to find TStrings type property.');
+
+ Result := '';
+
+ //if sl.Text <> '' then
+ //begin
+ //writeln('Text = <', sl.Text, '>');
+ //writeln('StringList.Count = ', sl.Count);
+ for f := 0 to sl.Count - 1 do
+ Result := Result + ident + Name + '.Add(' + QuotedStr(sl.Strings[f]) + ');' + LineEnding;
+ //end;
+end;
+
+function TPropertyStringList.GetValueText(wg: TfpgWidget): string;
+var
+ sl: TStringList;
+begin
+ sl := TStringList(GetObjectProp(wg, Name, TStrings));
+ if not Assigned(sl) then
+ raise Exception.Create('Failed to find TStrings type property.');
+ Result := '[' + IntToStr(sl.Count) + ' lines]';
+end;
+
+procedure TPropertyStringList.OnExternalEdit(wg: TfpgWidget);
+var
+ sl: TStringList;
+begin
+ sl := TStringList(GetObjectProp(wg, Name, TStrings));
+ if not Assigned(sl) then
+ raise Exception.Create('Failed to find TStrings type property.');
+ EditStringList(sl);
+end;
+
+function TPropertyStringList.ParseSourceLine(wg: TfpgWidget; const line: string): boolean;
+var
+ s: string;
+ sval: string;
+ sl: TStringList;
+begin
+ s := line;
+ Result := False;
+ if UpperCase(GetIdentifier(s)) <> UpperCase(Name) then
+ Exit;
+
+ Result := CheckSymbol(s, '.');
+ Result := Result and (UpperCase(GetIdentifier(s)) = 'ADD');
+ Result := Result and CheckSymbol(s, '(');
+ if Result then
+ begin
+ sval := GetStringValue(s);
+ Result := Result and CheckSymbol(s, ')');
+ Result := Result and CheckSymbol(s, ';');
+ end;
+
+ if Result then
+ begin
+ sl := TStringList(GetObjectProp(wg, Name, TStrings));
+ if not Assigned(sl) then
+ raise Exception.Create('Failed to find TStrings type property.');
+ sl.Add(sval);
+ end;
+end;
+
+{ TPropertyBoolean }
+
+
+function TPropertyBoolean.ParseSourceLine(wg: TfpgWidget; const line: string): boolean;
+var
+ s: string;
+ bval: boolean;
+begin
+ s := line;
+ Result := False;
+ if UpperCase(GetIdentifier(s)) <> UpperCase(Name) then
+ Exit;
+
+ Result := CheckSymbol(s, ':=');
+ if Result then
+ begin
+ bval := GetBoolValue(s);
+ Result := CheckSymbol(s, ';');
+ end
+ else
+ bval := False;
+
+ if Result then
+ SetOrdProp(wg, Name, Ord(bval));
+end;
+
+function TPropertyBoolean.GetPropertySource(wg: TfpgWidget; const ident: string): string;
+var
+ i: integer;
+ s: string;
+ PropInfo: PPropInfo;
+begin
+ PropInfo := GetPropInfo(wg.ClassType, Name);
+ i := GetOrdProp(wg, Name);
+ if PropInfo^.Default <> i then
+ begin
+ if i = 1 then
+ s := 'True'
+ else
+ s := 'False';
+ Result := ident + Name + ' := ' + s + ';' + LineEnding;
+ end
+ else
+ Result := '';
+end;
+
+function TPropertyBoolean.GetValueText(wg: TfpgWidget): string;
+begin
+ if GetOrdProp(wg, Name) = 1 then
+ Result := 'True'
+ else
+ Result := 'False';
+end;
+
+function TPropertyBoolean.CreateEditor(AOwner: TComponent): TVFDPropertyEditor;
+begin
+ Result := TBooleanPropertyEditor.Create(AOwner, self);
+end;
+
+{ TExternalPropertyEditor }
+
+procedure TExternalPropertyEditor.HandlePaint;
+var
+ r: TfpgRect;
+begin
+// inherited HandlePaint;
+// if not Windowed then
+// Exit;
+ if widget = nil then
+ Exit;
+ Canvas.Clear(clBoxColor);
+ Canvas.GetWinRect(r);
+ Canvas.SetTextColor(clText1);
+ prop.DrawValue(Widget, Canvas, r, 0);
+end;
+
+procedure TExternalPropertyEditor.CreateLayout;
+begin
+ inherited;
+ Widget := nil;
+ Anchors := [anTop, anLeft, anRight];
+
+ btnEdit := TfpgButton.Create(self);
+ with btnEdit do
+ begin
+ Height := self.Height;
+ Width := 24;
+ Top := 0;
+ Left := self.Width - btnEdit.Width;
+ Text := '...';
+ UpdateWindowPosition;
+ Anchors := [anTop, anRight];
+ OnClick := @OnEditClick;
+ Visible := True;
+ end;
+end;
+
+procedure TExternalPropertyEditor.LoadValue(wg: TfpgWidget);
+begin
+ Widget := wg;
+ RePaint;
+end;
+
+procedure TExternalPropertyEditor.OnEditClick(Sender: TObject);
+begin
+ if widget = nil then
+ Exit;
+ prop.OnExternalEdit(widget);
+ widget.Invalidate;
+ RePaint;
+end;
+
+procedure TExternalPropertyEditor.StoreValue(wg: TfpgWidget);
+begin
+ // nothing
+end;
+
+{ TPropertyEnum }
+
+function TPropertyEnum.CreateEditor(AOwner: TComponent): TVFDPropertyEditor;
+begin
+ Result := TChoicePropertyEditor.Create(AOwner, self);
+end;
+
+function TPropertyEnum.GetValueText(wg: TfpgWidget): string;
+begin
+ Result := GetEnumProp(wg, Name);
+end;
+
+function TPropertyEnum.GetPropertySource(wg: TfpgWidget; const ident: string): string;
+var
+ PropInfo: PPropInfo;
+begin
+ PropInfo := GetPropInfo(wg.ClassType, Name);
+ if PropInfo^.Default <> GetOrdProp(wg, Name) then
+ Result := ident + Name + ' := ' + GetEnumProp(wg, Name) + ';' + LineEnding
+ else
+ Result := '';
+end;
+
+function TPropertyEnum.ParseSourceLine(wg: TfpgWidget; const line: string): boolean;
+var
+ s, sval: string;
+begin
+ s := line;
+ Result := False;
+ if UpperCase(GetIdentifier(s)) <> UpperCase(Name) then
+ Exit;
+
+ Result := CheckSymbol(s, ':=');
+ if Result then
+ begin
+ sval := GetIdentifier(s);
+ Result := CheckSymbol(s, ';');
+ end;
+
+ if Result then
+ try
+ SetEnumProp(wg, Name, sval);
+ except
+ Writeln('invalid enum value: "' + sval + '" for ' + Name);
+ Result := False;
+ end;
+end;
+
+{ TChoicePropertyEditor }
+
+procedure TChoicePropertyEditor.CreateLayout;
+begin
+ Anchors := [anTop, anLeft, anRight];
+ chl := TfpgComboBox.Create(self);
+ chl.SetPosition(0, 0, Width, Height);
+ chl.Anchors := Anchors;
+ chl.OnChange := @UpdateProperty;
+ chl.Visible := True;
+end;
+
+procedure TChoicePropertyEditor.LoadValue(wg: TfpgWidget);
+var
+ sv: string;
+ i, fi: integer;
+ sl: TStringList;
+begin
+ sv := GetEnumProp(wg, prop.Name);
+ sl := TStringList.Create;
+ GetEnumPropValueList(wg, prop.Name, sl);
+ fi := 0;
+ for i := 0 to sl.Count - 1 do
+ begin
+ chl.Items.Add(sl.Strings[i]);
+ if UpperCase(sv) = UpperCase(sl.Strings[i]) then
+ fi := i;
+ end;
+ chl.FocusItem := fi;
+ sl.Free;
+end;
+
+procedure TChoicePropertyEditor.StoreValue(wg: TfpgWidget);
+begin
+ SetEnumProp(wg, prop.Name, chl.Text);
+end;
+
+{ TBooleanPropertyEditor }
+
+procedure TBooleanPropertyEditor.LoadValue(wg: TfpgWidget);
+var
+ b: integer;
+begin
+ b := GetOrdProp(wg, prop.Name);
+ chl.Items.Add('True');
+ chl.Items.Add('False');
+ if b = 1 then
+ chl.FocusItem := 0
+ else
+ chl.FocusItem := 1;
+end;
+
+procedure TBooleanPropertyEditor.StoreValue(wg: TfpgWidget);
+begin
+ SetOrdProp(wg, prop.Name, Ord(StrToBool(chl.Text)));
+end;
+
+{ TPropertyFontDesc }
+
+function TPropertyFontDesc.CreateEditor(AOwner: TComponent): TVFDPropertyEditor;
+begin
+ Result := TExternalPropertyEditor.Create(AOwner, self);
+end;
+
+procedure TPropertyFontDesc.OnExternalEdit(wg: TfpgWidget);
+var
+ s: string;
+begin
+ s := GetStrProp(wg, Name);
+ if SelectFontDialog(s) then
+ SetStrProp(wg, Name, s);
+end;
+
+end.
+