diff options
author | graemeg <graemeg@ae50a9b5-8222-0410-bf8d-8a13f76226bf> | 2007-09-13 10:45:08 +0000 |
---|---|---|
committer | graemeg <graemeg@ae50a9b5-8222-0410-bf8d-8a13f76226bf> | 2007-09-13 10:45:08 +0000 |
commit | 60515a6cef02edd0ccab823569f10238c26f10c7 (patch) | |
tree | 7d913e6ed3f587509dcaa2cd81a88fb63982d125 /src/gui | |
parent | 97c0f8c9a629842f647e19dc792c055895763f98 (diff) | |
download | fpGUI-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.lpk | 16 | ||||
-rw-r--r-- | src/gui/fpgui_package.pas | 7 | ||||
-rw-r--r-- | src/gui/gui_form.pas | 2 | ||||
-rw-r--r-- | src/gui/gui_iniutils.pas | 236 |
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. + |