kolibrios-gitea/programs/other/fb2reader/SRC/Settings.ob07
Anton Krotov c56f682434 FB2 Reader: refactoring, reduced memory usage for images, small improvements
git-svn-id: svn://kolibrios.org@9898 a494cfbc-eb01-0410-851d-a64ba20cac60
2023-02-01 13:36:55 +00:00

429 lines
13 KiB
Plaintext

(*
Copyright 2016, 2018, 2020-2023 Anton Krotov
This file is part of fb2read.
fb2read 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.
fb2read 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 fb2read. If not, see <http://www.gnu.org/licenses/>.
*)
MODULE Settings;
IMPORT SU := SysUtils, W := Window, C := ColorDlg, DOM, S := Strings, K := KOSAPI, File,
Font, KF := kfonts, OD := OpenDlg, LibImg, G := Graph, Ini, box_lib, sys := SYSTEM;
CONST
DAY = 19;
NIGHT = 20;
APPLY = 21;
CANCEL = 22;
BACK_PICTURE = 23;
C100 = 100;
CHANGE_BACK_COLOR = DOM.BACK_COLOR + C100;
CHANGE_TEXT_COLOR = DOM.TEXT_COLOR + C100;
CHANGE_ITALIC_COLOR = DOM.ITALIC_COLOR + C100;
CHANGE_LINK_COLOR = DOM.LINK_COLOR + C100;
CHANGE_VISITED_COLOR = DOM.VISITED_COLOR + C100;
MAX_LRpc = 25;
MAX_Top = 120;
MAX_PARAGRAPH = 120;
MAX_EPIGRAPH = 120;
MAX_CInt = 25;
MAX_InterLin = 50;
MAX_FONT_SIZE = 40;
MIN_FONT_SIZE = 10;
BtnH* = 25;
BoxW = 50;
TextLeft = 20;
BtnW* = 80;
VAR
Window : W.tWindow;
PID : INTEGER;
Slot : INTEGER;
Color : C.Dialog;
Data : DOM.TSettings;
String : S.STRING;
sb : ARRAY 7 OF box_lib.scrollbar;
check1 : box_lib.checkbox;
check2 : box_lib.checkbox;
OpenPict : OD.Dialog;
picture : INTEGER;
picture_fsize : INTEGER;
picture_path : S.STRING;
PROCEDURE Close*;
VAR pid: INTEGER;
BEGIN
IF PID # 0 THEN
pid := PID;
PID := 0;
IF (picture # Data.Picture) & (picture # 0) THEN
picture := K.free(picture);
picture_fsize := 0
END;
C.Destroy(Color);
OD.Destroy(OpenPict);
SU.TerminateThreadId(pid)
END
END Close;
PROCEDURE ClearWindow;
BEGIN
SU.Box(0, 0, Window.width - 10, Window.height - SU.SkinHeight() - 5, SU.winColor, SU.winColor)
END ClearWindow;
PROCEDURE OutText (x, y: INTEGER; text: ARRAY OF CHAR);
BEGIN
SU.OutText(x, y, text, LENGTH(text), SU.textColor)
END OutText;
PROCEDURE PlusMinus(x, y, max, min: INTEGER; _sb: box_lib.scrollbar);
VAR range, Y: INTEGER;
sysfont: ARRAY 20 OF CHAR;
BEGIN
sysfont := "System font only";
S.IntToString(_sb.position + min, String);
IF _sb = sb[0] THEN
Y := y - (BtnH + 10) * 2 + 26;
SU.Box(TextLeft + 230, Y, SU.FontW * LENGTH(sysfont), SU.FontH, SU.winColor, SU.winColor);
IF ~KF.Enabled(Font.KFont, _sb.position + min) THEN
OutText(TextLeft + 230, Y, sysfont)
END
END;
SU.Box(x + 25, y + 6, SU.FontW * 4, SU.FontH, SU.winColor, SU.winColor);
OutText(x + 25 + (35 - SU.FontW * LENGTH(String)) DIV 2, y + 6, String);
x := x + 60 - 25;
range := max - min;
_sb := box_lib.kolibri_scrollbar(_sb, (x + 30) * 65536 + 196, y * 65536 + 22 + 2, 22, range + range DIV 10, range DIV 10,
_sb.position, SU.lightColor, SU.btnColor, 0, 2)
END PlusMinus;
PROCEDURE Buttons;
VAR
X, Y, TextY : INTEGER;
WinW, WinH, SkinH : INTEGER;
i : INTEGER;
Rect : W.tRect;
BEGIN
Rect.left := 10;
Rect.top := 85;
Rect.width := 210;
Rect.height := 255;
SU.Box(Rect.left, Rect.top, Rect.width, Rect.height, SU.winColor, SU.borderColor);
SU.Box(Rect.left + 230, Rect.top, Rect.width + 170, Rect.height, SU.winColor, SU.borderColor);
WinW := Window.width;
WinH := Window.height;
SkinH := SU.SkinHeight();
X := 125;
Y := 10;
IF picture = 0 THEN
OutText(TextLeft + 20, Y + 6, "back picture (none)")
ELSE
OutText(TextLeft + 20, Y + 6, "back picture")
END;
SU.CreateButton(BACK_PICTURE, X + 75, Y, 30, BtnH, SU.btnColor, "...");
Y := 10 + (BtnH + 10);
OutText(TextLeft + 20, Y + 6, "two columns");
Y := Y + (BtnH + 10) * 2 - 20;
TextY := Y;
FOR i := 0 TO 4 DO
SU.Box(X, Y, BoxW, BtnH, Data.Colors[i], 0);
SU.CreateButton(i + C100, X + BoxW + 5, Y, 30, BtnH, SU.btnColor, "...");
Y := Y + BtnH + 10;
END;
X := 20; Y := TextY + 6;
OutText(TextLeft, Y, "back"); OutText(TextLeft + 230, Y, "font size"); PlusMinus(TextLeft + 330, Y - 6, MAX_FONT_SIZE, MIN_FONT_SIZE, sb[0]); Y := Y + BtnH + 10;
OutText(TextLeft, Y, "text"); OutText(TextLeft + 230, Y, "left & right %"); PlusMinus(TextLeft + 330, Y - 6, MAX_LRpc, 0, sb[1]); Y := Y + BtnH + 10;
OutText(TextLeft, Y, "italic"); OutText(TextLeft + 230, Y, "col. spacing %"); PlusMinus(TextLeft + 330, Y - 6, MAX_CInt, 0, sb[2]); Y := Y + BtnH + 10;
OutText(TextLeft, Y, "link"); OutText(TextLeft + 230, Y, "top & bottom"); PlusMinus(TextLeft + 330, Y - 6, MAX_Top, 0, sb[3]); Y := Y + BtnH + 10;
OutText(TextLeft, Y, "visited"); OutText(TextLeft + 230, Y, "paragraph"); PlusMinus(TextLeft + 330, Y - 6, MAX_PARAGRAPH, 0, sb[4]); Y := Y + BtnH + 10;
OutText(TextLeft + 230, Y, "epigraph"); PlusMinus(TextLeft + 330, Y - 6, MAX_EPIGRAPH, 0, sb[5]); Y := Y + BtnH + 10;
OutText(TextLeft + 230, Y, "line spacing"); PlusMinus(TextLeft + 330, Y - 6, MAX_InterLin, 0, sb[6]);
Y := Y - 6;
SU.CreateButton(DAY, (Rect.width - (BtnW + 5 + BtnW)) DIV 2 + Rect.left, Y, 80, BtnH, SU.btnColor, "Day" );
SU.CreateButton(NIGHT, (Rect.width - (BtnW + 5 + BtnW)) DIV 2 + Rect.left + 5 + BtnW, Y, 80, BtnH, SU.btnColor, "Night" );
SU.CreateButton(APPLY, (WinW - (BtnW + 5 + BtnW) - 10) DIV 2, WinH - BtnH - SkinH - 10, 80, BtnH, SU.btnColor, "Apply" );
SU.CreateButton(CANCEL, (WinW - (BtnW + 5 + BtnW) - 10) DIV 2 + 5 + BtnW, WinH - BtnH - SkinH - 10, 80, BtnH, SU.btnColor, "Cancel");
FOR i := 0 TO LEN(sb) - 1 DO
box_lib.scrollbar_h_draw(sb[i])
END;
box_lib.check_box_draw2(check1);
box_lib.check_box_draw2(check2);
END Buttons;
PROCEDURE DrawWindow;
BEGIN
SU.GetSystemColors;
SU.WindowRedrawStatus(1);
SU.DefineAndDrawWindow(Window.left, Window.top, Window.width, Window.height,
SU.winColor, LSL(ORD({0, 1}), 4) + 4, Window.caption);
Buttons;
SU.WindowRedrawStatus(2)
END DrawWindow;
PROCEDURE SelColor(Color: C.Dialog; Default: INTEGER): INTEGER;
VAR Result: INTEGER;
BEGIN
Result := Default;
IF Color # NIL THEN
C.Show(Color);
WHILE Color.status = 2 DO
SU.Pause(20)
END;
IF Color.status = 1 THEN
Result := Color.color
END
END
RETURN Result
END SelColor;
PROCEDURE ChangeColor(idx: INTEGER);
BEGIN
Data.Colors[idx] := SelColor(Color, Data.Colors[idx])
END ChangeColor;
PROCEDURE Day;
BEGIN
Data.Colors[DOM.BACK_COLOR] := 0F0F0C7H;
Data.Colors[DOM.TEXT_COLOR] := 0000000H;
Data.Colors[DOM.ITALIC_COLOR] := 0505050H;
Data.Colors[DOM.LINK_COLOR] := 00000FFH;
Data.Colors[DOM.VISITED_COLOR] := 0800080H;
Data.Colors[DOM.CLICKED_COLOR] := 0FF0000H;
END Day;
PROCEDURE Night;
BEGIN
Data.Colors[DOM.BACK_COLOR] := 0000000H;
Data.Colors[DOM.TEXT_COLOR] := 0AFAFAFH;
Data.Colors[DOM.ITALIC_COLOR] := 07F7F7FH;
Data.Colors[DOM.LINK_COLOR] := 000A0D0H;
Data.Colors[DOM.VISITED_COLOR] := 0C000C0H;
Data.Colors[DOM.CLICKED_COLOR] := 0FF0000H;
END Night;
PROCEDURE Apply;
BEGIN
Data.FontSize := sb[0].position + MIN_FONT_SIZE;
Data.PADDING.LRpc := sb[1].position;
Data.PADDING.CInt := sb[2].position;
Data.PADDING.Top := sb[3].position;
Data.PARAGRAPH := sb[4].position;
Data.EPIGRAPH := sb[5].position;
Data.InterLin := sb[6].position;
IF (picture # 0) & (picture # Data.Picture) THEN
IF Data.Picture # 0 THEN
Data.Picture := K.free(Data.Picture)
END;
Data.Picture := picture;
Data.picture_fsize := picture_fsize;
Ini.SetPicturePath(picture_path)
END;
picture := 0;
picture_fsize := 0;
DOM.SetSettings(Data);
Close
END Apply;
PROCEDURE LoadPicture(file_path: S.STRING);
VAR fsize, img: INTEGER;
BEGIN
img := File.Load(file_path, fsize);
IF img # 0 THEN
IF (picture # 0) & (picture # Data.Picture) THEN
picture := K.free(picture)
END;
picture := img;
picture_fsize := fsize;
picture_path := file_path
END
END LoadPicture;
PROCEDURE OpenPicture;
BEGIN
IF OpenPict # NIL THEN
OD.Show(OpenPict, 500, 400);
WHILE OpenPict.status = 2 DO
SU.Pause(30)
END;
IF OpenPict.status = 1 THEN
COPY(OpenPict.FilePath, picture_path);
LoadPicture(picture_path)
END
END
END OpenPicture;
PROCEDURE ButtonClick;
BEGIN
CASE SU.GetButtonCode() OF
|0 :
|1 : Close
|BACK_PICTURE : OpenPicture
|DAY : Day
|NIGHT : Night
|APPLY : Apply
|CANCEL : Close
|CHANGE_BACK_COLOR : ChangeColor(DOM.BACK_COLOR)
|CHANGE_TEXT_COLOR : ChangeColor(DOM.TEXT_COLOR)
|CHANGE_ITALIC_COLOR : ChangeColor(DOM.ITALIC_COLOR)
|CHANGE_LINK_COLOR : ChangeColor(DOM.LINK_COLOR)
|CHANGE_VISITED_COLOR : ChangeColor(DOM.VISITED_COLOR)
END;
ClearWindow;
Buttons
END ButtonClick;
PROCEDURE Default*;
BEGIN
Day;
Data.FontSize := 16;
Data.TwoCol := FALSE;
Data.PADDING.Top := 15;
Data.PADDING.LRpc := 3;
Data.PADDING.CInt := 6;
Data.PARAGRAPH := 30;
Data.EPIGRAPH := 100;
Data.InterLin := 0;
Data.Picture := picture;
Data.picture_fsize := picture_fsize;
DOM.SetSettings(Data)
END Default;
PROCEDURE Show;
VAR i, scrWidth, scrHeight: INTEGER;
BEGIN
SU.SetEventsMask({0, 2, 5, 30, 31});
W.init(Window, 0, 0, 640, 420, "Settings");
SU.GetScreenSize(scrWidth, scrHeight);
Window.left := (scrWidth - Window.width) DIV 2;
Window.top := (scrHeight - Window.height) DIV 2;
Color := C.Create(DrawWindow);
OpenPict := OD.Create(DrawWindow, 0, "/sys", "JPG|PNG|BMP|GIF");
Data := DOM.Settings;
picture := Data.Picture;
picture_fsize := Data.picture_fsize;
DrawWindow;
WHILE TRUE DO
CASE SU.WaitForEvent() OF
|1 : DrawWindow
|3 : ButtonClick
|6 : FOR i := 0 TO LEN(sb) - 1 DO
box_lib.scrollbar_h_mouse(sb[i])
END;
box_lib.check_box_mouse2(check1);
box_lib.check_box_mouse2(check2);
PlusMinus(TextLeft + 330, sb[0].y_h DIV 65536, MAX_FONT_SIZE, MIN_FONT_SIZE, sb[0]);
PlusMinus(TextLeft + 330, sb[1].y_h DIV 65536, MAX_LRpc, 0, sb[1]);
PlusMinus(TextLeft + 330, sb[2].y_h DIV 65536, MAX_CInt, 0, sb[2]);
PlusMinus(TextLeft + 330, sb[3].y_h DIV 65536, MAX_Top, 0, sb[3]);
PlusMinus(TextLeft + 330, sb[4].y_h DIV 65536, MAX_PARAGRAPH, 0, sb[4]);
PlusMinus(TextLeft + 330, sb[5].y_h DIV 65536, MAX_EPIGRAPH, 0, sb[5]);
PlusMinus(TextLeft + 330, sb[6].y_h DIV 65536, MAX_InterLin, 0, sb[6]);
Data.TwoCol := box_lib.check_box_get_value(check1);
Data.b_pict := box_lib.check_box_get_value(check2);
END
END
END Show;
PROCEDURE Open*;
BEGIN
IF PID = 0 THEN
Data := DOM.Settings;
box_lib.check_box_set_value(check1, Data.TwoCol);
box_lib.check_box_set_value(check2, Data.b_pict);
PID := SU.NewThread(Show, DOM.Stack);
Slot := SU.GetThreadSlot(PID);
sb[0].position := Data.FontSize - MIN_FONT_SIZE;
sb[1].position := Data.PADDING.LRpc;
sb[2].position := Data.PADDING.CInt;
sb[3].position := Data.PADDING.Top;
sb[4].position := Data.PARAGRAPH;
sb[5].position := Data.EPIGRAPH;
sb[6].position := Data.InterLin;
ELSE
SU.FocusWindow(Slot)
END
END Open;
PROCEDURE main;
VAR i: INTEGER;
bpicture, twocol: ARRAY 20 OF CHAR;
BEGIN
PID := 0;
FOR i := 0 TO LEN(sb) - 1 DO
sb[i] := box_lib.kolibri_new_scrollbar(10 * 65536 + 200, 10 * 65536 + 22 + 2, 22, 15, 10, 0, 0, 0, 0, 2)
END;
bpicture := "back picture";
twocol := "two columns";
check2 := box_lib.kolibri_new_check_box(TextLeft, 10 + 5, 16, 16, sys.SADR(""), LENGTH(bpicture) * 8 + 5);
check1 := box_lib.kolibri_new_check_box(TextLeft, 10 + (BtnH + 10) + 5, 16, 16, sys.SADR(""), LENGTH(twocol) * 8 + 5);
picture := 0;
picture_fsize := 0;
IF Ini.Picture # "" THEN
LoadPicture(Ini.Picture)
END
END main;
BEGIN
main
END Settings.