diff options
author | graemeg <graemeg@ae50a9b5-8222-0410-bf8d-8a13f76226bf> | 2007-07-25 14:00:35 +0000 |
---|---|---|
committer | graemeg <graemeg@ae50a9b5-8222-0410-bf8d-8a13f76226bf> | 2007-07-25 14:00:35 +0000 |
commit | a8a43f41c2a12ff4bb13a33b730edacd59fd21d5 (patch) | |
tree | 854997db2b923a055db0368347ea88fe883b1f39 /src/corelib | |
parent | fca7347de9404de1f2940d58dae9bdda6ed52caf (diff) | |
download | fpGUI-a8a43f41c2a12ff4bb13a33b730edacd59fd21d5.tar.xz |
* Implemented and added a new unit that will handle command line parameters.
* Implemented and added a new CheckBox widget. (needs testing under Windows).
* Made some timer changes for Windows (needs testing).
* Moved the global variable for the MainForm into the TfpgApplication class. I can almost remove the gui_form requirement from GFX.
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/fpgfx.pas | 19 | ||||
-rw-r--r-- | src/corelib/gdi/gfx_gdi.pas | 15 | ||||
-rw-r--r-- | src/corelib/gfx_cmdlineparams.pas | 432 | ||||
-rw-r--r-- | src/corelib/gfxbase.pas | 2 | ||||
-rw-r--r-- | src/corelib/x11/fpgfx_package.lpk | 6 | ||||
-rw-r--r-- | src/corelib/x11/fpgfx_package.pas | 2 | ||||
-rw-r--r-- | src/corelib/x11/gfx_x11.pas | 7 |
7 files changed, 461 insertions, 22 deletions
diff --git a/src/corelib/fpgfx.pas b/src/corelib/fpgfx.pas index e38c8700..434b5e40 100644 --- a/src/corelib/fpgfx.pas +++ b/src/corelib/fpgfx.pas @@ -184,7 +184,7 @@ type end; - TfpgTimer = class + TfpgTimer = class(TObject) private FEnabled: boolean; FNextAlarm: TDateTime; @@ -323,18 +323,21 @@ begin for n := 1 to fpgTimers.Count do begin t := TfpgTimer(fpgTimers[n - 1]); - if t.Enabled and (t.NextAlarm < dt) then begin + if t.Enabled and (t.NextAlarm < dt) then + begin dt := t.NextAlarm; tb := True; end; end; - if tb then begin + if tb then + begin Result := trunc(0.5 + (dt - ctime) / ONE_MILISEC); if Result < 0 then Result := 0; end - else Result := -1; + else + Result := -1; end; procedure TfpgTimer.SetEnabled(const AValue: boolean); @@ -371,7 +374,7 @@ end; procedure TfpgTimer.CheckAlarm(ctime: TDateTime); begin if not FEnabled then - Exit; + Exit; //==> if FNextAlarm <= ctime then begin @@ -380,8 +383,8 @@ begin while FNextAlarm <= ctime do FNextAlarm := FNextAlarm + interval * ONE_MILISEC; - if Assigned(OnTimer) then - OnTimer(self); + if Assigned(FOnTimer) then + FOnTimer(self); end; end; @@ -526,7 +529,7 @@ end; procedure TfpgApplication.Initialize; begin - {$Note remember to process parameter!! } + {$Note Remember to process parameters!! } if IsInitialized then InternalInit else diff --git a/src/corelib/gdi/gfx_gdi.pas b/src/corelib/gdi/gfx_gdi.pas index 5e53cf56..b49367a4 100644 --- a/src/corelib/gdi/gfx_gdi.pas +++ b/src/corelib/gdi/gfx_gdi.pas @@ -160,7 +160,6 @@ type FFocusedWindow: THANDLE; LastClickWindow: TfpgWinHandle; // double click generation LastWinClickTime: longword; - FTimerWnd: HWND; public constructor Create(const aparams: string); override; function DoMessagesPending: boolean; @@ -742,19 +741,19 @@ procedure TfpgApplicationImpl.DoWaitWindowMessage(atimeoutms: integer); var Msg: TMsg; timerid: longword; - timerwnd: HWND; + ltimerWnd: HWND; mp: boolean; begin timerid := 0; - timerwnd := 0; + ltimerWnd := TfpgWindomImpl(wapplication.MainForm).WinHandle; if (atimeoutms >= 0) and (not DoMessagesPending) then + begin if atimeoutms > 0 then - timerid := Windows.SetTimer(timerwnd, 1, atimeoutms, nil) - {$Note This needs to be enabled again, but find a butter solution.} - // timerwnd := fpgMainForm.WinHandle; + timerid := Windows.SetTimer(ltimerWnd, 1, atimeoutms, nil) else Exit; // handling waiting timeout + end; {$Note Incorporate Felipe's code from previous fpGUI in here. It handles WinCE and Windows just fine. } if (GetVersion() < $80000000) then @@ -764,8 +763,8 @@ begin Windows.DispatchMessage(@msg); - if timerid > 0 then - Windows.KillTimer(timerwnd, 1); + if timerid <> 0 then + Windows.KillTimer(ltimerWnd, 1); // same IDEvent as used in SetTimer end; procedure TfpgApplicationImpl.DoFlush; diff --git a/src/corelib/gfx_cmdlineparams.pas b/src/corelib/gfx_cmdlineparams.pas new file mode 100644 index 00000000..1e833f81 --- /dev/null +++ b/src/corelib/gfx_cmdlineparams.pas @@ -0,0 +1,432 @@ +{ + fpGUI - Free Pascal GUI Library + + Unit to handle command line processing + + Copyright (C) 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. +} + +unit gfx_cmdlineparams; + +{$mode objfpc}{$H+} + +interface +uses + Classes; + +const + ctiCommandLineParamPrefix = '-'; + +type + + TGfxCommandLineParams = class(TObject) + private + FsParams: string; + FslParams: TStringList; + procedure ReadParams; + function WordExtract(const AInput: string; const APos: integer; const ADelims: string): string; + function WordCount(const AStrToProcess: string; ADelims: string): integer; + function WordPosition(const AN: integer; const AStr: string; ADelims: string): integer; + function ExtractChar(const AValue: string; const APos: integer): char; + function CharInStr(const AChr: char; const AStr: string): boolean; + function StripLeadingDelims(const AStrToProcess: string; ADelims: string): string; + function StripTrailingDelims(const AStrToProcess: string; ADelims: string): string; + function NumToken(const AValue, AToken: string): integer; + function Token(const AValue, AToken: string; const APos: integer): string; + function StrTran(AValue, ADel, AIns: string): string; + public + constructor Create; + destructor Destroy; override; + function IsParam(const AParam: string): boolean; overload; + function IsParam(const AParams: array of string): boolean; overload; + function GetParam(const AParam: string): string; + property Params: TStringList read FslParams; + property AsString: string read FsParams; + end; + + +// Singleton +function gCommandLineParams: TGfxCommandLineParams; + + +implementation + +uses + SysUtils; + +var + uCommandLineParams: TGfxCommandLineParams; + +// Singleton +function gCommandLineParams: TGfxCommandLineParams; +begin + if uCommandLineParams = nil then + uCommandLineParams := TGfxCommandLineParams.Create; + result := uCommandLineParams; +end; + +{ TGfxCommandLineParams } + +constructor TGfxCommandLineParams.Create; +begin + inherited; + FslParams := TStringList.Create; + ReadParams; +end; + +destructor TGfxCommandLineParams.destroy; +begin + FslParams.Free; + inherited; +end; + +function TGfxCommandLineParams.GetParam(const AParam: string): string; +begin + result := FslParams.Values[ upperCase(AParam)]; +end; + +function TGfxCommandLineParams.IsParam(const AParam: string): boolean; +var + i: integer; +begin + result := false; + for i := 0 to FslParams.Count - 1 do begin + if FslParams.Names[i] = upperCase(AParam) then begin + result := true; + break; //==> + end; + end; +end; + +function TGfxCommandLineParams.IsParam(const AParams: array of string): boolean; +var + i: integer; +begin + result := false; + for i := Low(AParams) to High(AParams) do + if IsParam(AParams[i]) then + begin + result := true; + Exit; //==> + end; +end; + +procedure TGfxCommandLineParams.ReadParams; +var + i: integer; + j: integer; + lsNameValue: string; + lsValue: string; + lsName: string; +const + cDelim = ' '; +begin + lsValue := ''; + FsParams := ''; + j := ParamCount; + for i := 1 to j do begin + if FsParams <> '' then FsParams := FsParams + cDelim; + FsParams := FsParams + ParamStr(i); + end ; + + j := WordCount(FsParams, ctiCommandLineParamPrefix); + for i := 1 to j do begin + lsNameValue := WordExtract(FsParams, i, ctiCommandLineParamPrefix); + lsName := Token(lsNameValue, cDelim, 1); + lsValue := copy(lsNameValue, length(lsName) + 1, + length(FsParams) - length(lsValue)); + + lsValue := Trim(lsValue); + lsName := StrTran(lsName, ctiCommandLineParamPrefix, ''); + lsName := upperCase(lsName); + + FslParams.Add(lsName + '=' + lsValue); + end; +end; + +function TGfxCommandLineParams.StrTran(AValue, ADel, AIns: string): string; +var + i: integer; + sToChange: string; +begin + result := ''; + sToChange := AValue; + i := pos(ADel, sToChange); + while i <> 0 do + begin + result := result + copy(sToChange, 1, i-1) + AIns; + delete(sToChange, 1, i+length(ADel)-1); + i := pos(ADel, sToChange); + end; + result := result + sToChange; +end; + +function TGfxCommandLineParams.NumToken(const AValue, AToken: string): integer; +var + i, iCount: integer; + lsValue: string; +begin + result := 0; + if AValue = '' then + Exit; //==> + + iCount := 0; + lsValue := AValue; + i := pos(AToken, lsValue); + while i <> 0 do + begin + delete(lsValue, i, length(AToken)); + inc(iCount); + i := pos(AToken, lsValue); + end; + result := iCount + 1; +end; + +function TGfxCommandLineParams.Token(const AValue, AToken: string; + const APos: integer): string; +var + i, iCount, iNumToken: integer; + lsValue: string; +begin + result := ''; + + iNumToken := NumToken(AValue, AToken); + if APos = 1 then + begin + if pos(AToken, AValue) = 0 then + result := AValue + else + result := copy(AValue, 1, pos(AToken, AValue)-1); + end + else if (iNumToken < APos-1) or (APos<1) then + begin + result := ''; + end + else + begin + { Remove leading blocks } + iCount := 1; + lsValue := AValue; + i := pos(AToken, lsValue); + while (i<>0) and (iCount<APos) do + begin + delete(lsValue, 1, i + length(AToken) - 1); + inc(iCount); + i := pos(AToken, lsValue); + end; + + if (i=0) and (iCount=APos) then + result := lsValue + else if (i=0) and (iCount<>APos) then + result := '' + else + result := copy(lsValue, 1, i-1); + end; +end; + +function TGfxCommandLineParams.WordExtract(const AInput: string; + const APos: integer; const ADelims: string): string; +var + iStart: integer; + i: integer; + iLen: integer; +begin + result := ''; + + // Find the starting pos of the Nth word + iStart := WordPosition(APos, AInput, ADelims); + + if iStart <> 0 then + begin + i := iStart; + iLen := length(AInput); + // Build up result until we come to our next wordDelim + // while (i <= iLen) and not(S[i] in ADelims) do begin + while (i <= iLen) and not(CharInStr(ExtractChar(AInput, i), ADelims)) do + begin + result := result + ExtractChar(AInput, i); + inc(i); + end; + end; +end; + +function TGfxCommandLineParams.WordPosition(const AN: integer; + const AStr: string; ADelims: string): integer; +var + lCount: integer; + lI: Word; + lSLen: integer; +begin + lCount := 0; + lI := 1; + Result := 0; + lSLen := length(AStr); + + while (lI <= lSLen) and (lCount <> AN) do + begin + while (lI <= lSLen) and (CharInStr(ExtractChar(AStr, lI), ADelims)) do + begin + Inc(lI); + end; + + // if we're not beyond end of S, we're at the start of a word + if lI <= lSLen then + begin + Inc(lCount); + end; + + // if not finished, find the end of the current word + if lCount <> AN then + begin + while (lI <= lSLen) and not(CharInStr(ExtractChar(AStr, lI), ADelims)) do + begin + Inc(lI); + end; + end + else + begin + Result := lI; + end; + end; +end; + +function TGfxCommandLineParams.ExtractChar(const AValue: string; + const APos: integer): char; +var + lResult: string; +begin + if APos > length(AValue) then + begin + result := ' '; + exit; + end; + lResult := copy(AValue, APos, 1); + result := lResult[1]; +end; + +function TGfxCommandLineParams.StripLeadingDelims(const AStrToProcess: string; + ADelims: string): string; +var + i: integer; + lCharCurrent: char; +begin + result := AStrToProcess; + // Loop through each char in the string + for i := 1 to length(AStrToProcess) do + begin + // Extract the current character + lCharCurrent := ExtractChar(AStrToProcess, i); + + // Is this character a NON word delim?, then we have found the body of the string. + if not CharInStr(lCharCurrent, ADelims) then + begin + result := copy(AStrToProcess, i, + length(AStrToProcess) - i + 1); + exit; //==> + // The current char is a word delim, but we are at the end of the string - + // so no words + end + else + begin + if i = length(AStrToProcess) then + begin + result := ''; + end; + end; + end; +end; + +// Strip any trailing ADelims +function TGfxCommandLineParams.StripTrailingDelims(const AStrToProcess: string; + ADelims: string): string; +var + i: integer; + lCharCurrent: char; +begin + result := AStrToProcess; + // Loop through each char in the string + for i := length(AStrToProcess) downto 1 do + begin + // Extract the current character + lCharCurrent := ExtractChar(AStrToProcess, i); + + // Is this character a NON word delim?, then we have found the body of the string. + if not CharInStr(lCharCurrent, ADelims) then + begin + result := copy(AStrToProcess, 1, i); + exit; //==> + // The current char is a word delim, but we are at the beginning of the string - + // so no words + end + else + begin + if i = length(AStrToProcess) then + begin + result := ''; + end; + end; + end; +end; + +// Given a set of word delimiters, return number of words in S +function TGfxCommandLineParams.WordCount(const AStrToProcess: string; + ADelims: string): integer; +var + i: integer; + lCharLast: char; + lCharCurrent: char; + lStrToProcess: string; +begin + // Strip any leading ADelims + lStrToProcess := StripLeadingDelims(AStrToProcess, ADelims); + lStrToProcess := StripTrailingDelims(lStrToProcess, ADelims); + + // If lStrToProcess is empty, then there are no words + if lStrToProcess = '' then + begin + result := 0; + Exit; //==> + end; + + // lStrToProcess is not empty, therefore there must be at least one word + // Every wordDelim we find equals another word: + // 0 word delim := 1 word + // 1 word delim := 2 words... + result := 1; + + // lCharLast is used to check for more than 1 wordDelim together + lCharLast := #0; + + for i := 1 to length(lStrToProcess) do + begin + lCharCurrent := ExtractChar(lStrToProcess, i); + if CharInStr(lCharCurrent, ADelims) and not(CharInStr(lCharLast, ADelims)) then + begin + inc(result); + end; + lCharLast := lCharCurrent; + end; +end; + +// Is AChr in the string AStr ? +function TGfxCommandLineParams.CharInStr(const AChr: char; const AStr: string): boolean; +begin + result := pos(AChr, AStr) <> 0; +end; + + +initialization + +finalization + uCommandLineParams.Free; + +end. + diff --git a/src/corelib/gfxbase.pas b/src/corelib/gfxbase.pas index 5add81ad..28149f8f 100644 --- a/src/corelib/gfxbase.pas +++ b/src/corelib/gfxbase.pas @@ -349,6 +349,7 @@ type TfpgApplicationBase = class(TObject) private + FMainForm: TfpgWindowBase; FTopModalForm: TfpgWindowBase; protected FIsInitialized: Boolean; @@ -356,6 +357,7 @@ type constructor Create(const AParams: string); virtual; abstract; property IsInitialized: boolean read FIsInitialized; property TopModalForm: TfpgWindowBase read FTopModalForm write FTopModalForm; + property MainForm: TfpgWindowBase read FMainForm write FMainForm; end; diff --git a/src/corelib/x11/fpgfx_package.lpk b/src/corelib/x11/fpgfx_package.lpk index 1521ea5a..77167bd2 100644 --- a/src/corelib/x11/fpgfx_package.lpk +++ b/src/corelib/x11/fpgfx_package.lpk @@ -24,7 +24,7 @@ <License Value="Modified LGPL "/> <Version Minor="5"/> - <Files Count="10"> + <Files Count="11"> <Item1> <Filename Value="x11_xft.pas"/> <UnitName Value="x11_xft"/> @@ -65,6 +65,10 @@ <Filename Value="../gfx_extinterpolation.pas"/> <UnitName Value="gfx_extinterpolation"/> </Item10> + <Item11> + <Filename Value="../gfx_cmdlineparams.pas"/> + <UnitName Value="gfx_cmdlineparams"/> + </Item11> </Files> <RequiredPkgs Count="1"> <Item1> diff --git a/src/corelib/x11/fpgfx_package.pas b/src/corelib/x11/fpgfx_package.pas index 0fc83352..7fa2a8c3 100644 --- a/src/corelib/x11/fpgfx_package.pas +++ b/src/corelib/x11/fpgfx_package.pas @@ -8,7 +8,7 @@ interface uses x11_xft, x11_keyconv, gfxbase, gfx_x11, fpgfx, gfx_stdimages, gfx_imgfmt_bmp, - gfx_widget, gfx_UTF8utils, gfx_extinterpolation; + gfx_widget, gfx_UTF8utils, gfx_extinterpolation, gfx_cmdlineparams; implementation diff --git a/src/corelib/x11/gfx_x11.pas b/src/corelib/x11/gfx_x11.pas index 1935ff57..35564db6 100644 --- a/src/corelib/x11/gfx_x11.pas +++ b/src/corelib/x11/gfx_x11.pas @@ -621,10 +621,9 @@ begin repeat if (atimeoutms >= 0) and (XPending(display) <= 0) then begin - // waiting some event for the given timeout - - // this Select handles only the first 256 file descriptors - // poll would be better but FPC has no official poll interface (if I'm right) + // Some event is waiting for the given timeout. + // This Select handles only the first 256 file descriptors. + // Poll would be better but FPC has no official poll interface (if I'm right) fpFD_ZERO(rfds); fpFD_SET(xfd, rfds); r := fpSelect(xfd + 1, @rfds, nil, nil, atimeoutms); |