(* 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 . *) 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.