279 lines
7.8 KiB
ObjectPascal
279 lines
7.8 KiB
ObjectPascal
{
|
|
********************************************************************************
|
|
|
|
YaPeTaVi - Yet another Periodic Table Viewer
|
|
Copyright (C) 2018 Geoffray Levasseur <geoffray.levasseurbrandin@numericable.fr>.
|
|
|
|
All rights reserved.
|
|
http://www.geoffray-levasseur.org/
|
|
|
|
This program is free software; you can redistribute it and/or modify it under
|
|
the terms of the GNU General Public License as published by the Free Software
|
|
Foundation; either version 3 of the License, or (at your option) any later
|
|
version.
|
|
|
|
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. See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along with
|
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
|
Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
********************************************************************************
|
|
|
|
Description:
|
|
Common specific YaPeTaVi code
|
|
|
|
}
|
|
unit uCommon;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, Graphics, ComCtrls;
|
|
|
|
const
|
|
ElemNumber = 112;
|
|
|
|
type
|
|
TRange = array[1..ElemNumber] of Boolean;
|
|
|
|
//Get a color from the given value according min and max levels
|
|
function GetGradientColor(const Min, Max, Value: integer;
|
|
const MinCol, MaxCol: TColor): TColor;
|
|
function GetGradientColor(const Min, Max, Value: Double;
|
|
const MinCol, MaxCol: TColor): TColor;
|
|
|
|
//Convert ListView index to an element list index
|
|
function GetListIndexFromView(var LV: TListView; const I: integer): integer;
|
|
|
|
//setup a range with the given string
|
|
function SetRange(S: string): Boolean;
|
|
|
|
//setup the range to include all possible values
|
|
procedure FullRange;
|
|
|
|
//look for picture in different possible place and with different possible format
|
|
function GetPicRessource(Name: string): string;
|
|
|
|
implementation
|
|
|
|
uses
|
|
uDebug, uConst, uUtils;
|
|
|
|
function GetGradientColor(const Min, Max, Value: integer;
|
|
const MinCol, MaxCol: TColor): TColor;
|
|
var
|
|
MinR, MinG, MinB, MaxR, MaxG, MaxB: byte;
|
|
begin
|
|
MinR := Red(ColorToRGB(MinCol));
|
|
MinG := Green(ColorToRGB(MinCol));
|
|
MinB := Blue(ColorToRGB(MinCol));
|
|
MaxR := Red(ColorToRGB(MaxCol));
|
|
MaxG := Green(ColorToRGB(MaxCol));
|
|
MaxB := Blue(ColorToRGB(MaxCol));
|
|
Result := RGBToColor(
|
|
Round((MaxR - MinR) * ((Value - Min) / (Max - Min)) + MinR),
|
|
Round((MaxG - MinG) * ((Value - Min) / (Max - Min)) + MinG),
|
|
Round((MaxB - MinB) * ((Value - Min) / (Max - Min)) + MinB));
|
|
end;
|
|
|
|
function GetGradientColor(const Min, Max, Value: Double;
|
|
const MinCol, MaxCol: TColor): TColor;
|
|
var
|
|
MinR, MinG, MinB, MaxR, MaxG, MaxB: byte;
|
|
begin
|
|
MinR := Red(ColorToRGB(MinCol));
|
|
MinG := Green(ColorToRGB(MinCol));
|
|
MinB := Blue(ColorToRGB(MinCol));
|
|
MaxR := Red(ColorToRGB(MaxCol));
|
|
MaxG := Green(ColorToRGB(MaxCol));
|
|
MaxB := Blue(ColorToRGB(MaxCol));
|
|
Result := RGBToColor(
|
|
Round((MaxR - MinR) * ((Value - Min) / (Max - Min))) + MinR,
|
|
Round((MaxG - MinG) * ((Value - Min) / (Max - Min))) + MinG,
|
|
Round((MaxB - MinB) * ((Value - Min) / (Max - Min))) + MinB);
|
|
end;
|
|
|
|
function SetRange(S: string): Boolean;
|
|
{$warning Add a Range as var parameter, then change all the calls}
|
|
{$warning Improve in order to use the error system}
|
|
var
|
|
TmpRange: TRange;
|
|
|
|
procedure InitRange(var R: TRange);
|
|
var
|
|
I: integer;
|
|
begin
|
|
for I := 1 to ElemNumber do
|
|
R[I] := False;
|
|
end;
|
|
|
|
function ApplyRange(S: string): Boolean;
|
|
var
|
|
I: integer;
|
|
J: integer;
|
|
N1, N2: integer;
|
|
Tmp1, Tmp2: string;
|
|
begin
|
|
PrintLnDbg('-- Applying new range: "' + S + '"...', vlLow);
|
|
Inc(DebugLevel);
|
|
Tmp1 := '';
|
|
Tmp2 := '';
|
|
I := 1;
|
|
while S[I] <> ';' do //find the first number
|
|
begin
|
|
while S[I] in ['0'..'9'] do
|
|
begin
|
|
Tmp1 := Tmp1 + S[I];
|
|
Inc(I);
|
|
end {while};
|
|
if Length(Tmp1) < 1 then
|
|
begin
|
|
Result := False; //syntax error
|
|
PrintLnDbg('*** uUtils.ApplyRange: ERROR: Range error at pos #' +
|
|
IntToStr(I), vlLow);
|
|
Exit;
|
|
end {if};
|
|
while S[I] = ' ' do Inc(I); //eliminate space
|
|
if S[I] = ';' then //single number
|
|
begin
|
|
TmpRange[StrToInt(Tmp1)] := True;
|
|
if I < Length(S) then
|
|
Result := ApplyRange(Copy(S, I + 1, Length(S) - I));
|
|
end else
|
|
if S[I] = '-' then // full range
|
|
begin
|
|
Inc(I);
|
|
while S[I] in ['0'..'9'] do //find second number
|
|
begin
|
|
Tmp2 := Tmp2 + S[I];
|
|
Inc(I);
|
|
end {while};
|
|
if Length(Tmp2) < 1 then
|
|
begin
|
|
Result := False; //syntax error
|
|
PrintLnDbg('*** uUtils.ApplyRange: ERROR: Range error at pos #' +
|
|
IntToStr(I), vlLow);
|
|
Exit;
|
|
end {if};
|
|
if StrToInt(Tmp1) >= StrToInt(Tmp2) then
|
|
for J := StrToInt(Tmp2) to StrToInt(Tmp1) do
|
|
TmpRange[J] := True
|
|
else for J := StrToInt(Tmp1) to StrToInt(Tmp2) do
|
|
TmpRange[J] := True;
|
|
if I < Length(S) then
|
|
Result := ApplyRange(Copy(S, I + 1, Length(S) - I));
|
|
if S[I] <> ';' then
|
|
begin
|
|
Result := False; //syntax error
|
|
PrintLnDbg(' *** uUtils.ApplyRange: ERROR: Range error at pos #' +
|
|
IntToStr(I), vlLow);
|
|
Exit;
|
|
end {if};
|
|
end else
|
|
begin
|
|
Result := False; //syntax error
|
|
PrintLnDbg('*** uUtils.ApplyRange: ERROR: Range error at pos #' +
|
|
IntToStr(I), vlLow);
|
|
Exit;
|
|
end {if};
|
|
end;
|
|
Dec(DebugLevel);
|
|
PrintLnDbg('-- Ok', vlLow);
|
|
end;
|
|
|
|
begin
|
|
InitRange(TmpRange);
|
|
S := Trim(S);
|
|
if Length(S) = 0 then
|
|
S := '1-' + IntToStr(ElemNumber) + ';';
|
|
if S[Length(S)] <> ';' then
|
|
S := S + ';';
|
|
Result := ApplyRange(S);
|
|
if Result then
|
|
begin
|
|
InitRange(RangeArray);
|
|
RangeArray := TmpRange;
|
|
end;
|
|
end;
|
|
|
|
procedure FullRange;
|
|
var
|
|
I: integer;
|
|
begin
|
|
for I := 1 to ElemNumber do
|
|
RangeArray[I] := True;
|
|
end;
|
|
|
|
function GetListIndexFromView(var LV: TListView; const I: integer): integer;
|
|
var
|
|
N: integer;
|
|
begin
|
|
// Writeln('Get list index from view... I = ', I, ' for ',
|
|
// LV.Items[I].SubItems[0]);
|
|
for N := 1 to ElemNumber do
|
|
if (ElementsList.Elements[N].ShortName = LV.Items[I].SubItems[0]) then
|
|
begin
|
|
Result := N;
|
|
Exit;
|
|
end;
|
|
end;
|
|
|
|
//return the full path of a picture ressource:
|
|
//- check it in users path (for personnal datas), then application prefix,
|
|
// then (on unix-like) on FHS
|
|
//- check for .jpg, .jpeg, .png, .gif
|
|
//CAREFULL: on unix like this is case sensitive
|
|
function GetPicRessource(Name: string): string;
|
|
var
|
|
Err, APos: integer;
|
|
S: string;
|
|
|
|
function TestExt(Path, Name: string): string;
|
|
begin
|
|
if Path[Length(Path)] <> DirectorySeparator then
|
|
Path := Path + DirectorySeparator;
|
|
if not FileExists(Path + Name + '.jpg') then
|
|
if not FileExists(Path+ Name + '.jpeg') then
|
|
if not FileExists(Path + Name + '.png') then
|
|
if not FileExists(Path + Name + '.gif') then
|
|
Result := ''
|
|
else Result := Path + Name + '.gif'
|
|
else Result := Path + Name + '.png'
|
|
else Result := Path + Name + '.jpeg'
|
|
else Result := Path + Name + '.jpg';
|
|
PrintLnDbg('Path ' + Path + ' checked for pictures with result: ' + Result,
|
|
vlHigh);
|
|
end;
|
|
|
|
begin
|
|
S := TestExt(sPicPath, Name);
|
|
if S = '' then
|
|
begin
|
|
S := TestExt(GetProgramPrefix + '../pics', Name);
|
|
if S = '' then
|
|
{$ifdef UNIX}
|
|
begin
|
|
S := TestExt('/usr/share/yapetavi/pics/', Name);
|
|
if S = '' then
|
|
begin
|
|
S := TestExt('/usr/local/share/yapetavi/pics/', Name);
|
|
if S = '' then
|
|
{$endif}
|
|
PrintLnDbg('E Can''t find picture for "' + Name + '"!', vlLow);
|
|
{$ifdef UNIX}
|
|
end;
|
|
end;
|
|
{$endif}
|
|
end;
|
|
if S <> '' then
|
|
FormatFileName(S, Result);
|
|
end;
|
|
|
|
end.
|
|
|