summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
authorgraemeg <graemeg@ae50a9b5-8222-0410-bf8d-8a13f76226bf>2007-09-13 10:45:08 +0000
committergraemeg <graemeg@ae50a9b5-8222-0410-bf8d-8a13f76226bf>2007-09-13 10:45:08 +0000
commit60515a6cef02edd0ccab823569f10238c26f10c7 (patch)
tree7d913e6ed3f587509dcaa2cd81a88fb63982d125 /src/gui
parent97c0f8c9a629842f647e19dc792c055895763f98 (diff)
downloadfpGUI-60515a6cef02edd0ccab823569f10238c26f10c7.tar.xz
* CoreLib: fpgApplication now has a Terminated property which terminates the
main event loop and application. Halt was just to harsh and objects never got freed. * GUI: Added a new INI Utils unit which introduces ReadOnly ini support and can also save a form's state and position. You access the ini file via the gINI singleton function. fpGUI Designer uses this. * All example project now free there main forms correctly. * Many bug fixes in GUI Designer. GUI Designer now also remembers the size and location of most forms. * Many of the GUI Designer forms are now maintained by the GUI Designer itself. * GUI Designer: Started implementing a Recent Files feature so it is quicker to open frequently used files.
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/fpgui_package.lpk16
-rw-r--r--src/gui/fpgui_package.pas7
-rw-r--r--src/gui/gui_form.pas2
-rw-r--r--src/gui/gui_iniutils.pas236
4 files changed, 251 insertions, 10 deletions
diff --git a/src/gui/fpgui_package.lpk b/src/gui/fpgui_package.lpk
index 9ac337fb..d94380a1 100644
--- a/src/gui/fpgui_package.lpk
+++ b/src/gui/fpgui_package.lpk
@@ -6,7 +6,7 @@
<CompilerOptions>
<Version Value="5"/>
<SearchPaths>
- <UnitOutputDirectory Value="../../lib/"/>
+ <UnitOutputDirectory Value="../../lib"/>
</SearchPaths>
<CodeGeneration>
<Generate Value="Faster"/>
@@ -18,7 +18,7 @@
<Description Value="fpGUI - multi-handle redesign"/>
<License Value="Modified LGPL"/>
<Version Minor="5"/>
- <Files Count="22">
+ <Files Count="23">
<Item1>
<Filename Value="gui_button.pas"/>
<UnitName Value="gui_button"/>
@@ -107,15 +107,19 @@
<Filename Value="gui_tree.pas"/>
<UnitName Value="gui_tree"/>
</Item22>
+ <Item23>
+ <Filename Value="gui_iniutils.pas"/>
+ <UnitName Value="gui_iniutils"/>
+ </Item23>
</Files>
<RequiredPkgs Count="2">
<Item1>
- <PackageName Value="FCL"/>
- <MinVersion Major="1" Valid="True"/>
- </Item1>
- <Item2>
<PackageName Value="fpgfx_package"/>
<MinVersion Minor="5" Valid="True"/>
+ </Item1>
+ <Item2>
+ <PackageName Value="FCL"/>
+ <MinVersion Major="1" Valid="True"/>
</Item2>
</RequiredPkgs>
<UsageOptions>
diff --git a/src/gui/fpgui_package.pas b/src/gui/fpgui_package.pas
index 0bd885ab..b08c8134 100644
--- a/src/gui/fpgui_package.pas
+++ b/src/gui/fpgui_package.pas
@@ -8,9 +8,10 @@ interface
uses
gui_button, gui_combobox, gui_dialogs, gui_edit, gui_form, gui_label,
- gui_listbox, gui_memo, gui_scrollbar, gui_bevel, gui_checkbox,
- gui_radiobutton, gui_trackbar, gui_tab, gui_basegrid, gui_listview,
- gui_customgrid, gui_progressbar, gui_menu, gui_style, gui_grid, gui_tree;
+ gui_listbox, gui_memo, gui_scrollbar, gui_bevel, gui_checkbox,
+ gui_radiobutton, gui_trackbar, gui_tab, gui_basegrid, gui_listview,
+ gui_customgrid, gui_progressbar, gui_menu, gui_style, gui_grid, gui_tree,
+ gui_iniutils;
implementation
diff --git a/src/gui/gui_form.pas b/src/gui/gui_form.pas
index 2e5be8ab..0bb25567 100644
--- a/src/gui/gui_form.pas
+++ b/src/gui/gui_form.pas
@@ -292,7 +292,7 @@ procedure TfpgForm.Close;
begin
Hide;
if fpgApplication.MainForm = self then
- Halt(0);
+ fpgApplication.Terminated := True;
end;
diff --git a/src/gui/gui_iniutils.pas b/src/gui/gui_iniutils.pas
new file mode 100644
index 00000000..9d045f3d
--- /dev/null
+++ b/src/gui/gui_iniutils.pas
@@ -0,0 +1,236 @@
+{
+ fpGUI - Free Pascal GUI Library
+
+ Copyright (C) 2006 - 2007 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:
+ This descendant adds ReadOnly support and can read/write Form state
+ information.
+}
+
+unit gui_iniutils;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes,
+ SysUtils,
+ IniFiles,
+ gui_form;
+
+type
+
+ TfpgINIFile = class(TINIFile)
+ private
+ FReadOnly: Boolean;
+ public
+ constructor CreateExt(const AFileName: string = ''; AReadOnly: Boolean = False);
+ function ReadString(const ASection, AIdent, ADefault: string): string; override;
+ function ReadInteger(const ASection, AIdent: string; ADefault: longint): longint; override;
+ function ReadBool(const ASection, AIdent: string; ADefault: Boolean): Boolean; override;
+ function ReadDate(const ASection, AName: string; ADefault: TDateTime): TDateTime; override;
+ function ReadDateTime(const ASection, AName: string; ADefault: TDateTime): TDateTime; override;
+ function ReadFloat(const ASection, AName: string; ADefault: double): double; override;
+ function ReadTime(const ASection, AName: string; ADefault: TDateTime): TDateTime; override;
+ procedure ReadFormState(AForm: TfpgForm; AHeight: integer = -1; AWidth: integer = -1);
+ procedure WriteFormState(AForm: TfpgForm);
+ end;
+
+// singleton
+function gINI(const AFileName: string = ''): TfpgINIFile;
+
+implementation
+
+uses
+ fpgfx;
+
+var
+ uINI: TfpgINIFile;
+
+
+function gINI(const AFileName: string): TfpgINIFile;
+begin
+ if uINI = nil then
+ uINI := TfpgINIFile.CreateExt(AFileName);
+ Result := uINI;
+end;
+
+{ TfpgINIFile }
+
+constructor TfpgINIFile.CreateExt(const AFileName: string; AReadOnly: Boolean);
+var
+ lDir: string;
+ lFileName: string;
+begin
+ FReadOnly := AReadOnly;
+ lDir := ExtractFileDir(AFileName);
+ lFileName := ExtractFileName(AFileName);
+
+ if lDir = '' then
+ lDir := GetAppConfigDir(False);
+ lDir := lDir + PathDelim;
+
+ { We used a non-Global config dir, so should be able to create the dir }
+ if not ForceDirectories(lDir) then
+ raise Exception.Create('Failed to create the directory <' + lDir + '>');
+
+
+ if lFileName = '' then
+ lFileName := ApplicationName + '.ini'
+ else if ExtractFileExt(lFileName) = '' then
+ lFileName := lFileName + '.ini';
+
+ lFileName := lDir + lFileName;
+ Create(lFileName);
+end;
+
+function TfpgINIFile.ReadString(const ASection, AIdent, ADefault: string): string;
+begin
+ Result := inherited ReadString(ASection, AIdent, ADefault);
+ if (not ValueExists(ASection, AIdent)) and
+ (not FReadOnly) then
+ WriteString(ASection, AIdent, ADefault);
+end;
+
+function TfpgINIFile.ReadInteger(const ASection, AIdent: string; ADefault: longint): longint;
+begin
+ if (not ValueExists(ASection, AIdent)) and
+ (not FReadOnly) then
+ WriteInteger(ASection, AIdent, ADefault);
+ Result := inherited ReadInteger(ASection, AIdent, ADefault);
+end;
+
+function TfpgINIFile.ReadBool(const ASection, AIdent: string; ADefault: Boolean): Boolean;
+var
+ lValueExists: Boolean;
+begin
+ lValueExists := ValueExists(ASection, AIdent);
+ if (not lValueExists) and
+ (not FReadOnly) then
+ WriteBool(ASection, AIdent, ADefault);
+ Result := inherited ReadBool(ASection, AIdent, ADefault);
+end;
+
+function TfpgINIFile.ReadDate(const ASection, AName: string; ADefault: TDateTime): TDateTime;
+begin
+ if (not ValueExists(ASection, AName)) and
+ (not FReadOnly) then
+ WriteDate(ASection, AName, ADefault);
+ Result := inherited ReadDate(ASection, AName, ADefault);
+end;
+
+function TfpgINIFile.ReadDateTime(const ASection, AName: string; ADefault: TDateTime): TDateTime;
+begin
+ if (not ValueExists(ASection, AName)) and
+ (not FReadOnly) then
+ WriteDateTime(ASection, AName, ADefault);
+ Result := inherited ReadDateTime(ASection, AName, ADefault);
+end;
+
+function TfpgINIFile.ReadFloat(const ASection, AName: string; ADefault: double): double;
+begin
+ if (not ValueExists(ASection, AName)) and
+ (not FReadOnly) then
+ WriteFloat(ASection, AName, ADefault);
+ Result := inherited ReadFloat(ASection, AName, ADefault);
+end;
+
+function TfpgINIFile.ReadTime(const ASection, AName: string; ADefault: TDateTime): TDateTime;
+begin
+ if (not ValueExists(ASection, AName)) and
+ (not FReadOnly) then
+ WriteTime(ASection, AName, ADefault);
+ Result := inherited ReadTime(ASection, AName, ADefault);
+end;
+
+procedure TfpgINIFile.ReadFormState(AForm: TfpgForm; AHeight: integer; AWidth: integer);
+var
+ LINISection: string;
+ LTop: integer;
+ LLeft: integer;
+ LHeight: integer;
+ LWidth: integer;
+begin
+ Assert(AForm <> nil, 'pForm not assigned');
+ LINISection := AForm.Name + 'State';
+ // Read form position, -1 if not stored in registry
+ LTop := readInteger(LINISection, 'Top', -1);
+ LLeft := readInteger(LINISection, 'Left', -1);
+ // The form pos was found in the registr
+ if (LTop <> -1) and (LLeft <> -1) then
+ begin
+ AForm.Top := readInteger(LINISection, 'Top', AForm.Top);
+ AForm.Left := readInteger(LINISection, 'Left', AForm.Left);
+ AForm.WindowPosition := wpUser;
+ // No form pos in the registry, so default to screen center
+ end
+ else if Assigned(fpgApplication.MainForm) and (fpgApplication.MainForm <> AForm) then
+ AForm.WindowPosition := wpAuto
+ else
+ AForm.WindowPosition := wpScreenCenter;
+ // Only set the form size if a bsSizable window
+ if AForm.Sizeable then
+ begin
+ if AHeight = -1 then
+ LHeight := AForm.Height
+ else
+ LHeight := AHeight;
+ if AWidth = -1 then
+ LWidth := AForm.Width
+ else
+ LWidth := AWidth;
+ AForm.Height := readInteger(LINISection, 'Height', LHeight);
+ AForm.Width := readInteger(LINISection, 'Width', LWidth);
+ end;
+ // AForm.WindowState := TWindowState(ReadInteger(LINISection, 'WindowState', ord(wsNormal)));
+
+ // If the form is off screen (positioned outside all monitor screens) then
+ // center the form on screen.
+ //{$IFDEF MSWINDOWS}
+ //if (AForm.FormStyle <> fsMDIChild) {$IFNDEF FPC} and tiFormOffScreen(AForm) {$ENDIF} then
+ //begin
+ //if Assigned(Application.MainForm) and (Application.MainForm <> AForm) then
+ //AForm.Position := poMainFormCenter
+ //else
+ //AForm.Position:= poScreenCenter;
+ //end;
+ //{$ENDIF MSWINDOWS}
+end;
+
+procedure TfpgINIFile.WriteFormState(AForm: TfpgForm);
+var
+ LINISection: string;
+begin
+ LINISection := AForm.Name + 'State';
+ // writeInteger(LINISection, 'WindowState', ord(AForm.WindowState));
+ // if AForm.WindowState = wsNormal then
+ // begin
+ writeInteger(LINISection, 'Top', AForm.Top);
+ writeInteger(LINISection, 'Left', AForm.Left);
+ if AForm.Sizeable then
+ begin
+ writeInteger(LINISection, 'Height', AForm.Height);
+ WriteInteger(LINISection, 'Width', AForm.Width);
+ end;
+ // end;
+end;
+
+
+initialization
+ uINI := nil;
+
+finalization
+ uINI.Free;
+
+end.
+