diff --git a/.gitignore b/.gitignore index 0dcd404..df100be 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ backup Deploy +SnapTimer *.o *.or *.ppu diff --git a/controllers/maincontroller.pas b/controllers/maincontroller.pas new file mode 100644 index 0000000..3264f30 --- /dev/null +++ b/controllers/maincontroller.pas @@ -0,0 +1,271 @@ +unit MainController; + +{$mode objfpc} + +interface + +uses + Classes, SysUtils, MyTimer; + +type + TMainController = class + private + FCompactMode : Boolean; + FTimer : TMyTimer; + procedure SetCompactMode(Value: Boolean); + + procedure OnTick(Sender: TObject); + procedure OnTimerStateChanged(Sender: TObject); + procedure UpdateTime; + procedure UpdateButtonsAndMenus; + public + constructor Create; + + // Called from MainForm and CompactModeForm + procedure ToggleCountdown(Sender: TObject); + procedure ResetCountdown(Sender: TObject); + + procedure PlayTicking; + procedure ShowTrayMessage(Msg: string); + procedure ShowDoneMessage(Msg: string); + + property CompactMode : Boolean read FCompactMode; + property Timer : TMyTimer read FTimer; + end; + + +function GetMainController : TMainController; + +implementation + +uses Forms, MainForm1, CompactMode, Utils, Config, MsgBox, Consts; + +var + MainControllerInstance : TMainController; + +procedure TMainController.SetCompactMode(Value: Boolean); +var Pos : TPoint; +begin + if (Value = FCompactMode) or (GetConfig.CompactMode.Enabled = False) then + Exit; + + if Value = True then + begin + // Note: Width and ClientWidth are the same + CompactModeForm.Width:= MainForm.Count.Width; + CompactModeForm.Height:= MainForm.Count.Height; + Pos:= TUtils.GetControlPos(MainForm.Count); + CompactModeForm.Top:= Pos.Y; + CompactModeForm.Left:= Pos.X; + CompactModeForm.Count.Caption:= MainForm.Count.Caption; + CompactModeForm.Count.Font:= MainForm.Count.Font; + CompactModeForm.Count.Color:= MainForm.Count.Color; + CompactModeForm.SetTransparency(GetConfig.CompactMode); + CompactModeForm.Visible:= True; + MainForm.Visible:= False; + end + else + begin + MainForm.Count.Caption:= CompactModeForm.Count.Caption; + CompactModeForm.Visible:= False; + MainForm.Visible:= True; + end; + + FCompactMode:= Value; +end; + +procedure TMainController.OnTick(Sender: TObject); +begin + UpdateTime; +end; + +procedure TMainController.OnTimerStateChanged(Sender: TObject); +var Config: TConfig; +begin + Config:= GetConfig; + + case Timer.State of + Ready: + begin + SetCompactMode(False); + if Config.SecondsMode then + Timer.Seconds := MainForm.TimeEdit.Value + else + Timer.Minutes:= MainForm.TimeEdit.Value; + UpdateTime(); + UpdateButtonsAndMenus; + MainForm.TrayIconMain.Icon:= MainForm.ImgIconMain.Picture.Icon; + end; + + Running: + begin + UpdateButtonsAndMenus; + MainForm.TrayIconMain.Icon:= MainForm.ImgIconRunning.Picture.Icon; + if Config.TickingOn then + PlayTicking(); + + SetCompactMode(True); + end; + + Paused: + begin + SetCompactMode(False); + UpdateButtonsAndMenus; + MainForm.TrayIconMain.Icon:= MainForm.ImgIconPaused.Picture.Icon; + TUtils.StopAudio; + end; + + Finished: + begin + SetCompactMode(False); + UpdateTime(); + UpdateButtonsAndMenus; + TUtils.StopAudio; + + Application.Title := APP_NAME; + if Config.DoneAudioEnabled then + TUtils.PlayAudio(Config.DoneAudio, Config.LoopAudio); + if Config.DoneAppEnabled then + TUtils.RunApp(Config.DoneApp); + if Config.DoneTrayMsgEnabled then + ShowTrayMessage(Config.DoneTrayMsg); + if Config.DoneMessageEnabled then + ShowDoneMessage(Config.DoneMessage); + if Config.AutoRestart then + ToggleCountdown(Sender) + else + MainForm.TrayIconMain.Icon := MainForm.ImgIconDone.Picture.Icon; + + MainForm.ShowForm; + end; + end; +end; + +// TODO Animate icon between alarm icon and main so it blinks every second +// Instead of playing icon, animate the clock hands so they go around? +// http://delphi.about.com/od/kbwinshell/l/aa122501a.htm +procedure TMainController.UpdateTime(); +var + Time : String; +begin + Time:= TUtils.SecondsToTime(Timer.Seconds, GetConfig.HideSeconds); + + if CompactMode then + begin + CompactModeForm.Count.Visible := False; + CompactModeForm.Count.Caption := Time; + CompactModeForm.Count.Visible := True; + end + else + begin + // Changing caption while it's not visible keeps time from flashing + MainForm.Count.Visible := False; + MainForm.Count.Caption := Time; + MainForm.Count.Visible := True; + end; + + MainForm.MenuCount.Caption := Time; + if Timer.State = TState.Running then + begin + Application.Title := Time + ' - ' + APP_NAME; + MainForm.TrayIconMain.Hint := Time; + end + else + begin + Application.Title := APP_NAME; + MainForm.TrayIconMain.Hint := APP_NAME; + end; +end; + +procedure TMainController.UpdateButtonsAndMenus; +begin + // When it comes to buttons and menus, there are only two states. + with MainForm do + begin + if Timer.State = TState.Running then + begin + ImgPause.Visible := True; + ImgStart.Visible := False; + MenuToggle.Caption := BTN_PAUSE; + TrayMenuToggle.Caption := BTN_PAUSE; + end + else + begin + ImgPause.Visible := False; + ImgStart.Visible := True; + MenuToggle.Caption := BTN_START; + TrayMenuToggle.Caption := BTN_START; + end; + end; +end; + + + + + +constructor TMainController.Create; +begin + FCompactMode:= False; + FTimer:= TMyTimer.Create; + FTimer.OnSecondElapsed:= @OnTick; + FTimer.OnStateChanged:= @OnTimerStateChanged; +end; + +procedure TMainController.ToggleCountdown(Sender: TObject); +begin + if ((Sender = MainForm.Count) or (Sender = CompactModeForm.Count)) and (GetConfig.ClickTime = False) then + Exit; + + // We want to go from `Finished` state directly to `Running` state. (or not?) + if Timer.State = TState.Finished then + Timer.Reset; + + Timer.Toggle; +end; + +procedure TMainController.ResetCountdown(Sender: TObject); +begin + if ((Sender = MainForm.Count) or (Sender = CompactModeForm.Count)) and (GetConfig.DblClickTime = False) then + Exit; + + Timer.Reset; +end; + +procedure TMainController.PlayTicking(); +begin + TUtils.PlayAudio('.\sounds\ticking\ticking.wav', True); +end; + +procedure TMainController.ShowTrayMessage(Msg: string); +begin + with MainForm.TrayIconMain do + begin + BalloonHint := Msg; + ShowBalloonHint; + BalloonTimeout := 4000; + end; +end; + +procedure TMainController.ShowDoneMessage(Msg: string); +begin + // http://msdn.microsoft.com/en-us/library/ms645505(VS.85).aspx + //Windows.MessageBox(self.Handle, pChar(msg), 'Done', + // MB_SYSTEMMODAL or MB_SETFOREGROUND or MB_TOPMOST or MB_ICONINFORMATION); + MsgboxForm := TMsgBoxForm.Create(MainForm); + MsgBoxForm.SetText(Msg); + MsgboxForm.ShowModal; + MsgboxForm.Release; + TUtils.StopAudio; +end; + + +function GetMainController : TMainController; +begin + Result:= MainControllerInstance; +end; + +initialization + MainControllerInstance:= TMainController.Create; + +end. + diff --git a/mainform1.pas b/mainform1.pas deleted file mode 100644 index 7fcd141..0000000 --- a/mainform1.pas +++ /dev/null @@ -1,961 +0,0 @@ -unit MainForm1; - -{$mode objfpc}{$H+} - -interface - -uses - Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, - Menus, StdCtrls, Spin, ExtCtrls, About, LCLType, IniFiles, Settings, MMSystem, - Windows, StrUtils, DateUtils; - -type - TMode = (Timer, Stopwatch); - TPosition = (Center, Remember, TopLeft, TopRight, BottomLeft, BottomRight); - - { TMainForm } - - TMainForm = class(TForm) - ImgIconMain: TImage; - ImgIconRunning: TImage; - ImgIconPaused: TImage; - ImgIconDone: TImage; - ImgStart: TImage; - ImgPause: TImage; - MainMenu1: TMainMenu; - MenuItem1: TMenuItem; - MenuItem2: TMenuItem; - MenuCompact: TMenuItem; - MenuReset: TMenuItem; - MenuToggle: TMenuItem; - MenuSave: TMenuItem; - PopupMenuCompact: TPopupMenu; - ImgReset: TImage; - TrayMenuOptions: TMenuItem; - TrayMenuShow: TMenuItem; - TrayMenuToggle: TMenuItem; - TrayMenuReset: TMenuItem; - TrayMenuExit: TMenuItem; - MenuCount: TMenuItem; - TrayMenuAbout: TMenuItem; - MenuOptions: TMenuItem; - MenuHelp: TMenuItem; - MenuAbout: TMenuItem; - MenuFile: TMenuItem; - MenuExit: TMenuItem; - MenuEdit: TMenuItem; - TrayMenu: TPopupMenu; - TimeLabel: TLabel; - Minutes: TSpinEdit; - Count: TStaticText; - Timer1: TTimer; - TrayIconMain: TTrayIcon; - procedure FormActivate(Sender: TObject); - procedure ToggleCompact(Sender: TObject); - procedure MinutesChanged(Sender: TObject); - procedure OnDestroyForm(Sender: TObject); - procedure OnShowForm(Sender: TObject); - procedure ShowAbout(Sender: TObject); - procedure CloseApp(Sender: TObject); - procedure OnCreateForm(Sender: TObject); - procedure Countdown(Sender: TObject); - procedure ResetCountdown(Sender: TObject); - procedure DisableTimer(); - procedure EnableTimer(); - procedure SetTimer(); - procedure ShowOptions(Sender: TObject); - procedure ToggleCountdown(Sender: TObject); - procedure FormKeyPress(Sender: TObject; var Key: char); - function SecondsToTime(Seconds: integer): string; - procedure FormWindowStateChange(Sender: TObject); - procedure UpdateTime(); - procedure SaveSettings(Sender: TObject); - class function GetFilePath(Path: string): string; - procedure PlayAudio(Path: string; Loop: boolean); - procedure StopAudio(); - procedure RunApp(Path: string); - procedure ShowDoneMessage(Msg: string); - procedure ShowTrayMessage(Msg: string); - function GetHandle(): HWND; - procedure SetDefaults(Sender: TObject); - function FontStylesToInt(Fnt: TFont): integer; - function IntToFontStyles(Mask: integer): TFontStyles; - procedure SetFieldsVisible(showFields: boolean); - procedure UpdateAlwaysOnTop(onTop: boolean); - procedure PlayTicking(); - function IsInteger(S: String): boolean; - procedure UpdateTimeCaption(newSecondsMode: boolean); - private - { private declarations } - IniFile: TIniFile; - AlwaysOnTop: boolean; - MinToTray: boolean; - AutoStart: boolean; - HideSeconds: boolean; - ClickTime: boolean; - DblClickTime: boolean; - AutoRestart: boolean; - LoopAudio: boolean; - AudioPlaying: boolean; - TickingOn: boolean; - AutoSave: boolean; - DoneMessage: string; - DoneMessageEnabled: boolean; - DoneTrayMsg: string; - DoneTrayMsgEnabled: boolean; - DoneAudio: string; - DoneAudioEnabled: boolean; - DoneApp: string; - DoneAppEnabled: boolean; - WndPosition: TPosition; - WndPositions: TStrings; - WndHeight: integer; - WndWidth: integer; - WndTop: integer; - WndLeft: integer; - WndHandle: HWND; - SecondsMode: boolean; // Undocumented mode to treat minutes as seconds - Mode: TMode; - CompactMode: boolean; - FontSizeChanged : boolean; - //FormerWidth : integer; - //FormerHeight : integer; - EndTime: TDateTime; - StartTime: TDateTime; - CountdownDone: boolean; - public - { public declarations } - end; - -var - MainForm: TMainForm; - AppName: string; - IniFilename: string; - -implementation - -{ TMainForm } - -const - APP_NAME = 'SnapTimer'; - INI_SEC_MAIN = 'Main'; - INI_SEC_ALARMS = 'Alarms'; - INI_SEC_PLACEMENT = 'Placement'; - INI_SEC_FONTS = 'Fonts'; - INI_MINUTES = 'Minutes'; - INI_ALWAYS_ON_TOP = 'AlwaysOnTop'; - INI_MIN_TO_TRAY = 'MinToTray'; - INI_AUTOSTART = 'AutoStart'; - INI_HIDESECONDS = 'HideSeconds'; - INI_CLICKTIME = 'ClickTime'; - INI_DBLCLICKTIME = 'DoubleClickTime'; - INI_AUTORESTART = 'AutoRestart'; - INI_LOOP_AUDIO = 'LoopAudio'; - INI_TICKING_ON = 'TickingEnabled'; - INI_AUTOSAVE = 'AutoSave'; - INI_HEIGHT = 'WinHeight'; - INI_WIDTH = 'WinWidth'; - INI_LEFT = 'WinLeft'; - INI_TOP = 'WinTop'; - INI_POSITION = 'WinPosition'; - INI_DONE_MESSAGE = 'Message'; - INI_DONE_MESSAGE_ON = 'MessageEnabled'; - INI_DONE_TRAY_MESSAGE = 'TrayMessage'; - INI_DONE_TRAY_MESSAGE_ON = 'TrayMessageEnabled'; - INI_DONE_AUDIO = 'AudioFile'; - INI_DONE_AUDIO_ON = 'AudioFileEnabled'; - INI_DONE_APP = 'RunApp'; - INI_DONE_APP_ON = 'RunAppEnabled'; - INI_SECONDS_MODE = 'SecondsMode'; - INI_FONT_NAME = 'Name'; - INI_FONT_CHARSET = 'Charset'; - INI_FONT_COLOR = 'Color'; - INI_FONT_SIZE = 'Size'; - INI_FONT_STYLE = 'Style'; - INI_BG_COLOR = 'BgColor'; - - // Menu items - MENU_FILE = '&File'; - MENU_EXIT = 'E&xit'; - MENU_EDIT = '&Edit'; - MENU_OPTIONS = 'Op&tions'; - MENU_HELP = '&Help'; - MENU_ABOUT = '&About'; - TRAY_MENU_SHOW = 'Show application'; - - // Buttons - BTN_START = '&Start'; - BTN_PAUSE = '&Pause'; - BTN_RESET = '&Reset'; - - // Labels - LBL_MINUTES = '&Minutes:'; - LBL_SECONDS = '&Seconds:'; - - // Default values - DEF_TIME = 15; - DEF_DONE_MSG = 'Time''s up'; - DEF_DONE_MSG_ON = True; - DEF_DONE_TRAY_MSG = 'Countdown completed'; - DEF_DONE_TRAY_MSG_ON = False; - DEF_DONE_AUDIO = '.\sounds\alarm_clock_bell.wav'; - DEF_DONE_AUDIO_ON = False; - DEF_DONE_APP = ''; - DEF_DONE_APP_ON = False; - DEF_ALWAYS_ON_TOP = False; - DEF_MIN_TO_TRAY = False; - DEF_AUTOSTART = False; - DEF_HIDESECONDS = False; - DEF_CLICKTIME = True; - DEF_DBLCLICKTIME = True; - DEF_AUTORESTART = False; - DEF_LOOP_AUDIO = False; - DEF_TICKING_ON = False; - DEF_TICKING_PATH = '.\sounds\ticking\ticking.wav'; - DEF_AUTOSAVE = True; - DEF_SECONDS_MODE = False; - DEF_POSITION = Ord(Center); - DEF_HEIGHT = 149; - DEF_WIDTH = 214; - DEF_FONT_NAME = 'Arial'; - DEF_FONT_CHARSET = 0; - DEF_FONT_COLOR = clNavy; - DEF_FONT_SIZE = 38; - DEF_FONT_STYLE = 0; - DEF_BG_COLOR = clNone; - - // Messages - MSG_OPEN_INI = 'An error occurred opening the .ini file, settings won''t be saved'; - MSG_WRITE_INI = - 'An error occurred trying to write to the .ini file, settings won''t be saved.'; - -procedure TMainForm.OnCreateForm(Sender: TObject); -begin - MenuFile.Caption := MENU_FILE; - MenuToggle.Caption := BTN_START; - MenuReset.Caption := BTN_RESET; - MenuExit.Caption := MENU_EXIT; - MenuEdit.Caption := MENU_EDIT; - MenuOptions.Caption := MENU_OPTIONS; - MenuHelp.Caption := MENU_HELP; - MenuAbout.Caption := MENU_ABOUT; - - TrayMenuShow.Caption := TRAY_MENU_SHOW; - TrayMenuToggle.Caption := BTN_START; - TrayMenuReset.Caption := BTN_RESET; - TrayMenuAbout.Caption := MENU_ABOUT; - TrayMenuExit.Caption := MENU_EXIT; - - // Set all defaults, then load from .ini - Minutes.Value := DEF_TIME; - AlwaysOnTop := DEF_ALWAYS_ON_TOP; - MinToTray := DEF_MIN_TO_TRAY; - AutoStart := DEF_AUTOSTART; - HideSeconds := DEF_HIDESECONDS; - ClickTime := DEF_CLICKTIME; - DblClickTime := DEF_DBLCLICKTIME; - AutoRestart := DEF_AUTORESTART; - LoopAudio := DEF_LOOP_AUDIO; - TickingOn := DEF_TICKING_ON; - AutoSave := DEF_AUTOSAVE; - DoneMessage := DEF_DONE_MSG; - DoneMessageEnabled := DEF_DONE_MSG_ON; - DoneTrayMsg := DEF_DONE_TRAY_MSG; - DoneTrayMsgEnabled := DEF_DONE_TRAY_MSG_ON; - DoneAudio := DEF_DONE_AUDIO; - DoneAudioEnabled := DEF_DONE_AUDIO_ON; - DoneApp := DEF_DONE_APP; - DoneAppEnabled := DEF_DONE_APP_ON; - SecondsMode := DEF_SECONDS_MODE; - WndPosition := TPosition(DEF_POSITION); - - WndPositions := TStringList.Create; - WndPositions.Add('Centered'); - WndPositions.Add('Remember position'); - WndPositions.Add('Top left'); - WndPositions.Add('Top right'); - WndPositions.Add('Bottom left'); - WndPositions.Add('Bottom right'); - - Mode := Timer; - CompactMode := False; - AudioPlaying := False; - Self.DoubleBuffered := True; - Count.DoubleBuffered := True; - Timer1.Interval := 150; - CountdownDone := False; - - AppName := ExtractFileName(Application.ExeName); - IniFilename := ExtractFilePath(Application.ExeName) + ChangeFileExt(AppName, '.ini'); - - // TODO For some reason this isn't working at all - //WriteLn('checking for options: ' + IntToStr(ParamCount)); - //If ParamCount > 1 then begin - // WriteLn('has options'); - //if Application.HasOption('h', 'help') then begin - // WriteLn('SnapTimer usage'); - // WriteLn('[number of minutes] (must be the only parameter)'); - // WriteLn('-h|--help\tShow this usage'); - // WriteLn('-i|--ini=\tPath to .ini file to use'); - //end else if Application.HasOption('i', 'ini') then begin - // //IniFilename := Application.GetOptionValue('i', 'ini'); - // WriteLn('ini option found'); - //end; - //end; - try - IniFile := TIniFile.Create(IniFilename); - Minutes.Value := IniFile.ReadInteger(INI_SEC_MAIN, INI_MINUTES, DEF_TIME); - AlwaysOnTop := IniFile.ReadBool(INI_SEC_MAIN, INI_ALWAYS_ON_TOP, DEF_ALWAYS_ON_TOP); - MinToTray := IniFile.ReadBool(INI_SEC_MAIN, INI_MIN_TO_TRAY, DEF_MIN_TO_TRAY); - AutoStart := IniFile.ReadBool(INI_SEC_MAIN, INI_AUTOSTART, DEF_AUTOSTART); - HideSeconds := IniFile.ReadBool(INI_SEC_MAIN, INI_HIDESECONDS, DEF_HIDESECONDS); - ClickTime := IniFile.ReadBool(INI_SEC_MAIN, INI_CLICKTIME, DEF_CLICKTIME); - DblClickTime := IniFile.ReadBool(INI_SEC_MAIN, INI_DBLCLICKTIME, DEF_DBLCLICKTIME); - AutoRestart := IniFile.ReadBool(INI_SEC_MAIN, INI_AUTORESTART, DEF_AUTORESTART); - LoopAudio := IniFile.ReadBool(INI_SEC_MAIN, INI_LOOP_AUDIO, DEF_LOOP_AUDIO); - TickingOn := IniFile.ReadBool(INI_SEC_MAIN, INI_TICKING_ON, DEF_TICKING_ON); - AutoSave := IniFile.ReadBool(INI_SEC_MAIN, INI_AUTOSAVE, DEF_AUTOSAVE); - SecondsMode := IniFile.ReadBool(INI_SEC_MAIN, INI_SECONDS_MODE, DEF_SECONDS_MODE); - DoneMessage := IniFile.ReadString(INI_SEC_ALARMS, INI_DONE_MESSAGE, DEF_DONE_MSG); - DoneMessageEnabled := IniFile.ReadBool(INI_SEC_ALARMS, INI_DONE_MESSAGE_ON, - DEF_DONE_MSG_ON); - DoneTrayMsg := IniFile.ReadString(INI_SEC_ALARMS, INI_DONE_TRAY_MESSAGE, - DEF_DONE_TRAY_MSG); - DoneTrayMsgEnabled := IniFile.ReadBool(INI_SEC_ALARMS, - INI_DONE_TRAY_MESSAGE_ON, DEF_DONE_TRAY_MSG_ON); - DoneAudio := IniFile.ReadString(INI_SEC_ALARMS, INI_DONE_AUDIO, DEF_DONE_AUDIO); - DoneAudioEnabled := IniFile.ReadBool(INI_SEC_ALARMS, INI_DONE_AUDIO_ON, - DEF_DONE_AUDIO_ON); - DoneApp := IniFile.ReadString(INI_SEC_ALARMS, INI_DONE_APP, DEF_DONE_APP); - DoneAppEnabled := IniFile.ReadBool(INI_SEC_ALARMS, INI_DONE_APP_ON, DEF_DONE_APP_ON); - WndHeight := IniFile.ReadInteger(INI_SEC_PLACEMENT, INI_HEIGHT, DEF_HEIGHT); - WndWidth := IniFile.ReadInteger(INI_SEC_PLACEMENT, INI_WIDTH, DEF_WIDTH); - WndPosition := TPosition(IniFile.ReadInteger(INI_SEC_PLACEMENT, INI_POSITION, DEF_POSITION)); - WndLeft := IniFile.ReadInteger(INI_SEC_PLACEMENT, INI_LEFT, 0); - WndTop := IniFile.ReadInteger(INI_SEC_PLACEMENT, INI_TOP, 0); - - Count.Font.Quality := fqAntialiased; - Count.Font.Name := IniFile.ReadString(INI_SEC_FONTS, INI_FONT_NAME, - DEF_FONT_NAME); - Count.Font.CharSet := IniFile.ReadInteger(INI_SEC_FONTS, INI_FONT_CHARSET, - DEF_FONT_CHARSET); - Count.Font.Color := IniFile.ReadInteger(INI_SEC_FONTS, INI_FONT_COLOR, - DEF_FONT_COLOR); - Count.Font.Size := IniFile.ReadInteger(INI_SEC_FONTS, INI_FONT_SIZE, - DEF_FONT_SIZE); - Count.Font.Style := IntToFontStyles(IniFile.ReadInteger(INI_SEC_FONTS, - INI_FONT_STYLE, DEF_FONT_STYLE)); - Count.Color := IniFile.ReadInteger(INI_SEC_FONTS, INI_BG_COLOR, DEF_BG_COLOR); - - except - MessageDlg(MSG_OPEN_INI, mtError, [mbOK], 0); - end; - if Assigned(IniFile) then - IniFile.Free; - - // Use minutes argument if it's the only parameter and it's numeric - if (ParamCount = 1) and (IsInteger(ParamStr(1))) then - Minutes.Value := StrToInt(ParamStr(1)); - - UpdateTimeCaption(SecondsMode); - ResetCountdown(Sender); - if AutoStart then - ToggleCountdown(Sender); -end; - -procedure TMainForm.ResetCountdown(Sender: TObject); -begin - if (Sender.ClassName = Count.ClassName) and (not DblClickTime) then - Exit; - // Turn off both looping audio and ticking - StopAudio(); - DisableTimer(); - SetTimer(); - TrayIconMain.Icon := ImgIconMain.Picture.Icon; -end; - -procedure TMainForm.DisableTimer(); -begin - Timer1.Enabled := False; - ImgPause.Visible := False; - ImgStart.Visible := True; - MenuToggle.Caption := BTN_START; - TrayMenuToggle.Caption := BTN_START; - StopAudio(); -end; - -procedure TMainForm.EnableTimer(); -begin - Timer1.Enabled := True; - ImgPause.Visible := True; - ImgStart.Visible := False; - MenuToggle.Caption := BTN_PAUSE; - TrayMenuToggle.Caption := BTN_PAUSE; - TrayIconMain.Icon := ImgIconRunning.Picture.Icon; - - if TickingOn then - PlayTicking(); -end; - -procedure TMainForm.SetTimer(); -begin - if SecondsMode then - Timer1.Tag := Minutes.Value - else - Timer1.Tag := Minutes.Value * 60; - UpdateTime(); -end; - -procedure TMainForm.ShowOptions(Sender: TObject); -begin - OptionsForm := TOptionsForm.Create(Self); - with OptionsForm do - begin - NotifyMsg.Text := DoneMessage; - NotifyMsgOn.Checked := DoneMessageEnabled; - - NotifyTrayMsg.Text := DoneTrayMsg; - NotifyTrayMsgOn.Checked := DoneTrayMsgEnabled; - - NotifyAudio.Text := DoneAudio; - NotifyAudioOn.Checked := DoneAudioEnabled; - - NotifyRunApp.Text := DoneApp; - NotifyRunAppOn.Checked := DoneAppEnabled; - - CheckAlwaysOnTop.Checked := AlwaysOnTop; - CheckMinToTray.Checked := MinToTray; - CheckAutostart.Checked := AutoStart; - CheckHideSeconds.Checked := HideSeconds; - CheckClicktime.Checked := ClickTime; - CheckDblClickTime.Checked := DblClickTime; - CheckAutoRestart.Checked := AutoRestart; - CheckLoopAudio.Checked := LoopAudio; - CheckTicking.Checked := TickingOn; - CheckAutoSave.Checked := AutoSave; - CheckSecondsMode.Checked := SecondsMode; - - PositionCombo.Items := WndPositions; - PositionCombo.ItemIndex := Ord(WndPosition); - - PageControl1.TabIndex := 0; - - f := TFont.Create; - f.Name := Count.Font.Name; - f.Size := Count.Font.Size; - f.CharSet := Count.Font.CharSet; - f.Color := Count.Font.Color; - f.Style := Count.Font.Style; - BgColor.ButtonColor := Count.Color; - FontSizeChanged := False; - - if ShowModal = mrOk then - begin - UpdateTimeCaption(CheckSecondsMode.Checked); - - DoneMessage := NotifyMsg.Text; - DoneMessageEnabled := NotifyMsgOn.Checked; - DoneTrayMsg := NotifyTrayMsg.Text; - DoneTrayMsgEnabled := NotifyTrayMsgOn.Checked; - DoneAudio := NotifyAudio.Text; - DoneAudioEnabled := NotifyAudioOn.Checked; - DoneApp := NotifyRunApp.Text; - DoneAppEnabled := NotifyRunAppOn.Checked; - AlwaysOnTop := CheckAlwaysOnTop.Checked; - MinToTray := CheckMinToTray.Checked; - AutoStart := CheckAutostart.Checked; - HideSeconds := CheckHideSeconds.Checked; - ClickTime := CheckClicktime.Checked; - DblClickTime := CheckDblClickTime.Checked; - AutoRestart := CheckAutoRestart.Checked; - LoopAudio := CheckLoopAudio.Checked; - TickingOn := CheckTicking.Checked; - AutoSave := CheckAutoSave.Checked; - SecondsMode := CheckSecondsMode.Checked; - WndPosition := TPosition(PositionCombo.ItemIndex); - //if not (Count.Font.Size = f.Size) then - //begin - //FontSizeChanged := True; - //GetPreferredSize(FormerWidth, FormerHeight, True); - //ShowMessageFmt('width: %d, height: %d', [FormerWidth, FormerHeight]); - //end; - //Count.Font := f; - // TODO Get font colors and background color to be shown - what's up? - Count.Font.Name := f.Name; - Count.Font.Size := f.Size; - Count.Font.CharSet := f.CharSet; - Count.Font.Color := f.Color; - Count.Font.Style := f.Style; - Count.Font.Quality := fqAntialiased; - Count.Color := BgColor.ButtonColor; - - //if FontSizeChanged then OnShowForm(Sender); - - UpdateAlwaysOnTop(AlwaysOnTop); - - if Timer1.Enabled then - begin - if TickingOn then - PlayTicking - else - StopAudio(); - end; - - if AutoSave then - SaveSettings(Sender); - // TODO Resize the window if necessary to accomodate larger text - // Get the text size from the font for '00:00:00'? - - end; - end; - OptionsForm.Free; -end; - -procedure TMainForm.ToggleCountdown(Sender: TObject); -begin - if (Sender.ClassName = Count.ClassName) and (not ClickTime) then - Exit; - - if Minutes.Value = 0 then - begin - Mode := Stopwatch; - StartTime := Now - (Timer1.Tag * OneSecond); - end - else - begin - Mode := Timer; - EndTime := Now + (Timer1.Tag * OneSecond); - end; - - if Timer1.Enabled then - begin - TrayIconMain.Icon := ImgIconPaused.Picture.Icon; - DisableTimer(); - end - else - begin - if CountdownDone then - begin - // TODO When restarting after countdown has elapsed, quickly jumps from - // starting number to next one - fix? - CountdownDone := False; - ResetCountdown(Sender); - EndTime := Now + (Timer1.Tag * OneSecond); - end; - EnableTimer(); - end -end; - -procedure TMainForm.Countdown(Sender: TObject); -begin - if MODE = Stopwatch then - begin - Timer1.Tag := SecondsBetween(StartTime, Now); - UpdateTime(); - end - else - begin - if EndTime <= Now then - begin - Timer1.Tag := 0; - UpdateTime(); - DisableTimer(); - CountdownDone := True; - Application.Title := APP_NAME; - if DoneAudioEnabled then - PlayAudio(DoneAudio, LoopAudio); - if DoneAppEnabled then - RunApp(DoneApp); - if DoneTrayMsgEnabled then - ShowTrayMessage(DoneTrayMsg); - if DoneMessageEnabled then - ShowDoneMessage(DoneMessage); - - if AutoRestart then - ToggleCountdown(Sender) - else - TrayIconMain.Icon := ImgIconDone.Picture.Icon; - end - else - UpdateTime(); - Timer1.Tag := SecondsBetween(EndTime, Now); - end; -end; - -procedure TMainForm.ShowAbout(Sender: TObject); -var - AboutForm: TAboutForm; -begin - AboutForm := TAboutForm.Create(Self); - AboutForm.ShowModal; - AboutForm.Release; -end; - -procedure TMainForm.OnDestroyForm(Sender: TObject); -begin - if AutoSave then - SaveSettings(Sender); -end; - -procedure TMainForm.OnShowForm(Sender: TObject); -var - //w: integer; - //h: integer; - wRect: TRect; - //cRect: TRect; - flags: integer; - -begin - Self.Position := poDesigned; - WndHandle := GetHandle(); - GetWindowRect(WndHandle, wRect); - flags := SWP_SHOWWINDOW; - - case WndPosition of - Remember: SetWindowPos(WndHandle, HWND_TOP, WndLeft, WndTop, WndWidth, WndHeight, flags); - TopLeft: SetWindowPos(WndHandle, HWND_TOP, 0, 0, WndWidth, WndHeight, flags); - TopRight: SetWindowPos(WndHandle, HWND_TOP, Monitor.WorkareaRect.Right - WndWidth, 0, WndWidth, WndHeight, flags); - BottomLeft: SetWindowPos(WndHandle, HWND_TOP, 0, Monitor.WorkareaRect.Bottom - WndHeight, WndWidth, WndHeight, flags); - BottomRight: SetWindowPos(WndHandle, HWND_TOP, Monitor.WorkareaRect.Right - WndWidth, - Monitor.WorkareaRect.Bottom - WndHeight, WndWidth, WndHeight, flags); - Center: - begin - SetWindowPos(WndHandle, HWND_TOP, 0, 0, WndWidth, WndHeight, SWP_SHOWWINDOW or SWP_NOMOVE); - Self.Position := poScreenCenter; - end; - end; - - // TODO Get this working for window size (getpreferred size gets form, not window) - // Get preferred size before font change, then after and add or subtract that delta from the - // window size? - // AutoSize is working on startup, just not when font size is changed. - // Need to find the method that will set the window to the preferred size, because the preferred size is correct - // setBounds does it, but it also requires - if FontSizeChanged then - begin - //AutoSize:= True; - //MainForm.FontChanged(Sender); - //GetPreferredSize(w, h, True); - //cRect := GetClientRect; - //cRect.Right := w; - //cRect.Bottom := h; - //AdjustClientRect(cRect); - - // These two lines cause an exception - why I don't know - //Count.Width:= w; - //Count.Height:= h; - - //InvalidatePreferredSize; - //Repaint; - //Resize; - //AdjustSize; - - //GetPreferredSize(w, h, True); - //ShowMessageFmt('width: %d, height: %d', [w, h]); - //ShowMessageFmt('width: %d, height: %d', [FormerWidth, FormerHeight]); - //WndWidth:= WndWidth + (w - FormerWidth); - //WndHeight:= WndHeight + (h - FormerHeight); - //SetBounds(Monitor.WorkareaRect.Right - w + rightAdjust, 0, w, h); - //WndWidth:= w; - //WndHeight:= h; - //ShowMessageFmt('width: %d, height: %d', [w, h]); - //exit; - end; - - UpdateAlwaysOnTop(AlwaysOnTop); -end; - -procedure TMainForm.SaveSettings(Sender: TObject); -var - wRect: TRect; -begin - try - IniFile := TIniFile.Create(IniFilename); - IniFile.CacheUpdates := True; - IniFile.WriteInteger(INI_SEC_MAIN, INI_MINUTES, Minutes.Value); - IniFile.WriteBool(INI_SEC_MAIN, INI_ALWAYS_ON_TOP, AlwaysOnTop); - IniFile.WriteBool(INI_SEC_MAIN, INI_MIN_TO_TRAY, MinToTray); - IniFile.WriteBool(INI_SEC_MAIN, INI_AUTOSTART, AutoStart); - IniFile.WriteBool(INI_SEC_MAIN, INI_HIDESECONDS, HideSeconds); - IniFile.WriteBool(INI_SEC_MAIN, INI_CLICKTIME, ClickTime); - IniFile.WriteBool(INI_SEC_MAIN, INI_DBLCLICKTIME, DblClickTime); - IniFile.WriteBool(INI_SEC_MAIN, INI_AUTORESTART, AutoRestart); - IniFile.WriteBool(INI_SEC_MAIN, INI_LOOP_AUDIO, LoopAudio); - IniFile.WriteBool(INI_SEC_MAIN, INI_TICKING_ON, TickingOn); - IniFile.WriteBool(INI_SEC_MAIN, INI_AUTOSAVE, AutoSave); - IniFile.WriteBool(INI_SEC_MAIN, INI_SECONDS_MODE, SecondsMode); - - GetWindowRect(GetHandle(), wRect); - - IniFile.WriteInteger(INI_SEC_PLACEMENT, INI_HEIGHT, wRect.Bottom - wRect.Top); - IniFile.WriteInteger(INI_SEC_PLACEMENT, INI_WIDTH, wRect.Right - wRect.Left); - IniFile.WriteInteger(INI_SEC_PLACEMENT, INI_LEFT, wRect.Left); - IniFile.WriteInteger(INI_SEC_PLACEMENT, INI_TOP, wRect.Top); - IniFile.WriteInteger(INI_SEC_PLACEMENT, INI_POSITION, Ord(WndPosition)); - - IniFile.WriteString(INI_SEC_ALARMS, INI_DONE_MESSAGE, DoneMessage); - IniFile.WriteBool(INI_SEC_ALARMS, INI_DONE_MESSAGE_ON, DoneMessageEnabled); - IniFile.WriteString(INI_SEC_ALARMS, INI_DONE_TRAY_MESSAGE, DoneTrayMsg); - IniFile.WriteBool(INI_SEC_ALARMS, INI_DONE_TRAY_MESSAGE_ON, DoneTrayMsgEnabled); - IniFile.WriteString(INI_SEC_ALARMS, INI_DONE_AUDIO, DoneAudio); - IniFile.WriteBool(INI_SEC_ALARMS, INI_DONE_AUDIO_ON, DoneAudioEnabled); - IniFile.WriteString(INI_SEC_ALARMS, INI_DONE_APP, DoneApp); - IniFile.WriteBool(INI_SEC_ALARMS, INI_DONE_APP_ON, DoneAppEnabled); - - IniFile.WriteString(INI_SEC_FONTS, INI_FONT_NAME, Count.Font.Name); - IniFile.WriteInteger(INI_SEC_FONTS, INI_FONT_CHARSET, Count.Font.CharSet); - IniFile.WriteInteger(INI_SEC_FONTS, INI_FONT_COLOR, Count.Font.Color); - IniFile.WriteInteger(INI_SEC_FONTS, INI_FONT_SIZE, Count.Font.Size); - IniFile.WriteInteger(INI_SEC_FONTS, INI_FONT_STYLE, FontStylesToInt(Count.Font)); - IniFile.WriteInteger(INI_SEC_FONTS, INI_BG_COLOR, Count.Color); - IniFile.UpdateFile; - except - MessageDlg(MSG_WRITE_INI, mtError, [mbOK], 0); - end; -end; - -procedure TMainForm.MinutesChanged(Sender: TObject); -begin - if not Timer1.Enabled then - ResetCountdown(Sender); -end; - -procedure TMainForm.ToggleCompact(Sender: TObject); -begin - SetFieldsVisible(CompactMode); - CompactMode := not CompactMode; -end; - - // TODO Figure out how to remove the fields from the form so they don't - // take up space anymore (and count can expand to top) - // Easier to create a new form, hide this one and show the other one - // Set border style to none too. -procedure TMainForm.SetFieldsVisible(showFields: boolean); -begin - if showFields then - begin - MainForm.Menu := MainMenu1; - end - else - begin - MainForm.Menu := nil; - TimeLabel.Visible := showFields; - Minutes.Visible := showFields; - ImgStart.Visible := showFields; - ImgReset.Visible := showFields; - ImgPause.Visible := showFields; - end; -end; - -procedure TMainForm.CloseApp(Sender: TObject); -begin - OnDestroyForm(Sender); - Close; -end; - -function TMainForm.SecondsToTime(Seconds: integer): string; -var - h, m, s: integer; -begin - h := Seconds div 3600; - m := Seconds div 60 - h * 60; - s := Seconds - (h * 3600 + m * 60); - if HideSeconds then - begin - Result := SysUtils.Format('%.2d:%.2d', [h, m]); - end - else - begin - Result := SysUtils.Format('%.2d:%.2d:%.2d', [h, m, s]); - end; -end; - -procedure TMainForm.FormKeyPress(Sender: TObject; var Key: char); -begin - // TMainForm's KeyPreview property must be set to True for this to work. - if key = #27 then - Close; // 27 = Escape - if (Minutes.Focused) and (key = #13) then - ToggleCountdown(Sender); -end; - - // TODO Animate icon between alarm icon and main so it blinks every second - // Instead of playing icon, animate the clock hands so they go around? - // http://delphi.about.com/od/kbwinshell/l/aa122501a.htm -procedure TMainForm.UpdateTime(); -begin - // Changing caption while it's not visible keeps time from flashing - Count.Visible := False; - Count.Caption := SecondsToTime(Timer1.Tag); - Count.Visible := True; - MenuCount.Caption := Count.Caption; - if Timer1.Enabled then - begin - Application.Title := Count.Caption + ' - ' + APP_NAME; - TrayIconMain.Hint := Count.Caption; - end - else - begin - Application.Title := APP_NAME; - TrayIconMain.Hint := APP_NAME; - end; -end; - -procedure TMainForm.FormWindowStateChange(Sender: TObject); -begin - if not MinToTray then - Exit; - - if WindowState = wsMinimized then - begin - WindowState := wsNormal; - ShowInTaskBar := stNever; - Hide; - end; -end; - -// TODO Interpret env vars in the path -class function TMainForm.GetFilePath(Path: string): string; -begin - if AnsiStartsStr('.', Path) then - begin - Result := ExtractFilePath(Application.ExeName) + Path; - end else - Result := Path; -end; - -procedure TMainForm.PlayAudio(Path: string; Loop: boolean); -begin - if AudioPlaying then - Exit; - if Loop then - begin - AudioPlaying := True; - sndPlaySound(PChar(GetFilePath(Path)), SND_NODEFAULT or SND_ASYNC or SND_LOOP); - end - else - sndPlaySound(PChar(GetFilePath(Path)), SND_NODEFAULT or SND_ASYNC); -end; - -procedure TMainForm.StopAudio(); -begin - sndPlaySound(nil, 0); - AudioPlaying := False; -end; - -procedure TMainForm.PlayTicking(); -begin - sndPlaySound(PChar(GetFilePath(DEF_TICKING_PATH)), SND_NODEFAULT or - SND_ASYNC or SND_LOOP); -end; - -procedure TMainForm.RunApp(Path: string); -begin - ShellExecute(0, 'open', PChar(GetFilePath(Path)), nil, nil, SW_SHOWNORMAL); -end; - -procedure TMainForm.ShowTrayMessage(Msg: string); -begin - with TrayIconMain do - begin - BalloonHint := Msg; - ShowBalloonHint; - BalloonTimeout := 4000; - end; -end; - -procedure TMainForm.ShowDoneMessage(Msg: string); -begin - // http://msdn.microsoft.com/en-us/library/ms645505(VS.85).aspx - Windows.MessageBox(GetHandle(), pChar(msg), 'Done', - MB_SYSTEMMODAL or MB_SETFOREGROUND or MB_TOPMOST or MB_ICONINFORMATION); - StopAudio(); -end; - -function TMainForm.GetHandle(): HWND; -begin - Result := Application.MainForm.Handle; -end; - -procedure TMainForm.SetDefaults(Sender: TObject); -begin - with Sender as TOptionsForm do - BgColor.ButtonColor := DEF_BG_COLOR; - f.Name := DEF_FONT_NAME; - f.Color := DEF_FONT_COLOR; - f.CharSet := DEF_FONT_CHARSET; - f.Size := DEF_FONT_SIZE; - f.Style := IntToFontStyles(DEF_FONT_STYLE); -end; - -function TMainForm.FontStylesToInt(Fnt: TFont): integer; -var - Mask: integer; - Style: TFontStyle; -begin - // Translate the set into a bit mask - Mask := 0; - for Style := Low(TFontStyle) to High(TFontStyle) do - if Style in Fnt.Style then - Mask := Mask or (1 shl Ord(Style)); - Result := Mask; -end; - -function TMainForm.IntToFontStyles(Mask: integer): TFontStyles; -var - i: integer; - StyleSet: TFontStyles; -begin - // Translate the bit mask into a set - StyleSet := []; - for i := 0 to Ord(High(TFontStyle)) do - if Mask and (1 shl i) <> 0 then - StyleSet := StyleSet + [TFontStyle(i)]; - Result := StyleSet; -end; - -procedure TMainForm.UpdateAlwaysOnTop(onTop: boolean); -begin - if onTop then - FormStyle:= fsSystemStayOnTop - else - FormStyle:= fsNormal -end; - -procedure TMainForm.FormActivate(Sender: TObject); -begin - WindowState := wsNormal; - ShowInTaskBar := stDefault; - Show; -end; - -function TMainForm.IsInteger(S: String): boolean; -begin - try - Result := True; - StrToInt(S); - except on E: EConvertError do - Result := False; - end; -end; - -// TODO Only update the time if this value changed (otherwise it resets -// the time every time you modify settings) -// It's not working - test it thoroughly and fix it. -procedure TMainForm.UpdateTimeCaption(newSecondsMode: boolean); -begin - if newSecondsMode <> SecondsMode then - begin - if newSecondsMode then - TimeLabel.Caption := LBL_SECONDS - else - TimeLabel.Caption := LBL_MINUTES; - SetTimer(); - end; - -end; - -initialization - {$I mainform1.lrs} -end. - diff --git a/model/config.pas b/model/config.pas new file mode 100644 index 0000000..1c8733d --- /dev/null +++ b/model/config.pas @@ -0,0 +1,468 @@ +unit Config; + +{$mode objfpc} + +interface + +uses + Classes, SysUtils, Graphics; + +const + COMPACT_MODE_ALPHA_MIN = 10; + +type + TPosition = ( + Center, + Remember, + TopLeft, + TopRight, + BottomLeft, + BottomRight, + // Aliases + _TPositionFirst = Center, + _TPositionLast = BottomRight + ); + + TCompactModeTransparency = ( + None, + TransparentBackground, + AlphaBlending, + // Aliases + _TCompactModeTransparencyFirst = None, + _TCompactTransparencyLast = AlphaBlending + ); + + TFontConfig = class + Name: String; + Charset: Integer; + Color: Integer; + BgColor: Integer; + Size: Integer; + Style: TFontStyles; + end; + + TCompactModeConfig = class + Enabled: Boolean; + Transparency: TCompactModeTransparency; + AlphaValue: Byte; + end; + + TConfig = class + private + // Main + FMinutes: Integer; + FAlwaysOnTop: boolean; + FMinToTray: boolean; + FAutoStart: boolean; + FHideSeconds: boolean; + FClickTime: boolean; + FDblClickTime: boolean; + FAutoRestart: boolean; + FLoopAudio: boolean; + FTickingOn: boolean; + FAutoSave: boolean; + FSecondsMode: boolean; + // Placement + FWndHeight: integer; + FWndWidth: integer; + FWndLeft: integer; + FWndTop: integer; + FWndPosition: TPosition; + // Alarms + FDoneMessage: string; + FDoneMessageEnabled: boolean; + FDoneTrayMsg: string; + FDoneTrayMsgEnabled: boolean; + FDoneAudio: string; + FDoneAudioEnabled: boolean; + FDoneApp: string; + FDoneAppEnabled: boolean; + // Font + FFont: TFontConfig; + FDefaultFont: TFontConfig; + // Compact Mode + FCompactMode: TCompactModeConfig; + + procedure SetWndPosition(Value: TPosition); + procedure SetDoneMessage(Msg: String); + procedure SetDoneTrayMessage(Msg: String); + public + constructor Create; + destructor Free; + function Load : Boolean; + function Save : Boolean; + function GetDefaultFont : TFontConfig; + + // Main + property Minutes: Integer read FMinutes write FMinutes; + property AlwaysOnTop: boolean read FAlwaysOnTop write FAlwaysOnTop; + property MinToTray: boolean read FMinToTray write FMinToTray; + property AutoStart: boolean read FAutoStart write FAutoStart; + property HideSeconds: boolean read FHideSeconds write FHideSeconds; + property ClickTime: boolean read FClickTime write FClickTime; + property DblClickTime: boolean read FDblClickTime write FDblClickTime; + property AutoRestart: boolean read FAutoRestart write FAutoRestart; + property LoopAudio: boolean read FLoopAudio write FLoopAudio; + property TickingOn: boolean read FTickingOn write FTickingOn; + property AutoSave: boolean read FAutoSave write FAutoSave; + property SecondsMode: boolean read FSecondsMode write FSecondsMode; // Undocumented mode to treat minutes as seconds + // Placement + property WndHeight: integer read FWndHeight write FWndHeight; + property WndWidth: integer read FWndWidth write FWndWidth; + property WndLeft: integer read FWndLeft write FWndLeft; + property WndTop: integer read FWndTop write FWndTop; + property WndPosition: TPosition read FWndPosition write SetWndPosition; + // Alarm + property DoneMessage: string read FDoneMessage write SetDoneMessage; + property DoneMessageEnabled: boolean read FDoneMessageEnabled write FDoneMessageEnabled; + property DoneTrayMsg: string read FDoneTrayMsg write SetDoneTrayMessage; + property DoneTrayMsgEnabled: boolean read FDoneTrayMsgEnabled write FDoneTrayMsgEnabled; + property DoneAudio: string read FDoneAudio write FDoneAudio; + property DoneAudioEnabled: boolean read FDoneAudioEnabled write FDoneAudioEnabled; + property DoneApp: string read FDoneApp write FDoneApp; + property DoneAppEnabled: boolean read FDoneAppEnabled write FDoneAppEnabled; + // Fonts + property Font: TFontConfig read FFont write FFont; + // Compact Mode + property CompactMode: TCompactModeConfig read FCompactMode write FCompactMode; +end; + +function GetConfig : TConfig; + +implementation + +uses + IniFiles; + +// Default values +const + INI_SEC_MAIN = 'Main'; + INI_SEC_ALARMS = 'Alarms'; + INI_SEC_PLACEMENT = 'Placement'; + INI_SEC_FONTS = 'Fonts'; + INI_SEC_COMPACT_MODE = 'CompactMode'; + INI_MINUTES = 'Minutes'; + INI_ALWAYS_ON_TOP = 'AlwaysOnTop'; + INI_MIN_TO_TRAY = 'MinToTray'; + INI_AUTOSTART = 'AutoStart'; + INI_HIDESECONDS = 'HideSeconds'; + INI_CLICKTIME = 'ClickTime'; + INI_DBLCLICKTIME = 'DoubleClickTime'; + INI_AUTORESTART = 'AutoRestart'; + INI_LOOP_AUDIO = 'LoopAudio'; + INI_TICKING_ON = 'TickingEnabled'; + INI_AUTOSAVE = 'AutoSave'; + INI_HEIGHT = 'WinHeight'; + INI_WIDTH = 'WinWidth'; + INI_LEFT = 'WinLeft'; + INI_TOP = 'WinTop'; + INI_POSITION = 'WinPosition'; + INI_DONE_MESSAGE = 'Message'; + INI_DONE_MESSAGE_ON = 'MessageEnabled'; + INI_DONE_TRAY_MESSAGE = 'TrayMessage'; + INI_DONE_TRAY_MESSAGE_ON = 'TrayMessageEnabled'; + INI_DONE_AUDIO = 'AudioFile'; + INI_DONE_AUDIO_ON = 'AudioFileEnabled'; + INI_DONE_APP = 'RunApp'; + INI_DONE_APP_ON = 'RunAppEnabled'; + INI_SECONDS_MODE = 'SecondsMode'; + INI_FONT_NAME = 'Name'; + INI_FONT_CHARSET = 'Charset'; + INI_FONT_COLOR = 'Color'; + INI_FONT_SIZE = 'Size'; + INI_FONT_STYLE = 'Style'; + INI_BG_COLOR = 'BgColor'; + INI_COMPACT_MODE_ENABLED = 'Enabled'; + INI_COMPACT_MODE_TRANSPARENCY = 'Transparency'; + INI_COMPACT_MODE_ALPHA_VALUE = 'AlphaValue'; + + INI_FILE_NAME = 'SnapTimer.ini'; + DEF_TIME = 15; + DEF_DONE_MSG = 'Time''s up'; + DEF_DONE_MSG_ON = True; + DEF_DONE_TRAY_MSG = 'Countdown completed'; + DEF_DONE_TRAY_MSG_ON = False; + DEF_DONE_AUDIO = '.\sounds\alarm_clock_bell.wav'; + DEF_DONE_AUDIO_ON = False; + DEF_DONE_APP = ''; + DEF_DONE_APP_ON = False; + DEF_ALWAYS_ON_TOP = False; + DEF_MIN_TO_TRAY = False; + DEF_AUTOSTART = False; + DEF_HIDESECONDS = False; + DEF_CLICKTIME = True; + DEF_DBLCLICKTIME = True; + DEF_AUTORESTART = False; + DEF_LOOP_AUDIO = False; + DEF_TICKING_ON = False; + DEF_TICKING_PATH = '.\sounds\ticking\ticking.wav'; + DEF_AUTOSAVE = True; + DEF_SECONDS_MODE = False; + DEF_POSITION = Ord(Center); + DEF_HEIGHT = 149; + DEF_WIDTH = 214; + DEF_FONT_NAME = 'Arial'; + DEF_FONT_CHARSET = 0; + DEF_FONT_COLOR = clNavy; + DEF_FONT_BG_COLOR = clNone; + DEF_FONT_SIZE = 38; + DEF_FONT_STYLE = 0; + DEF_COMPACT_MODE = False; + DEF_COMPACT_MODE_TRANSPARENCY = TCompactModeTransparency.None; + DEF_COMPACT_MODE_ALPHA = 128; + + var + ConfigInstance : TConfig; + + + function FontStylesToInt(FontStyles: TFontStyles): integer; + var + Mask: integer; + Style: TFontStyle; + begin + // Translate the set into a bit mask + Mask := 0; + for Style := Low(TFontStyle) to High(TFontStyle) do + if Style in FontStyles then + Mask := Mask or (1 shl Ord(Style)); + Result := Mask; + end; + + function IntToFontStyles(Mask: integer): TFontStyles; + var + i: integer; + StyleSet: TFontStyles; + begin + // Translate the bit mask into a set + StyleSet := []; + for i := 0 to Ord(High(TFontStyle)) do + if Mask and (1 shl i) <> 0 then + StyleSet := StyleSet + [TFontStyle(i)]; + Result := StyleSet; + end; + +procedure TConfig.SetDoneMessage(Msg: String); +begin + // TODO Set some reasonable length limit + FDoneMessage:= Msg; +end; + +procedure TConfig.SetDoneTrayMessage(Msg: String); +begin + // TODO Set some reasonable length limit + FDoneTrayMsg:= Msg; +end; + + +procedure TConfig.SetWndPosition(Value: TPosition); +begin + if Value < _TPositionFirst then + Value:= _TPositionFirst; + + if Value > _TPositionLast then + Value:= _TPositionLast; + + FWndPosition:= Value; +end; + +constructor TConfig.Create; +begin + // Main + Minutes:= DEF_TIME; + AlwaysOnTop := DEF_ALWAYS_ON_TOP; + MinToTray:= DEF_MIN_TO_TRAY; + AutoStart:= DEF_AUTOSTART; + HideSeconds:= DEF_HIDESECONDS; + ClickTime:= DEF_CLICKTIME; + DblClickTime:= DEF_DBLCLICKTIME; + AutoRestart:= DEF_AUTORESTART; + LoopAudio:= DEF_LOOP_AUDIO; + TickingOn:= DEF_TICKING_ON; + AutoSave:= DEF_AUTOSAVE; + SecondsMode:= DEF_SECONDS_MODE; + // Placement + WndPosition:= TPosition(DEF_POSITION); + WndWidth:= DEF_WIDTH; + WndHeight:= DEF_HEIGHT; + // Alarms + DoneMessage:= DEF_DONE_MSG; + DoneMessageEnabled:= DEF_DONE_MSG_ON; + DoneTrayMsg:= DEF_DONE_TRAY_MSG; + DoneTrayMsgEnabled:= DEF_DONE_TRAY_MSG_ON; + DoneAudio:= DEF_DONE_AUDIO; + DoneAudioEnabled:= DEF_DONE_AUDIO_ON; + DoneApp:= DEF_DONE_APP; + DoneAppEnabled:= DEF_DONE_APP_ON; + // Fonts + FFont:= TFontConfig.Create; + Font.Name:= DEF_FONT_NAME; + Font.Charset:= DEF_FONT_CHARSET; + Font.Color:= DEF_FONT_COLOR; + Font.BgColor:= DEF_FONT_BG_COLOR; + Font.Size:= DEF_FONT_SIZE; + Font.Style:= IntToFontStyles(DEF_FONT_STYLE); + // CompactMode + CompactMode := TCompactModeConfig.Create; + CompactMode.Enabled:= DEF_COMPACT_MODE; + CompactMode.Transparency:= DEF_COMPACT_MODE_TRANSPARENCY; + CompactMode.AlphaValue:= DEF_COMPACT_MODE_ALPHA; + + FDefaultFont:= TFontConfig.Create; + FDefaultFont.Name:= DEF_FONT_NAME; + FDefaultFont.Charset:= DEF_FONT_CHARSET; + FDefaultFont.Color:= DEF_FONT_COLOR; + FDefaultFont.BgColor:= DEF_FONT_BG_COLOR; + FDefaultFont.Size:= DEF_FONT_SIZE; + FDefaultFont.Style:= IntToFontStyles(DEF_FONT_STYLE); +end; + +destructor TConfig.Free; +begin + FFont.Free; + FDefaultFont.Free; + FCompactMode.Free; +end; + +function ReadInt(InIfile: TIniFile; const Section, Ident: String; Min, Max, Default: Integer) : Integer; +begin + Result:= IniFile.ReadInteger(Section, Ident, Default); + if Result < Min then + Result:= Min; + if Result > Max then + Result:= Max; +end; + +function TConfig.Load : Boolean; +var IniFile: TIniFile; +begin + try + IniFile := TIniFile.Create(INI_FILE_NAME); + // Main + Minutes := IniFile.ReadInteger(INI_SEC_MAIN, INI_MINUTES, DEF_TIME); + AlwaysOnTop := IniFile.ReadBool(INI_SEC_MAIN, INI_ALWAYS_ON_TOP, DEF_ALWAYS_ON_TOP); + MinToTray := IniFile.ReadBool(INI_SEC_MAIN, INI_MIN_TO_TRAY, DEF_MIN_TO_TRAY); + AutoStart := IniFile.ReadBool(INI_SEC_MAIN, INI_AUTOSTART, DEF_AUTOSTART); + HideSeconds := IniFile.ReadBool(INI_SEC_MAIN, INI_HIDESECONDS, DEF_HIDESECONDS); + ClickTime := IniFile.ReadBool(INI_SEC_MAIN, INI_CLICKTIME, DEF_CLICKTIME); + DblClickTime := IniFile.ReadBool(INI_SEC_MAIN, INI_DBLCLICKTIME, DEF_DBLCLICKTIME); + AutoRestart := IniFile.ReadBool(INI_SEC_MAIN, INI_AUTORESTART, DEF_AUTORESTART); + LoopAudio := IniFile.ReadBool(INI_SEC_MAIN, INI_LOOP_AUDIO, DEF_LOOP_AUDIO); + TickingOn := IniFile.ReadBool(INI_SEC_MAIN, INI_TICKING_ON, DEF_TICKING_ON); + AutoSave := IniFile.ReadBool(INI_SEC_MAIN, INI_AUTOSAVE, DEF_AUTOSAVE); + SecondsMode := IniFile.ReadBool(INI_SEC_MAIN, INI_SECONDS_MODE, DEF_SECONDS_MODE); + // Placement + WndHeight := IniFile.ReadInteger(INI_SEC_PLACEMENT, INI_HEIGHT, DEF_HEIGHT); + WndWidth := IniFile.ReadInteger(INI_SEC_PLACEMENT, INI_WIDTH, DEF_WIDTH); + WndLeft := IniFile.ReadInteger(INI_SEC_PLACEMENT, INI_LEFT, 0); + WndTop := IniFile.ReadInteger(INI_SEC_PLACEMENT, INI_TOP, 0); + WndPosition := TPosition(ReadInt(IniFile, INI_SEC_PLACEMENT, INI_POSITION, Ord(_TPositionFirst), Ord(_TPositionLast), DEF_POSITION)); + // Alarm + DoneMessage := IniFile.ReadString(INI_SEC_ALARMS, INI_DONE_MESSAGE, DEF_DONE_MSG); + DoneMessageEnabled := IniFile.ReadBool(INI_SEC_ALARMS, INI_DONE_MESSAGE_ON, DEF_DONE_MSG_ON); + DoneTrayMsg := IniFile.ReadString(INI_SEC_ALARMS, INI_DONE_TRAY_MESSAGE, DEF_DONE_TRAY_MSG); + DoneTrayMsgEnabled := IniFile.ReadBool(INI_SEC_ALARMS, INI_DONE_TRAY_MESSAGE_ON, DEF_DONE_TRAY_MSG_ON); + DoneAudio := IniFile.ReadString(INI_SEC_ALARMS, INI_DONE_AUDIO, DEF_DONE_AUDIO); + DoneAudioEnabled := IniFile.ReadBool(INI_SEC_ALARMS, INI_DONE_AUDIO_ON, DEF_DONE_AUDIO_ON); + DoneApp := IniFile.ReadString(INI_SEC_ALARMS, INI_DONE_APP, DEF_DONE_APP); + DoneAppEnabled := IniFile.ReadBool(INI_SEC_ALARMS, INI_DONE_APP_ON, DEF_DONE_APP_ON); + // Fonts + Font.Name := IniFile.ReadString(INI_SEC_FONTS, INI_FONT_NAME, DEF_FONT_NAME); + Font.Charset := IniFile.ReadInteger(INI_SEC_FONTS, INI_FONT_CHARSET, DEF_FONT_CHARSET); + Font.Color := IniFile.ReadInteger(INI_SEC_FONTS, INI_FONT_COLOR, DEF_FONT_COLOR); + Font.BgColor := IniFile.ReadInteger(INI_SEC_FONTS, INI_BG_COLOR, DEF_FONT_BG_COLOR); + Font.Size := IniFile.ReadInteger(INI_SEC_FONTS, INI_FONT_SIZE, DEF_FONT_SIZE); + Font.Style := IntToFontStyles(IniFile.ReadInteger(INI_SEC_FONTS, INI_FONT_STYLE, DEF_FONT_STYLE)); + // CompactMode + CompactMode.Enabled := IniFile.ReadBool(INI_SEC_COMPACT_MODE, INI_COMPACT_MODE_ENABLED, DEF_COMPACT_MODE); + CompactMode.Transparency:= TCompactModeTransparency(ReadInt(IniFile, INI_SEC_COMPACT_MODE, INI_COMPACT_MODE_TRANSPARENCY, + Ord(_TCompactModeTransparencyFirst), Ord(_TCompactTransparencyLast), Ord(DEF_COMPACT_MODE_TRANSPARENCY))); + CompactMode.AlphaValue:= ReadInt(Inifile, INI_SEC_COMPACT_MODE, INI_COMPACT_MODE_ALPHA_VALUE, COMPACT_MODE_ALPHA_MIN, 255, DEF_COMPACT_MODE_ALPHA); + except + Result:= False; + end; + Result:= True; + + if Assigned(IniFile) then + IniFile.Free; + +{$IFDEF LINUX} + // Not supported on Linux + LoopAudio:= False; + TickingOn:= False; + if CompactMode.Transparency = TransparentBackground then + CompactMode.Transparency:= None; +{$ENDIF} +end; + +function TConfig.Save : Boolean; +var IniFile: TIniFile; +begin + try + IniFile := TIniFile.Create(INI_FILE_NAME); + IniFile.CacheUpdates := True; + // Main + IniFile.WriteInteger(INI_SEC_MAIN, INI_MINUTES, Minutes); + IniFile.WriteBool(INI_SEC_MAIN, INI_ALWAYS_ON_TOP, AlwaysOnTop); + IniFile.WriteBool(INI_SEC_MAIN, INI_MIN_TO_TRAY, MinToTray); + IniFile.WriteBool(INI_SEC_MAIN, INI_AUTOSTART, AutoStart); + IniFile.WriteBool(INI_SEC_MAIN, INI_HIDESECONDS, HideSeconds); + IniFile.WriteBool(INI_SEC_MAIN, INI_CLICKTIME, ClickTime); + IniFile.WriteBool(INI_SEC_MAIN, INI_DBLCLICKTIME, DblClickTime); + IniFile.WriteBool(INI_SEC_MAIN, INI_AUTORESTART, AutoRestart); + IniFile.WriteBool(INI_SEC_MAIN, INI_LOOP_AUDIO, LoopAudio); + IniFile.WriteBool(INI_SEC_MAIN, INI_TICKING_ON, TickingOn); + IniFile.WriteBool(INI_SEC_MAIN, INI_AUTOSAVE, AutoSave); + IniFile.WriteBool(INI_SEC_MAIN, INI_SECONDS_MODE, SecondsMode); + // Placement + IniFile.WriteInteger(INI_SEC_PLACEMENT, INI_HEIGHT, WndHeight); + IniFile.WriteInteger(INI_SEC_PLACEMENT, INI_WIDTH, WndWidth); + IniFile.WriteInteger(INI_SEC_PLACEMENT, INI_LEFT, WndLeft); + IniFile.WriteInteger(INI_SEC_PLACEMENT, INI_TOP, WndTop); + IniFile.WriteInteger(INI_SEC_PLACEMENT, INI_POSITION, Ord(WndPosition)); + // Alarms + IniFile.WriteString(INI_SEC_ALARMS, INI_DONE_MESSAGE, DoneMessage); + IniFile.WriteBool(INI_SEC_ALARMS, INI_DONE_MESSAGE_ON, DoneMessageEnabled); + IniFile.WriteString(INI_SEC_ALARMS, INI_DONE_TRAY_MESSAGE, DoneTrayMsg); + IniFile.WriteBool(INI_SEC_ALARMS, INI_DONE_TRAY_MESSAGE_ON, DoneTrayMsgEnabled); + IniFile.WriteString(INI_SEC_ALARMS, INI_DONE_AUDIO, DoneAudio); + IniFile.WriteBool(INI_SEC_ALARMS, INI_DONE_AUDIO_ON, DoneAudioEnabled); + IniFile.WriteString(INI_SEC_ALARMS, INI_DONE_APP, DoneApp); + IniFile.WriteBool(INI_SEC_ALARMS, INI_DONE_APP_ON, DoneAppEnabled); + // Fonts + IniFile.WriteString(INI_SEC_FONTS, INI_FONT_NAME, Font.Name); + IniFile.WriteInteger(INI_SEC_FONTS, INI_FONT_CHARSET, Font.Charset); + IniFile.WriteInteger(INI_SEC_FONTS, INI_FONT_COLOR, Font.Color); + IniFile.WriteInteger(INI_SEC_FONTS, INI_BG_COLOR, Font.BgColor); + IniFile.WriteInteger(INI_SEC_FONTS, INI_FONT_SIZE, Font.Size); + IniFile.WriteInteger(INI_SEC_FONTS, INI_FONT_STYLE, FontStylesToInt(Font.Style)); + // CompactMode + IniFile.WriteBool(INI_SEC_COMPACT_MODE, INI_COMPACT_MODE_ENABLED, CompactMode.Enabled); + IniFile.WriteInteger(INI_SEC_COMPACT_MODE, INI_COMPACT_MODE_TRANSPARENCY, Ord(CompactMode.Transparency)); + IniFile.WriteInteger(INI_SEC_COMPACT_MODE, INI_COMPACT_MODE_ALPHA_VALUE, CompactMode.AlphaValue); + + IniFile.UpdateFile; + except + Result:= False; + end; + Result:= True; + + if Assigned(IniFile) then + IniFile.Free; +end; + +function TConfig.GetDefaultFont : TFontConfig; +begin + Result:= FDefaultFont; +end; + + +function GetConfig : TConfig; +begin + Result:= ConfigInstance; +end; + +initialization + ConfigInstance:= TConfig.Create; + +end. + diff --git a/model/mytimer.pas b/model/mytimer.pas new file mode 100644 index 0000000..511b0c3 --- /dev/null +++ b/model/mytimer.pas @@ -0,0 +1,205 @@ +unit MyTimer; + +{$mode objfpc} + +interface + +uses + Classes, SysUtils, ExtCtrls; + +type + TMode = (Timer, Stopwatch); + TState = (Ready, Running, Finished, Paused); + + // TODO find better name + TMyTimer = class + private + FTimer: TTimer; + // Start or End time, depending on the Mode. + FTime: TDateTime; + FSeconds: Integer; + FSecondsInitial: Integer; + FState: TState; + FMode: TMode; + FOnSecondElapsed: TNotifyEvent; + FOnStateChanged: TNotifyEvent; + + function GetSeconds : Integer; + procedure SetSeconds(AValue: Integer); + function GetMinutes : Integer; + procedure SetMinutes(AValue: Integer); + + procedure OnTimer(Sender: TObject); + procedure UpdateSeconds; + procedure UpdateTime; + public + constructor Create; + destructor Free; + procedure Start; + procedure Pause; + procedure Resume; + procedure Toggle; + procedure Reset; + + property Seconds: Integer read GetSeconds write SetSeconds; + property Minutes: Integer read GetMinutes write SetMinutes; + property State: TState read FState; + property Mode: TMode read FMode write FMode; + property OnSecondElapsed: TNotifyEvent read FOnSecondElapsed write FOnSecondElapsed; + property OnStateChanged: TNotifyEvent read FOnStateChanged write FOnStateChanged; + private + +end; + +implementation + +uses DateUtils; + +function TMyTimer.GetSeconds : Integer; +begin + Result:= FSeconds; +end; + +procedure TMyTimer.SetSeconds(AValue: Integer); +begin + if State <> Ready then + Raise Exception.Create('Timer is not in `Ready` state'); + FSeconds:= AValue; + FSecondsInitial:= AValue; +end; + +function TMyTimer.GetMinutes : Integer; +begin + Result:= FSeconds div 60; +end; + +procedure TMyTimer.SetMinutes(AValue: Integer); +begin + if State <> Ready then + Raise Exception.Create('Timer is not in `Ready` or `Finished` state'); + FSeconds:= AValue * 60; + FSecondsInitial:= FSeconds; +end; + +procedure TMyTimer.OnTimer(Sender: TObject); +begin + if Mode = Timer then + begin + if Now >= FTime then + begin + FTimer.Enabled:= False; + FSeconds:= 0; + FState:= Finished; + if Assigned(FOnStateChanged) then + FOnStateChanged(self); + end + else + UpdateSeconds; + end + else + begin + // Stopwatch + UpdateSeconds; + end +end; + +procedure TMyTimer.UpdateSeconds; +var s : Integer; +begin + s:= SecondsBetween(FTime, Now); + if s <> FSeconds then + begin + FSeconds:= s; + if Assigned(FOnSecondElapsed) then + FOnSecondElapsed(self); + end; +end; + +procedure TMyTimer.UpdateTime; +begin + if Mode = Timer then + FTime:= Now + (FSeconds * OneSecond) // FTime is the end time + else + FTime:= Now - (FSeconds * OneSecond) // FTime is the start time +end; + +constructor TMyTimer.Create; +begin + FTimer:= TTimer.Create(nil); + FTimer.Enabled:= False; + FTimer.Interval:= 160; + FTimer.OnTimer:= @OnTimer; + FSeconds:= 10 * 60; + FSecondsInitial:= FSeconds; + FState:= Ready; + FMode:= Timer; + FOnSecondElapsed:= nil; + FOnStateChanged:= nil; +end; + +destructor TMyTimer.Free; +begin + FTimer.Free; +end; + + +procedure TMyTimer.Start; +begin + if State <> Ready then + Raise Exception.Create('Timer is not in `Ready` state'); + + FState:= Running; + UpdateTime; + if Assigned(FOnStateChanged) then + FOnStateChanged(self); + FTimer.Enabled:= True; +end; + +procedure TMyTimer.Pause; +begin + if State <> Running then + Raise Exception.Create('Timer is not in `Running` state'); + + FState:= Paused; + if Assigned(FOnStateChanged) then + FOnStateChanged(self); + FTimer.Enabled:= False; +end; + +procedure TMyTimer.Resume; +begin + if State <> Paused then + Raise Exception.Create('Timer is not in `Paused` state'); + + FState:= Running; + UpdateTime; + if Assigned(FOnStateChanged) then + FOnStateChanged(self); + FTimer.Enabled:= True; +end; + +procedure TMyTimer.Toggle; +begin + case State of + Ready : Start; + Running : Pause; + Finished : Reset; + Paused : Resume; + end; +end; + +procedure TMyTimer.Reset; +var PrevState: TState; +begin + PrevState:= FState; + FTimer.Enabled:= False; + FState:= Ready; + FSeconds:= FSecondsInitial; + // We want FOnStateChanged to be called even if we are in `Ready` state. + if Assigned(FOnStateChanged) {and (PrevState <> Ready)} then + FOnStateChanged(self); +end; + + +end. + diff --git a/model/utils.pas b/model/utils.pas new file mode 100644 index 0000000..68cdc01 --- /dev/null +++ b/model/utils.pas @@ -0,0 +1,280 @@ +unit utils; + +{$mode objfpc}{$H+} +{$modeswitch advancedrecords} + +interface + +Uses Forms, Types, Controls; + + +// https://forum.lazarus.freepascal.org/index.php/topic,29450.msg186002.html?PHPSESSID=0l7k7l8bgpqdvcqcqetk17rt04#msg186002 +type + TRectHelper = record helper for TRect + private + function GetWidth: Integer; + procedure SetWidth(const Value: Integer); + function GetHeight: Integer; + procedure SetHeight(const Value: Integer); + public + property Width: Integer read GetWidth write SetWidth; + property Height: Integer read GetHeight write SetHeight; + end; + +// TUtils class serves as a namespace. +type + TUtils = class + class function SecondsToTime(Seconds: integer; HideSeconds: Boolean): string; + class function GetFilePath(Path: string): string; + class procedure RunApp(Path: string); + class function IsInteger(S: String): boolean; + class function GetFormRect(Form: TForm) : TRect; + class procedure SetControlPos(Control: TWinControl; X: Integer; Y: Integer); + class function GetControlPos(Control: TWinControl) : TPoint; + class procedure PlayAudio(Path: string; Loop: boolean); + class procedure StopAudio; + end; + +implementation + +uses + Classes, SysUtils, StrUtils, FileUtil +{$IFDEF WINDOWS} + ,Windows, MMSystem +{$ENDIF} +{$IFDEF LINUX} + ,Process, asyncprocess +{$ENDIF} +; + + +function TRectHelper.GetHeight: Integer; +begin + Result := Bottom - Top; +end; + +procedure TRectHelper.SetHeight(const Value: Integer); +begin + Bottom := Top + Value; +end; + +function TRectHelper.GetWidth: Integer; +begin + Result := Right - Left; +end; + +procedure TRectHelper.SetWidth(const Value: Integer); +begin + Right := Left + Value; +end; + + + +class function TUtils.SecondsToTime(Seconds: integer; HideSeconds: Boolean): string; +var + h, m, s: integer; +begin + h := Seconds div 3600; + m := Seconds div 60 - h * 60; + s := Seconds - (h * 3600 + m * 60); + if HideSeconds then + begin + Result := SysUtils.Format('%.2d:%.2d', [h, m]); + end + else + begin + Result := SysUtils.Format('%.2d:%.2d:%.2d', [h, m, s]); + end; +end; + +// TODO Interpret env vars in the path +class function TUtils.GetFilePath(Path: string): string; +begin + if AnsiStartsStr('.', Path) then + begin + Result := ExtractFilePath(Application.ExeName) + Path; + end else + Result := Path; +end; + + +{$IFDEF LINUX} +// https://stackoverflow.com/questions/48609416/shellexecute-equivalent-for-linux-as-target-platform +procedure ShlOpen( FileName: String ) ; +var prc: TProcess; +begin + prc:= TProcess.Create ( nil ) ; + prc.CommandLine:= 'xdg-open ' + FileName; + prc.Execute; + prc.free; +end ; +{$ENDIF} + +class procedure TUtils.RunApp(Path: string); +begin +{$IFDEF WINDOWS} + ShellExecute(0, 'open', PChar(GetFilePath(Path)), nil, nil, SW_SHOWNORMAL); +{$ENDIF} + +{$IFDEF LINUX} + try + ShlOpen(Path); + except + On E: Exception do + E.CreateFmt('Failed to run: %s', [Path]); + end; +{$ENDIF} +end; + + +class function TUtils.IsInteger(S: String): boolean; +begin + try + Result := True; + StrToInt(S); + except on E: EConvertError do + Result := False; + end; +end; + + +class function TUtils.GetFormRect(Form: TForm) : TRect; +var r : TRect; +begin +{$IFDEF WINDOWS} + GetWindowRect(Form.Handle, r); + Result:= r; +{$ENDIF} + +{$IFDEF LINUX} + // TODO test this + r.SetWidth(Form.Width); + r.SetHeight(Form.height); + Result:= r; +{$ENDIF} +end; + +class procedure TUtils.SetControlPos(Control: TWinControl; X: Integer; Y: Integer); +begin + // It seems that there is no difference. + //SetWindowPos(Control.Handle, HWND_TOP, X, Y, 0, 0, SWP_SHOWWINDOW or SWP_NOSIZE); + Control.Left:= X; + Control.Top:= Y; +end; + +class function TUtils.GetControlPos(Control: TWinControl) : TPoint; +var r : TRect; + p : TPoint; +begin + //GetWindowRect(Control.Handle, r); + //Result.X:= r.Left; + //Result.Y:= r.Top; + // No difference + p.X:= 0; + p.Y:= 0; + Result:= Control.ClientToScreen(p); +end; + +// https://wiki.freepascal.org/Play_Sound_Multiplatform +// Modified +{$IFDEF LINUX} +procedure PlaySound(const szSoundFilename: string); +var + szNonWindowsPlayCommand: string; + SoundPlayerAsyncProcess: Tasyncprocess; +begin + szNonWindowsPlayCommand := ''; + // How to play in Linux? Use generic Linux commands + // Use asyncprocess to play sound as SND_ASYNC + // Try play + if (FindDefaultExecutablePath('play') <> '') then + szNonWindowsPlayCommand := 'play'; + // Try aplay + if (szNonWindowsPlayCommand = '') then + if (FindDefaultExecutablePath('aplay') <> '') then + szNonWindowsPlayCommand := 'aplay -q '; + // Try paplay + if (szNonWindowsPlayCommand = '') then + if (FindDefaultExecutablePath('paplay') <> '') then + szNonWindowsPlayCommand := 'paplay'; + // Try mplayer + if (szNonWindowsPlayCommand = '') then + if (FindDefaultExecutablePath('mplayer') <> '') then + szNonWindowsPlayCommand := 'mplayer -really-quiet '; + // Try CMus + if (szNonWindowsPlayCommand = '') then + if (FindDefaultExecutablePath('CMus') <> '') then + szNonWindowsPlayCommand := 'CMus '; + // Try pacat + if (szNonWindowsPlayCommand = '') then + if (FindDefaultExecutablePath('pacat') <> '') then + szNonWindowsPlayCommand := 'pacat -p '; + // Try ffplay + if (szNonWindowsPlayCommand = '') then + if (FindDefaultExecutablePath('ffplay') <> '') then + szNonWindowsPlayCommand := 'ffplay -autoexit -nodisp '; + // Try cvlc + if (szNonWindowsPlayCommand = '') then + if (FindDefaultExecutablePath('cvlc') <> '') then + szNonWindowsPlayCommand := 'cvlc -q --play-and-exit '; + // Try canberra-gtk-play + if (szNonWindowsPlayCommand = '') then + if (FindDefaultExecutablePath('canberra-gtk-play') <> '') then + szNonWindowsPlayCommand := 'canberra-gtk-play -c never -f '; + // Try Macintosh command? + if (szNonWindowsPlayCommand = '') then + if (FindDefaultExecutablePath('afplay') <> '') then + szNonWindowsPlayCommand := 'afplay'; + // proceed if we managed to find a valid command + if (szNonWindowsPlayCommand <> '') then + begin + SoundPlayerAsyncProcess := Tasyncprocess.Create(nil); + //SoundPlayerAsyncProcess.CurrentDirectory := ExtractFileDir(szSoundFilename); + SoundPlayerAsyncProcess.Executable := + FindDefaultExecutablePath(Copy2Space(szNonWindowsPlayCommand)); + SoundPlayerAsyncProcess.Parameters.Clear; + SoundPlayerAsyncProcess.Parameters.Add(szSoundFilename); + try + SoundPlayerAsyncProcess.Execute; + except + On E: Exception do + E.CreateFmt('Playstyle=paASync: Unable to Play %s Message:%s', [szSoundFilename, E.Message]); + end; + //FreeAndNil(SoundPlayerAsyncProcess); + end + else + raise Exception.CreateFmt('The play command %s does not work on your system', + [szNonWindowsPlayCommand]); +end; +{$ENDIF} + + +class procedure TUtils.PlayAudio(Path: string; Loop: boolean); +begin +{$IFDEF WINDOWS} + if Loop then + sndPlaySound(PChar(GetFilePath(Path)), SND_NODEFAULT or SND_ASYNC or SND_LOOP) + else + sndPlaySound(PChar(GetFilePath(Path)), SND_NODEFAULT or SND_ASYNC); +{$ENDIF} + +{$IFDEF LINUX} + // TODO Loop + PlaySound(Path); +{$ENDIF} +end; + +class procedure TUtils.StopAudio; +begin +{$IFDEF WINDOWS} + sndPlaySound(nil, 0); +{$ENDIF} + +{$IFDEF LINUX} + // TODO +{$ENDIF} +end; + + +end. + diff --git a/msgbox.lfm b/msgbox.lfm new file mode 100644 index 0000000..77f6133 --- /dev/null +++ b/msgbox.lfm @@ -0,0 +1,624 @@ +object MsgBoxForm: TMsgBoxForm + Left = 819 + Height = 136 + Top = 314 + Width = 162 + BorderStyle = bsDialog + Caption = 'Done' + ClientHeight = 136 + ClientWidth = 162 + FormStyle = fsSystemStayOnTop + Icon.Data = { + 662500000000010004002020000001001800A80C000046000000101000000100 + 180068030000EE0C00002020000001002000A810000056100000101000000100 + 200068040000FE2000002800000020000000400000000100180000000000000C + 0000640000006400000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000B1864DB2782BB27019B2 + 7019B4711CB27019B1711DB2782BB1864D000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000B39C7EB1711DB77521C48032CC883CD18D42D1 + 8D42D18D42D18D42D18D42CC883CC48032B77521B1711DB39C7E000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000B1762ABA7724CC883CD59149DC9B4DDD9C4EE2A251E2 + A251E2A251E2A251E2A251DD9C4EDB9B4DD59149CC883CBA7724B1762A000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000B27019C68436D59149DD9C4EE1A75AE3CEA3E7EEE0E9FFFFE9 + FFFFE9FFFFE9FFFFE9FFFFE7EEE0E3CEA3E1A75ADD9C4ED59149C68436B27019 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000B4711CD29149D9974EE09E4DE2D3B0E5FFFFE5FFFFE5FFFFE5FFFFE5 + FFFFE9FFFFE5FFFFE5FFFFE5FFFFE5FFFFE5FFFFE2D3B0E09E4DD9974ED29149 + B4711C0000000000000000000000000000000000000000000000000000000000 + 00B27019D29149DB9A51DEA155E2F3ECE5FFFFE5FFFFE5FFFFE1FEFEE5FFFFE5 + FFFF99A2A1E5FFFFE5FFFFE1FEFEE5FFFFE5FFFFE5FFFFE2F3ECDEA155DB9A51 + D29149B27019000000000000000000000000000000000000000000000000B176 + 2AC9883CDC9D51DEA155E1FEFEE1FEFEE1FEFE949D9CE1FEFEDDFAFCE1FEFEE5 + FFFF99A2A1E5FFFFE1FEFEDDFAFCE1FEFE949D9CE1FEFEE1FEFEE1FEFEDEA155 + DC9D51C9883CB2782B000000000000000000000000000000000000BDA587BC7A + 29DC9C59DD9949DEF1EBDDFDFEDDFDFEDDFDFEE1FEFEE1FEFEDDFAFCDDFAFCE1 + FEFE949D9CE5FFFFDDFAFCDDFAFBDDFDFEE1FEFEDDFDFEDDFDFEDDFDFEDEF1EB + DD9949DC9C59BC7A29BDA587000000000000000000000000000000B1711DD393 + 4DDC9D51DCCFABDDFDFEDDFDFEDDFAFCD9F9FCD9F8FBD9F8FBD9F8FBD9F9FCDD + FAFCDDFDFEDDFAFCD9F8FBD9F8FBD9F8FBD9F9FCD9F8FBDDFAFCDDFDFEDAFDFF + DCCFABDC9D51D3934DB1711D000000000000000000000000000000B97825E0A1 + 5EDC9D51DAFDFFDAFDFF8E9798DAFDFFD8F7FAD8F7FAD9F8FBD9F8FBD9F8FBD7 + F8FBD9F8FBD8F7FAD8F7FAD8F7FAD8F7FAD8F7FAD8F7FADAFDFF8E9798DAFDFF + DAFDFFDC9D51E0A15EB97825000000000000000000000000B78C53CD8D44DF9E + 55D8C59CD6FEFFD6F9FDD9F9FCD7F8FBD5F6F9D5F6F9D9F9FCDAFDFFDDFDFEDA + FDFFD8F7FAD5F6F9D5F6F9D5F6F9D8F7FAD5F6F9D5F6F9D7F8FBD9F9FCD6F9FD + D6FEFFD8C59CDF9E55CD8D44B78C53000000000000000000B2782BD99E5ADD99 + 49D5E4D8D2F9FED5F6F9D5F6F9D5F6F9D2F4F8D5F6F9DAFDFF858D8E828A8BDD + FDFED6F9FDD5F6F9D2F4F8D2F4F8D2F4F8D5F6F9D5F6F9D5F6F9D2F4F8D5F6F9 + D2F9FED5E4D8DD9949D99E5AB2782B000000000000000000B16F18E7AC6FDA94 + 41D0FDFFD2F9FED2F4F8D1F6FCD2F4F8D2F4F8D2F4F8D6FEFF8991904F47457D + 898ADDFDFED6F9FDD5F6F9D2F4F8D2F4F8D2F4F8D2F4F8D2F4F8D2F4F8D2F4F8 + D1F6FCD0FDFFDA9441E7AC6FB16F18000000000000000000B16F18E8AE72D991 + 3DCFFCFFCFF5FCD1F6FCD6F9FDD1F6FCD2F4F8CEF3F8D1F6FCD6FEFF858D8E43 + 3D3B748080DAFDFFD1F6FCCEF3F8CEF3F8CEF3F8D2F4F8D1F6FCD2F9FED2F9FE + CFF5FCCDFAFEDA9441E8AE72B06D16000000000000000000B06D16E9B076D991 + 3DCDFAFECFF5FC849092859394839091CFF5FCCDF1F6CEF3F8D1F6FCDAFDFF81 + 8D8E3731316E787AD2F9FECEF3F8CDF1F6CDF1F6CDF5FA839091859394839091 + D1F6FCCAF9FFD9913DE9B076B06D16000000000000000000B06D16EBB279D68D + 3AD0FDFFCAF4F9CDF5FACFF5FCCDF5FAC9F2F9C8F0F5C9F2F9CDF5FAD6FEFF7A + 86883C3434707B7DD2F9FEC8F0F5C8F0F5C8F0F5C9F2F9CDF5FACDF5FACDF5FA + CAF4F9D0FDFFD68D3AEBB279B06D16000000000000000000B06D16EDB77ED68D + 3ACFFCFFC6F1F7C8F0F5C8F0F5C8F0F5C8F0F5C8F0F5CAF4F9D0FDFF78848541 + 3838788485D0FDFFCAF4F9C8F0F5C8F0F5C8F0F5C8F0F5C8F0F5C8F0F5C8F0F5 + C6F1F7CFFCFFD68D3AEDB77EB06D16000000000000000000B5792CE4AB6DDA93 + 44CFFCFFC4EFF8C5EDF4C5EDF4C5EDF4C8F0F5C9F2F9CFFCFF7A8688483F3D7A + 8688D0FDFFC9F2F9C8F0F5C5EDF4C5EDF4C5EDF4C5EDF4C5EDF4C5EDF4C5EDF4 + C5F1F8CFFCFFDA9344E4AB6DB5792C000000000000000000C0955CD49954E19E + 58D2D5C4BEF2FDC4EFF8C3F0F7C4EFF8C5F1F8CAF9FF7D898A4E46437D898ACD + FAFEC5F1F8C1EDF5C2ECF3C2ECF3C5EDF4C2ECF3C2ECF3C3F0F7C3F0F7C3F0F7 + C1F0F9D2D5C4E19E58D49954C0955C000000000000000000000000BC7A29F0B5 + 7ACFB082C4F0FFC3F0F7758385C5F1F8CAF9FF818D8E554C4A818D8ECAF9FFC3 + F0F7C1EDF5C0EBF2C2ECF3C0EBF2C0EBF2C0EBF2C0EBF2C3F0F7758385C3F0F7 + C4F0FFCFB082F0B57ABC7A29000000000000000000000000000000B1711DE4AB + 6DE09B51C4D9D8BFECF9C1F0F9C1F0F98390915C524F849092C5F7FFC3F0F7BE + ECF3C1EDF5BEECF3BCEAF1BCEAF1BCEAF1BCEAF1BEECF3BEECF3BEEDF6BFECF9 + C4D9D8E09B51E4AB6DB1711D000000000000000000000000000000000000C181 + 33F2BA82D19B5AB9E4FABBECF5C1F0F9839091859394C5F7FFBEEDF6BEECF3BF + ECF9728386BFECF9BCEAF1BCEAF1BEECF3BEEDF6BEECF3BBECF5BBECF5B9E4FA + D19B5AF2BA82C18133000000000000000000000000000000000000000000B579 + 2CD99E5AEAAD6CC6A67AB0DEF5B8E7F4BEF2FD718588BEEDF6BAEAF4B9E8F1BE + EDF6718588BEEDF6B8E7F4B7E8F1BAEAF46D7E81BBECF5B6E4F1B0DEF5C6A67A + EDB071D99E5AB5792C0000000000000000000000000000000000000000000000 + 00AF6C14EEB880EAAD6CC59E6AACD3E6AEDDF0B7E8F5BAEAF4B7E8F1B7E8F1BB + ECF56E8082BBECF5B7E8F1B7E8F1BAEAF4B6E7F4AEDDF0ACD3E6C59E6AEAAD6C + EEB880AF6C140000000000000000000000000000000000000000000000000000 + 00000000B4711CF2BA82EDB071CF914CB5B6A7A2D2EEA6D3E9AADAEAAFE0EEB2 + E4F0B6E4F1B2E4F0AFE0EEAADAEAA6D3E9A2D2EEB5B6A7CF914CF0B57AEEB880 + B4711C0000000000000000000000000000000000000000000000000000000000 + 00000000000000AF6C14DCA362F9C692E39F57CA8B44B2AE99A4BFC899CDEC9A + CCEB9ACCEB9ACCEB99CDECA4BFC8B2AE99CA8B44E39F57F9C692DBA362AF6C13 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000B5792CC38437EEB880FCC996E6A561DA9142D0822CD0 + 822CD0822CD0822CD0822CDA9142E6A561FCC996EEB880C38437B5792C000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000B1711DBE7F2EDEA767F2C18DFFD5A8FF + D5A8FFD5A8FFD5A8FFD5A8F2C18DDEA767BE7F2EB1711D000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000C79B61B87C2FAF6B13AF + 6B13AF6B13AF6B13AF6B13B87C2FC79B61000000000000000000000000000000 + 000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFF0 + 07FFFF8000FFFF00007FFE00003FFC00001FF800000FF0000007E0000003E000 + 0003E0000003C0000001C0000001C0000001C0000001C0000001C0000001C000 + 0001C0000001C0000001E0000003E0000003F0000007F0000007F800000FFC00 + 001FFE00003FFF00007FFFC001FFFFF007FF2800000010000000200000000100 + 1800000000000003000064000000640000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000000000A2937E96 + 816596816599856C000000000000000000000000000000000000000000000000 + 000000000000A38660C27F2FD18F42D99749D99749D79547C9883AB47E3D0000 + 00000000000000000000000000000000000000AD7E45D79547E1C595E4EEE0E7 + FFFFE7FFFFE6FAF7E3DCBEDDA765C88639000000000000000000000000000000 + A77E4AD9994FE0E4D0CFE6E6E1FCFDE7FFFFBFD0D0E1FCFDCFE6E6E1FCFADEB6 + 7EC9883A000000000000000000000000D19147DCD6B7DCFCFEDCFAFCDBF9FBDC + FAFCCBE4E6DCFAFADCFAFCDCFAFCDCFAFADCA868B98443000000000000B88B52 + DCA868D6FAFDC5E0E3D7F6F9D9F9FCD9F9FCD9F9FCD7F6F9D7F6F9D9F9FCC5E1 + E4D8D6BBD19147000000000000C88A41D6C398D1F5F8D1F5F8D1F5F8AFC5C789 + 9595D6FAFDD1F5F8D1F5F8D1F5F8D1F5F8D2F4F4DD9D56A7967F000000CC8E45 + D2C59DBCDCE1ABC4C7CEF3F8D1F5F88995957C8A8ACDF5FACDF1F6BDDBE0ABC4 + C7CDF8FDE0A059A4927A000000CE9149D2C59DC9F2F8C9F2F8C9F1F6CDF5FA82 + 91927D8C8DC9F2F8C8EFF4C9F1F6C9F2F8CBF7FBE0A059A4927A000000C7904E + D7C097C3EDF5C4EDF5C7F2F9859495829192C7F2F9C2ECF3C2ECF3C4EDF5C4ED + F5C9EBEDDD9D56000000000000B49976E0AB6EC2E9F2AED5DB89999A87989AC2 + F1F8BFECF3BEEAF1BEEAF1BFECF3ADD3DBCDC5AACE9149000000000000000000 + CF934ECEB48EB9E8F68EA6AABEEEF7BCEBF497B8BEBAE8F2A8D0D7BAE8F2BAD4 + D7E2A869B69B78000000000000000000000000DFA463CBAC83AFD3DEAFE0EEB4 + E6F1A3CDD6B1E2EEADDDEFB7BDB2E3AE74C7985D000000000000000000000000 + 000000000000D29854E5AA6CC5A881B5A78CB5A78BB9A789D7A975E2A869C095 + 5E000000000000000000000000000000000000000000000000B99E7ACF9B5BD7 + A05DD7A05DD49D5BCC9E64000000000000000000000000000000FFFF0000FC3F + 0000F00F0000E00700B2C003D291C0019A51800155E28000E5FF8000FFFF8000 + FFE18001E5FF8001FFFFC001A1E5E003E5FFF007FEFEF81FFFE5280000002000 + 0000400000000100200000000000001000006400000064000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000001000000070000000E00000013000000160000 + 0016000000160000001600000016000000130000000E00000007000000010000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000002000000090000001500000024000000320000003C000000410000 + 00430000004300000043000000410000003C0000003200000024000000150000 + 0009000000020000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000600000014000000280000003C6741107C996117C3AA6B19EAB2701AFFB270 + 19FFB27019FFB27019FFB2701AFFAA6B19EA996117C36741107C0000003C0000 + 0028000000140000000600000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000001000000070000 + 001C000000377349128AB06F1AF9B77521FFC48032FFCB883BFFD28D43FFD18D + 42FFD18D42FFD18D42FFD28D43FFCB883BFFC48032FFB77521FFB06F1AF97349 + 128A000000370000001C00000007000000010000000000000000000000000000 + 00000000000000000000000000000000000000000001000000080000001F1910 + 0446AB6C19EDBA7724FFCC883CFFD59048FFDB9B4DFFDD9C4EFFE2A352FFE2A2 + 51FFE2A250FFE2A251FFE2A352FFDD9C4EFFDB9B4DFFD59048FFCC883CFFBA77 + 24FFAB6C19ED191004460000001F000000080000000100000000000000000000 + 000000000000000000000000000000000000000000070000001F3D260956B26F + 19FFC68436FFD6934BFFDC9B4DFFE1A75AFFE3CEA3FFE7EEE0FFE9FFFFFFE9FF + FFFFE9FFFFFFE9FFFFFFE9FFFFFFE7EEE0FFE3CEA3FFE1A75AFFDC9B4DFFD693 + 4BFFC68436FFB26F19FF3D2609560000001F0000000700000000000000000000 + 0000000000000000000000000000000000060000001C3C260953B4711CFFD18F + 47FFD9974EFFE09E4DFFE2D3B0FFE6FFFFFFE5FFFFFFE4FFFFFFE4FFFFFFE6FF + FFFFE7FFFFFFE6FFFFFFE4FFFFFFE4FFFFFFE5FFFFFFE6FFFFFFE2D3B0FFE09E + 4DFFD9974EFFD18F47FFB4711CFF3C2609530000001C00000006000000000000 + 0000000000000000000000000002000000141E130541B16F18FFD29149FFDB99 + 50FFDFA256FFE2F3ECFFE4FFFFFFE5FFFFFFE3FFFFFFE2FDFEFFE3FDFEFFE6FF + FFFF99A1A1FFE6FFFFFFE3FDFEFFE2FDFEFFE3FFFFFFE5FFFFFFE4FFFFFFE2F3 + ECFFDFA256FFDB9950FFD29149FFB16F18FF1E13054100000014000000020000 + 000000000000000000000000000900000028AC6C19ECC9883CFFDB9B52FFDEA1 + 54FFE0FFFFFFE0FFFFFFE1FFFFFF959D9CFFE1FEFFFFDFFBFCFFE0FCFDFFE4FF + FFFF99A3A1FFE4FFFFFFE0FCFDFFDFFBFCFFE1FEFFFF959D9CFFE1FFFFFFE0FF + FFFFE0FFFFFFDEA154FFDB9B52FFC9883CFFAC6C19EC00000028000000090000 + 00000000000000000001000000157D4F1381BC7A28FFDC9C59FFDE9A49FFDEF1 + EBFFDEFFFFFFDEFCFDFFDEFCFDFFDFFDFEFFDEFCFDFFDDFAFBFFDEFBFCFFE1FF + FFFF949E9EFFE1FFFFFFDEFBFCFFDDFAFBFFDEFCFDFFDFFDFEFFDEFCFDFFDEFC + FDFFDEFFFFFFDEF1EBFFDE9A49FFDC9C59FFBC7A28FF7D4F1381000000150000 + 0001000000000000000700000024B06E19F9D3934DFFDD9C50FFDCCFABFFDBFF + FFFFDCFCFFFFDBFAFDFFDAF8FCFFDAF8FCFFDAF8FBFFDAF8FBFFDAF8FBFFDCFA + FDFFDDFBFEFFDCFAFDFFDAF8FBFFDAF8FBFFDAF8FBFFDAF8FCFFDAF8FCFFDBFA + FDFFDCFCFFFFDBFFFFFFDCCFABFFDD9C50FFD3934DFFB06E19F9000000240000 + 0007000000000000000E774B136BB97825FFE0A15EFFDC9E52FFD8FAFFFFDAFD + FFFF8E9798FFDAFAFDFFD8F7FAFFD8F7FAFFD8F7FAFFD9F8FBFFD9F8FBFFD8F8 + FBFFD8F8FBFFD8F7FAFFD8F7FAFFD8F7FAFFD8F7FAFFD8F7FAFFD8F7FAFFDAFA + FDFF8E9798FFDAFDFFFFD8FAFFFFDC9E52FFE0A15EFFB97825FF774B136B0000 + 000E00000000000000139E6417BCCD8D44FFDF9E55FFD8C59CFFD6FDFFFFD7F9 + FDFFD8F9FCFFD7F8FBFFD6F6F9FFD6F6F9FFD8F9FCFFDBFDFFFFDCFDFFFFD9FA + FDFFD7F7FAFFD6F6F9FFD6F6F9FFD6F6F9FFD6F6F9FFD6F6F9FFD6F6F9FFD7F8 + FBFFD8F9FCFFD7F9FDFFD6FDFFFFD8C59CFFDF9E55FFCD8D44FF9E6417BC0000 + 00130000000000000016AB6B17E8DA9D5AFFDC984AFFD5E4D8FFD3F9FFFFD3F6 + F9FFD3F5F8FFD3F5F8FFD3F5F8FFD4F6F9FFD8FCFFFF868D8EFF828A8BFFDDFF + FFFFD6FAFDFFD3F6F9FFD3F5F8FFD3F5F8FFD3F5F8FFD3F5F8FFD3F5F8FFD3F5 + F8FFD3F5F8FFD3F6F9FFD3F9FFFFD5E4D8FFDD994BFFDA9D5AFFAB6B17E80000 + 00160000000000000016B16E17FFE7AC6FFFDA9441FFD0FFFFFFD1F7FCFFD2F5 + F9FFD2F5F9FFD2F5F9FFD1F4F8FFD2F5F9FFD6FBFFFF899190FF4F4745FF7C88 + 88FFDDFFFFFFD5F9FDFFD2F5F9FFD1F4F8FFD1F4F8FFD1F4F8FFD1F4F8FFD2F5 + F9FFD2F5F9FFD2F5F9FFD1F7FCFFD0FFFFFFDA9341FFE7AC6FFFB16E17FF0000 + 00160000000000000016B06E16FFE8AE72FFD9923EFFCDFBFFFFCFF5FCFFD2F7 + FCFFD3F8FDFFD2F7FCFFD0F4F9FFCEF3F8FFD1F5FAFFD7FFFFFF848E8EFF433D + 3BFF748080FFDAFFFFFFD1F6FBFFCEF2F7FFCEF2F7FFCEF2F7FFD0F4F9FFD2F7 + FCFFD3F8FDFFD2F7FCFFCFF5FCFFCDFBFFFFD9923EFFE8AE72FFB06E16FF0000 + 00160000000000000016B06D16FFE9B076FFD9903DFFCBFAFFFFCFF6FCFF8390 + 91FF859394FF839091FFCFF4FAFFCCF1F7FFCDF2F7FFD0F6FCFFDAFFFFFF818B + 8DFF373131FF6E787AFFD3FAFFFFCDF2F7FFCCF1F6FFCCF1F6FFCFF4FAFF8390 + 91FF859394FF839091FFCFF6FCFFCBFAFFFFD9903DFFE9B076FFB06D16FF0000 + 00160000000000000016B06D16FFEBB279FFD78E3BFFD0FDFFFFCAF3FAFFCDF5 + FAFFCEF6FBFFCDF5FAFFCAF2F7FFC9F0F5FFC9F1F6FFCDF6FBFFD7FFFFFF7987 + 89FF3C3434FF707B7DFFCFF9FEFFCAF1F6FFC9F0F5FFC9F0F5FFCAF2F7FFCDF5 + FAFFCEF6FBFFCDF5FAFFCAF3FAFFD0FDFFFFD78E3BFFEBB279FFB06D16FF0000 + 00160000000000000013B06D16FFEDB77EFFD68D3AFFCFFCFFFFC6F1F7FFC8F0 + F5FFC8F0F5FFC8F0F5FFC7EFF4FFC8F0F5FFCAF4F9FFD2FDFFFF788485FF4138 + 38FF778385FFD2FEFFFFCAF3F8FFC7EFF4FFC7EFF4FFC7EFF4FFC7EFF4FFC8F0 + F5FFC8F0F5FFC8F0F5FFC6F1F7FFCFFCFFFFD68D3AFFEDB77EFFB06D16FF0000 + 0013000000000000000EAC6B16E6E3AA6CFFDA9344FFD0FBFFFFC4EFF8FFC5ED + F5FFC5EDF5FFC5EDF4FFC6EEF5FFC8F1F9FFCFFBFFFF7B8688FF483F3DFF7A86 + 88FFD0FCFFFFC9F2F9FFC6EEF5FFC5EDF4FFC5EDF4FFC5EDF4FFC5EDF4FFC5ED + F4FFC5EDF5FFC5EDF5FFC4EFF8FFD0FBFFFFDA9344FFE3AA6CFFAC6B16E60000 + 000E0000000000000007A66917B3D49954FFE19E58FFD2D5C4FFC1F0FBFFC3EE + F6FFC4EFF6FFC4EEF6FFC5F1F8FFCBF9FFFF7E8A8BFF4E4643FF7D898BFFCCFA + FFFFC5F1F8FFC2EDF4FFC2ECF3FFC2ECF3FFC2ECF3FFC2ECF3FFC2ECF3FFC3EE + F5FFC4EFF6FFC3EEF6FFC1F0FBFFD2D5C4FFE19E58FFD49954FFA66917B30000 + 00070000000000000001945E1656BC7B2AFFF0B67BFFCFB082FFC4F0FFFFC2F0 + F8FF758385FFC5F1F9FFC8F8FFFF808D8FFF554C4AFF808D8EFFC9F9FFFFC3F0 + F7FFC1EDF4FFC0EBF2FFC0EBF2FFC0EBF2FFC0EBF2FFC0EBF2FFC0EBF3FFC2EE + F5FF758385FFC2F0F8FFC4F0FFFFCFB082FFF0B67BFFBC7B2AFF945E16560000 + 0001000000000000000000000009AF6D16F7E4AB6DFFE09B51FFC4D9D8FFBFEC + F9FFBFEFF7FFC2F2FAFF828E8EFF5C524FFF849092FFC6F7FFFFC0EFF6FFBFED + F4FFC0EEF5FFBFECF3FFBDEAF1FFBDEAF1FFBDEAF1FFBDEBF1FFBDEBF2FFBEEC + F3FFBFEFF6FFBFECF9FFC4D9D8FFE09B51FFE4AB6DFFAF6D16F7000000090000 + 00000000000000000000000000029D621766C18133FFF2BA83FFD19B5AFFB9E4 + FAFFBBEBF6FFC0F1FAFF838F8FFF869394FFC4F7FFFFBEEDF6FFBCEBF3FFBFEE + F7FF728386FFBFEEF7FFBCEAF2FFBBE9F1FFBDEBF3FFBDECF5FFBDEBF3FFBBEB + F4FFBBEAF5FFB9E4FAFFD19B5AFFF2BA82FFC18133FF9D621767000000020000 + 000000000000000000000000000000000006AF6D17E7D99F5BFFEAAD6CFFC6A6 + 7AFFB1DEF5FFB8E7F4FFBEF2FDFF718588FFBDEEF7FFB9E8F2FFB9E8F2FFBDED + F7FF718487FFBDEDF7FFB9E8F2FFB8E8F1FFBBEBF4FF6D7E81FFBBEDF6FFB6E4 + F1FFB0DEF5FFC6A67AFFEDB071FFD99F5BFFAF6D17E700000006000000000000 + 0000000000000000000000000000000000018E5A1527AF6C14FFEEB880FFEBAE + 6DFFC69E6BFFACD3E6FFAFDDF1FFB7E8F5FFB8EBF4FFB7E8F1FFB7E8F1FFBBEC + F5FF6E8082FFBBECF5FFB7E8F1FFB7E8F1FFB8EBF4FFB6E7F4FFAEDDF0FFACD3 + E6FFC59E6AFFEBAE6DFFEEB880FFAF6C14FF6E45111200000000000000000000 + 000000000000000000000000000000000000000000019D621738B4721CFFEFBA + 83FFEDB172FFCF914CFFB5B6A7FFA2D2EEFFA6D3E9FFAADAEAFFAFE0EEFFB2E4 + F0FFB3E5F2FFB2E4F0FFAFE0EEFFAADAEAFFA6D3E9FFA2D2EEFFB5B6A7FFCF91 + 4CFFF0B578FFEFBA82FFB4721CFF8F5A15230000000100000000000000000000 + 0000000000000000000000000000000000000000000000000001935C1522AF6C + 14FFDCA362FFF9C692FFE39F57FFCA8B44FFB2AE99FFA4BFC8FF99CDECFF9ACC + EBFF9ACCEBFF9ACCEBFF99CDECFFA4BFC8FFB2AE99FFCA8B44FFE39F57FFF9C6 + 92FFDBA362FFAF6C13FF945D1623000000010000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000007046 + 1110AF6C16E6C38437FFEDB880FFFCC996FFE6A561FFDA9043FFD0822DFFD182 + 2CFFD1822CFFD1822CFFD0822DFFDA9043FFE6A561FFFCC996FFEDB880FFC384 + 37FFAF6C16E67046111000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000002A769175FAF6D15F7BE7F2EFFDEA767FFF2C18DFFFFD5A9FFFFD5 + A8FFFFD5A8FFFFD5A8FFFFD5A9FFF2C18DFFDEA767FFBE7F2EFFAF6D15F7A769 + 175F000000020000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000001A769184CAC6B16ACAF6C15E2AF6B13FFAF6B + 13FFAF6B13FFAF6B13FFAF6B13FFAF6C15E2AC6B16ACA769184C000000010000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000FFFFFFFFFFC001FFFF00007FFE00003FF800000FF0000007F0000007E000 + 0003C0000001C000000180000000800000008000000080000000800000008000 + 000080000000800000008000000080000000800000008000000080000000C000 + 0001C0000001E0000003E0000007F0000007F800000FFE00003FFF00007FFFC0 + 01FF280000001000000020000000010020000000000000040000640000006400 + 0000000000000000000000000000000000000000000000000000000000000000 + 0002000000080000000B0000000B0000000A0000000500000000000000000000 + 0000000000000000000000000000000000000000000000000002000000121910 + 043C50330C8759380CA059380CA157360C9A4028096500000020000000070000 + 0000000000000000000000000000000000000000000206040122764B13ABC27F + 2FFED18F42FFD9974AFFD99749FFD79547FFCA883AFFAA6D23E0311F07620000 + 000C000000000000000000000000000000020F0902259D6521D5D59347FFE1C5 + 95FFE4EEE0FFE7FFFFFFE7FFFFFFE6FAF7FFE3DCBEFFDDA765FFC88639FF4B2F + 0B720000000A000000000000000000000012915D1CCBD9994FFFE0E4D0FFCFE6 + E6FFE1FDFEFFE3FDFEFFBFD0D0FFE1FCFDFFCFE6E6FFE1FCFAFFDEB67EFFC988 + 3BFF321F075A00000003000000024B2F0B6DD29147FFDCD6B7FFDCFCFEFFDCFA + FCFFDBF9FBFFDDFBFCFFCBE4E6FFDBF9FBFFDCFAFCFFDCFAFCFFDCFAFAFFDCA8 + 67FFAF7228DE0000001000000008A66D24C9DCA868FFD7FBFEFFC5E0E3FFD7F6 + F9FFD9F9FCFFD9F9FCFFD7F7FAFFD7F6F9FFD7F6F9FFD7F7FAFFC5E1E4FFD8D6 + BBFFD19147FF452B0A520000000BC7883DF9D6C398FFD2F6FBFFD2F5F8FFD2F5 + F8FFAFC5C7FF8A9695FFD6FAFCFFD2F4F8FFD2F4F8FFD2F4F8FFD2F5F8FFD2F4 + F4FFDE9D55FF57360B850000000BCC8E45FFD2C59EFFBCDCE1FFABC4C7FFCEF3 + F8FFD1F7FBFF889595FF7C8A8AFFCFF5FAFFCDF1F6FFBDDBE0FFABC4C7FFCDF8 + FDFFE0A058FF58360B8A0000000ACE9048FFD3C59CFFC9F2F8FFCAF2F7FFC8F0 + F5FFCCF6FAFF829091FF7D8C8DFFCAF3F8FFC8EFF4FFC9F1F6FFCAF2F7FFCBF7 + FBFFE1A15BFF58360B8A00000005C2853BE6D7C097FFC3EEF7FFC4EDF5FFC7F2 + F9FF859495FF829293FFC8F3F9FFC3ECF3FFC3ECF3FFC3EDF4FFC4EDF5FFC9EB + EDFFDC9D57FF54350B6C000000007F511595E0AB6EFFC2E9F2FFAED5DBFF8999 + 9AFF87989AFFC2F1F8FFC0ECF3FFBEEAF1FFBEEAF1FFBFECF3FFADD3DBFFCDC5 + AAFFCF924AFD311F0718000000003420071CCE914AF9CEB48EFFB9E8F6FF8EA6 + AAFFBEEEF7FFBCEBF4FF97B8BEFFBAE8F1FFA8D0D7FFBAE9F3FFBAD4D7FFE2A9 + 6AFF83541895000000000000000000000000764A1058DFA463FFCBAC83FFAFD3 + DEFFAFE0EEFFB4E6F1FFA3CDD6FFB1E2EEFFADDDEFFFB7BDB2FFE3AE74FFB87C + 31C83722080500000000000000000000000000000000905A134CD19650F9E5AA + 6CFFC5A881FFB5A78CFFB5A78BFFB9A789FFD7A975FFE3A868FFAA7027BD4A2E + 0B0900000000000000000000000000000000000000000000000053340B188555 + 1691CA8F47E3D7A05DFFD7A05DFFD39B57F8BB7E30BE72470E56000000000000 + 00000000000000000000F81F0000E0070000C003000080010000800000000000 + 00000000FFFF0000FFFF0000FFFF0000F1F10000B7B78000959580019393C001 + 9393E0039393F00F9696 + } + Position = poDesktopCenter + LCLVersion = '2.0.10.0' + object Button1: TButton + Left = 40 + Height = 26 + Top = 88 + Width = 88 + Caption = 'Ok' + OnClick = Button1Click + TabOrder = 0 + end + object Label1: TLabel + Left = 72 + Height = 15 + Top = 41 + Width = 53 + Caption = 'Time''s Up' + ParentColor = False + end + object Image1: TImage + Left = 24 + Height = 32 + Top = 33 + Width = 32 + Picture.Data = { + 055449636F6E662300000000010004002020000001000800A808000046000000 + 101000000100080068050000EE0800002020000001002000A8100000560E0000 + 101000000100200068040000FE1E000028000000200000004000000001000800 + 0000000000000000000000000000000000000000000000000000000037313100 + 3C34340041383800433D3B00483F3D004E4643004F474500554C4A005C524F00 + 6E787A00707B7D00AF6B1300AF6C1300AF6C1400B06D1600B16F1800B2701900 + B1711D00B4711C00B7752100BA772400B9782500B1762A00B2782B00B5792C00 + BC7A2900B87C2F00BE7F2E00D0822C00C1813300C4803200C3843700C6843600 + CB883B00C9883C00CC883C00D68D3A00D9913D00B1864D00B78C5300B39C7E00 + CA8B4400CD8D4400D18D4200D18F4700CF914C00DA914200DA944100DA934400 + D2914900D5914900D3934D00D9974E00DD994900DB9B4D00DC9B4D00DD9C4E00 + C0955C00D4995400DB9A5100DC9D5100DF9E5500D19B5A00D99E5A00DC9C5900 + E09E4D00E09B5100E39F5700E19E5800DEA15500E2A25100E1A75A00E0A15E00 + C79B6100C59E6A00DBA36200DCA36200DEA76700C6A67A00E6A56100E3AA6C00 + E4AB6D00E7AC6F00EAAD6C00E8AE7200EDB07100E9B07600EBB27900EDB77E00 + F0B57A006D7E81006E8082007480800072838600758385007184870078848500 + 718588007A8688007D898A00828A8B00818B8D00818D8E00858D8E0083909100 + 8490920085939400899190008E979800949D9C00BDA58700B2AE990099A2A100 + B5B6A700CFB08200EEB88000F2BA8200D8C59C00F2C18D00F9C69200FCC99600 + DCCFAB00E3CEA300FFD5A800E2D3B000A4BFC8009ACCEB0099CDEC00ACD3E600 + A6D3E900A2D2EE00AADAEA00AEDDF000B0DEF500AFE0EE00B2E4F000B6E4F100 + B6E7F400B8E7F400B7E8F100B7E8F500B9E8F100BCEAF100BEECF300BAEAF400 + BBECF500BEEDF600B9E4FA00BFECF900BEF2FD00D2D5C400C4D9D800D5E4D800 + DEF1EB00C0EBF200C2ECF300C1EDF500C5EDF400C4EFF800C3F0F700C6F1F700 + C8F0F500CDF1F600C1F0F900C5F1F800C4F0FF00C5F7FF00C9F2F900CEF3F800 + CAF4F900CDF5FA00CFF5FC00CAF9FF00CDFAFE00CFFCFF00D2F4F800D5F6F900 + D1F6FC00D8F7FA00D7F8FB00D2F9FE00D6F9FD00D0FDFF00D6FEFF00D9F8FB00 + DDFAFB00D9F9FC00DDFAFC00DAFDFF00DDFDFE00E7EEE000E2F3EC00E1FEFE00 + E5FFFF00E9FFFF0090006200B0007800CF008E00F000A400FF11B300FF31BE00 + FF51C700FF71D100FF91DC00FFB1E500FFD1F000FFFFFF00000000002C002F00 + 4B0050006900700087009000A500B000C400CF00E100F000F011FF00F231FF00 + F451FF00F671FF00F791FF00F9B1FF00FBD1FF00FFFFFF00000000001B002F00 + 2D0050003F007000520090006300B0007600CF008800F0009911FF00A631FF00 + B451FF00C271FF00CF91FF00DCB1FF00EBD1FF00FFFFFF000000000008002F00 + 0E005000150070001B0090002100B0002600CF002C00F0003E11FF005831FF00 + 7151FF008C71FF00A691FF00BFB1FF00DAD1FF00FFFFFF000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000027181111131112182700000000000000000000000000000000000000 + 002912141F242C2C2C2C2C241F14122900000000000000000000000000000000 + 1715243338394747474747393733241517000000000000000000000000000011 + 213339487BBFC3C3C3C3C3BF7B48393321110000000000000000000000001332 + 35427DC2C2C2C2C2C3C2C2C2C2C27D423532130000000000000000000011323C + 46C0C2C2C2C1C2C271C2C2C1C2C2C2C0463C3211000000000000000017233D46 + C1C1C16EC1BCC1C271C2C1BCC16EC1C1C1463D23180000000000006F1A41369A + BEBEBEC1C1BCBCC16EC2BCBABEC1BEBEBE9A36411A6F000000000012343D7ABE + BEBCBBB9B9B9BBBCBEBCB9B9B9BBB9BCBEBD7A3D3412000000000016493DBDBD + 6DBDB3B3B9B9B9B4B9B3B3B3B3B3B3BD6DBDBD3D491600000000282B3E76B8B6 + BBB4B1B1BBBDBEBDB3B1B1B1B3B1B1B4BBB6B8763E2B2800000018403699B5B1 + B1B1B0B1BD6865BEB6B1B0B0B0B1B1B1B0B1B599364018000000105330B7B5B0 + B2B0B0B0B86C0764BEB6B1B0B0B0B0B0B0B0B2B7305310000000105526AFACB2 + B6B2B0A9B2B868045DBDB2A9A9A9B0B2B5B5ACAE30550F0000000F5726AEAC6A + 6B69ACA3A9B2BD67010AB5A9A3A3AB696B69B2AD26570F0000000F5825B7AAAB + ACABA8A2A8ABB863020BB5A2A2A2A8ABABABAAB725580F0000000F5925AFA1A2 + A2A2A2A2AAB7610361B7AAA2A2A2A2A2A2A2A1AF25590F000000195231AF9F9E + 9E9EA2A8AF630563B7A8A29E9E9E9E9E9E9EA5AF3152190000003A3B4597969F + A09FA5AD640664AEA59D9C9C9E9C9CA0A0A0A497453B3A000000001A5A73A6A0 + 5FA5AD670867ADA09D9B9C9B9B9B9BA05FA0A6735A1A00000000001252439895 + A4A469096AA7A0909D908F8F8F8F90909395984352120000000000001E753F94 + 92A4696BA79390955E958F8F9093909292943F751E000000000000001940544F + 868B966293918E9362938B8C915B9289864F56401900000000000000000E7454 + 4B81858D918C8C925C928C8C918A85814B54740E000000000000000000001375 + 562E728382848788898887848283722E5A74130000000000000000000000000E + 4D78442A707E807F7F7F807E702A44784C0D0000000000000000000000000000 + 19207479502F1D1D1D1D1D2F5079742019000000000000000000000000000000 + 0000121C4E777C7C7C7C7C774E1C120000000000000000000000000000000000 + 000000004A1B0C0C0C0C0C1B4A0000000000000000000000FFFFFFFFFFFFFFFF + FFFFFFFFFFF007FFFF8000FFFF00007FFE00003FFC00001FF800000FF0000007 + E0000003E0000003E0000003C0000001C0000001C0000001C0000001C0000001 + C0000001C0000001C0000001C0000001E0000003E0000003F0000007F0000007 + F800000FFC00001FFE00003FFF00007FFFC001FFFFF007FF2800000010000000 + 2000000001000800000000000000000000000000000000000000000000000000 + 00000000B47E3D00C27F2F00AD7E4500A77E4A00C8863900C9883A00B9844300 + B88B52009681650099856C00A3866000A4927A00A2937E00A7967F00B4997600 + B69B7800B99E7A00C88A4100CC8E4500D18F4200C7904E00CE914900CF934E00 + D1914700D5934700D7954700D9974900D9994F00C0955E00C7985D00CF9B5B00 + D2985400DD9D5600D49D5B00D7A05D00E0A05900CC9E6400DFA46300DDA76500 + DCA86700DCA86800D7A97500DEB67E00E2A86900E0AB6E00E5AA6C00E3AE7400 + 7C8A8A007D8C8D0082919200859495008995950087989A0089999A00B5A78B00 + B5A78C00B9A789008EA6AA0097B8BE00B7BDB200C5A88100CBAC8300CEB48E00 + D7C09700D6C39800D2C59D00E1C59500CDC5AA00DCD6B700D8D6BB00E3DCBE00 + ABC4C700AFC5C700A3CDD600A8D0D700ADD3DB00AED5DB00AFD3DE00BFD0D000 + BAD4D700ADDDEF00BDDBE000BCDCE100AFE0EE00B1E2EE00B4E6F100BAE8F200 + BEEAF100BFECF300B9E8F600BCEBF400BEEEF700E0E4D000C5E0E300C5E1E400 + CBE4E600CFE6E600C9EBED00C2E9F200C2ECF300C3EDF500C4EDF500C8EFF400 + C9F1F600CDF1F600C2F1F800C7F2F900C9F2F800CEF3F800CBF7FB00CDF5FA00 + CDF8FD00D2F4F400D1F5F800D7F6F900D6FAFD00DBF9FB00DCFAFA00D9F9FC00 + DCFAFC00DCFCFE00E4EEE000E6FAF700E1FCFA00E1FCFD00E7FFFF00FFFFFF00 + 000000002F26000050410000705B000090740000B08E0000CFA90000F0C30000 + FFD21100FFD83100FFDD5100FFE47100FFEA9100FFF0B100FFF6D100FFFFFF00 + 000000002F1400005022000070300000903E0000B04D0000CF5B0000F0690000 + FF791100FF8A3100FF9D5100FFAF7100FFC19100FFD2B100FFE5D100FFFFFF00 + 000000002F030000500400007006000090090000B00A0000CF0C0000F00E0000 + FF201200FF3E3100FF5C5100FF7A7100FF979100FFB6B100FFD4D100FFFFFF00 + 000000002F000E00500017007000210090002B00B0003600CF004000F0004900 + FF115A00FF317000FF518600FF719C00FF91B200FFB1C800FFD1DF00FFFFFF00 + 000000002F0020005000360070004C0090006200B0007800CF008E00F000A400 + FF11B300FF31BE00FF51C700FF71D100FF91DC00FFB1E500FFD1F000FFFFFF00 + 000000002C002F004B0050006900700087009000A500B000C400CF00E100F000 + F011FF00F231FF00F451FF00F671FF00F791FF00F9B1FF00FBD1FF00FFFFFF00 + 000000001B002F002D0050003F007000520090006300B0007600CF008800F000 + 9911FF00A631FF00B451FF00C271FF00CF91FF00DCB1FF00EBD1FF00FFFFFF00 + 0000000008002F000E005000150070001B0090002100B0002600CF002C00F000 + 3E11FF005831FF007151FF008C71FF00A691FF00BFB1FF00DAD1FF00FFFFFF00 + 000000000000000000000000000000000000000000000D09090A000000000000 + 000000000B02141B1B1A060100000000000000031A437A7E7E7B472705000000 + 0000041C5D617D7E4F7D617C2B06000000001845797875786076787876290700 + 000829745E737777777373775F4618000012417272724934747272727271210E + 00134253486D7234306F69524870240C0016426C6C686F32316C67686C6E240C + 00154065666B33326B64646666622100000F2D634D36356A595858594C441600 + 0000173F5A3A5C5B3B574B57502C1000000000263E4E54564A55513C2F1E0000 + 00000000202E3D3837392A2C1D0000000000000000111F232322250000000000 + FFFF0000FC3F0000F00F0000E0070000C0030000C00100008001000080000000 + 80000000800000008001000080010000C0010000E0030000F0070000F81F0000 + 2800000020000000400000000100200000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000001000000070000000E00000013 + 0000001600000016000000160000001600000016000000130000000E00000007 + 0000000100000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000002000000090000001500000024000000320000003C + 00000041000000430000004300000043000000410000003C0000003200000024 + 0000001500000009000000020000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000600000014000000280000003C6741107C996117C3AA6B19EA + B2701AFFB27019FFB27019FFB27019FFB2701AFFAA6B19EA996117C36741107C + 0000003C00000028000000140000000600000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000001 + 000000070000001C000000377349128AB06F1AF9B77521FFC48032FFCB883BFF + D28D43FFD18D42FFD18D42FFD18D42FFD28D43FFCB883BFFC48032FFB77521FF + B06F1AF97349128A000000370000001C00000007000000010000000000000000 + 0000000000000000000000000000000000000000000000000000000100000008 + 0000001F19100446AB6C19EDBA7724FFCC883CFFD59048FFDB9B4DFFDD9C4EFF + E2A352FFE2A251FFE2A250FFE2A251FFE2A352FFDD9C4EFFDB9B4DFFD59048FF + CC883CFFBA7724FFAB6C19ED191004460000001F000000080000000100000000 + 000000000000000000000000000000000000000000000000000000070000001F + 3D260956B26F19FFC68436FFD6934BFFDC9B4DFFE1A75AFFE3CEA3FFE7EEE0FF + E9FFFFFFE9FFFFFFE9FFFFFFE9FFFFFFE9FFFFFFE7EEE0FFE3CEA3FFE1A75AFF + DC9B4DFFD6934BFFC68436FFB26F19FF3D2609560000001F0000000700000000 + 0000000000000000000000000000000000000000000000060000001C3C260953 + B4711CFFD18F47FFD9974EFFE09E4DFFE2D3B0FFE6FFFFFFE5FFFFFFE4FFFFFF + E4FFFFFFE6FFFFFFE7FFFFFFE6FFFFFFE4FFFFFFE4FFFFFFE5FFFFFFE6FFFFFF + E2D3B0FFE09E4DFFD9974EFFD18F47FFB4711CFF3C2609530000001C00000006 + 0000000000000000000000000000000000000002000000141E130541B16F18FF + D29149FFDB9950FFDFA256FFE2F3ECFFE4FFFFFFE5FFFFFFE3FFFFFFE2FDFEFF + E3FDFEFFE6FFFFFF99A1A1FFE6FFFFFFE3FDFEFFE2FDFEFFE3FFFFFFE5FFFFFF + E4FFFFFFE2F3ECFFDFA256FFDB9950FFD29149FFB16F18FF1E13054100000014 + 000000020000000000000000000000000000000900000028AC6C19ECC9883CFF + DB9B52FFDEA154FFE0FFFFFFE0FFFFFFE1FFFFFF959D9CFFE1FEFFFFDFFBFCFF + E0FCFDFFE4FFFFFF99A3A1FFE4FFFFFFE0FCFDFFDFFBFCFFE1FEFFFF959D9CFF + E1FFFFFFE0FFFFFFE0FFFFFFDEA154FFDB9B52FFC9883CFFAC6C19EC00000028 + 00000009000000000000000000000001000000157D4F1381BC7A28FFDC9C59FF + DE9A49FFDEF1EBFFDEFFFFFFDEFCFDFFDEFCFDFFDFFDFEFFDEFCFDFFDDFAFBFF + DEFBFCFFE1FFFFFF949E9EFFE1FFFFFFDEFBFCFFDDFAFBFFDEFCFDFFDFFDFEFF + DEFCFDFFDEFCFDFFDEFFFFFFDEF1EBFFDE9A49FFDC9C59FFBC7A28FF7D4F1381 + 0000001500000001000000000000000700000024B06E19F9D3934DFFDD9C50FF + DCCFABFFDBFFFFFFDCFCFFFFDBFAFDFFDAF8FCFFDAF8FCFFDAF8FBFFDAF8FBFF + DAF8FBFFDCFAFDFFDDFBFEFFDCFAFDFFDAF8FBFFDAF8FBFFDAF8FBFFDAF8FCFF + DAF8FCFFDBFAFDFFDCFCFFFFDBFFFFFFDCCFABFFDD9C50FFD3934DFFB06E19F9 + 0000002400000007000000000000000E774B136BB97825FFE0A15EFFDC9E52FF + D8FAFFFFDAFDFFFF8E9798FFDAFAFDFFD8F7FAFFD8F7FAFFD8F7FAFFD9F8FBFF + D9F8FBFFD8F8FBFFD8F8FBFFD8F7FAFFD8F7FAFFD8F7FAFFD8F7FAFFD8F7FAFF + D8F7FAFFDAFAFDFF8E9798FFDAFDFFFFD8FAFFFFDC9E52FFE0A15EFFB97825FF + 774B136B0000000E00000000000000139E6417BCCD8D44FFDF9E55FFD8C59CFF + D6FDFFFFD7F9FDFFD8F9FCFFD7F8FBFFD6F6F9FFD6F6F9FFD8F9FCFFDBFDFFFF + DCFDFFFFD9FAFDFFD7F7FAFFD6F6F9FFD6F6F9FFD6F6F9FFD6F6F9FFD6F6F9FF + D6F6F9FFD7F8FBFFD8F9FCFFD7F9FDFFD6FDFFFFD8C59CFFDF9E55FFCD8D44FF + 9E6417BC000000130000000000000016AB6B17E8DA9D5AFFDC984AFFD5E4D8FF + D3F9FFFFD3F6F9FFD3F5F8FFD3F5F8FFD3F5F8FFD4F6F9FFD8FCFFFF868D8EFF + 828A8BFFDDFFFFFFD6FAFDFFD3F6F9FFD3F5F8FFD3F5F8FFD3F5F8FFD3F5F8FF + D3F5F8FFD3F5F8FFD3F5F8FFD3F6F9FFD3F9FFFFD5E4D8FFDD994BFFDA9D5AFF + AB6B17E8000000160000000000000016B16E17FFE7AC6FFFDA9441FFD0FFFFFF + D1F7FCFFD2F5F9FFD2F5F9FFD2F5F9FFD1F4F8FFD2F5F9FFD6FBFFFF899190FF + 4F4745FF7C8888FFDDFFFFFFD5F9FDFFD2F5F9FFD1F4F8FFD1F4F8FFD1F4F8FF + D1F4F8FFD2F5F9FFD2F5F9FFD2F5F9FFD1F7FCFFD0FFFFFFDA9341FFE7AC6FFF + B16E17FF000000160000000000000016B06E16FFE8AE72FFD9923EFFCDFBFFFF + CFF5FCFFD2F7FCFFD3F8FDFFD2F7FCFFD0F4F9FFCEF3F8FFD1F5FAFFD7FFFFFF + 848E8EFF433D3BFF748080FFDAFFFFFFD1F6FBFFCEF2F7FFCEF2F7FFCEF2F7FF + D0F4F9FFD2F7FCFFD3F8FDFFD2F7FCFFCFF5FCFFCDFBFFFFD9923EFFE8AE72FF + B06E16FF000000160000000000000016B06D16FFE9B076FFD9903DFFCBFAFFFF + CFF6FCFF839091FF859394FF839091FFCFF4FAFFCCF1F7FFCDF2F7FFD0F6FCFF + DAFFFFFF818B8DFF373131FF6E787AFFD3FAFFFFCDF2F7FFCCF1F6FFCCF1F6FF + CFF4FAFF839091FF859394FF839091FFCFF6FCFFCBFAFFFFD9903DFFE9B076FF + B06D16FF000000160000000000000016B06D16FFEBB279FFD78E3BFFD0FDFFFF + CAF3FAFFCDF5FAFFCEF6FBFFCDF5FAFFCAF2F7FFC9F0F5FFC9F1F6FFCDF6FBFF + D7FFFFFF798789FF3C3434FF707B7DFFCFF9FEFFCAF1F6FFC9F0F5FFC9F0F5FF + CAF2F7FFCDF5FAFFCEF6FBFFCDF5FAFFCAF3FAFFD0FDFFFFD78E3BFFEBB279FF + B06D16FF000000160000000000000013B06D16FFEDB77EFFD68D3AFFCFFCFFFF + C6F1F7FFC8F0F5FFC8F0F5FFC8F0F5FFC7EFF4FFC8F0F5FFCAF4F9FFD2FDFFFF + 788485FF413838FF778385FFD2FEFFFFCAF3F8FFC7EFF4FFC7EFF4FFC7EFF4FF + C7EFF4FFC8F0F5FFC8F0F5FFC8F0F5FFC6F1F7FFCFFCFFFFD68D3AFFEDB77EFF + B06D16FF00000013000000000000000EAC6B16E6E3AA6CFFDA9344FFD0FBFFFF + C4EFF8FFC5EDF5FFC5EDF5FFC5EDF4FFC6EEF5FFC8F1F9FFCFFBFFFF7B8688FF + 483F3DFF7A8688FFD0FCFFFFC9F2F9FFC6EEF5FFC5EDF4FFC5EDF4FFC5EDF4FF + C5EDF4FFC5EDF4FFC5EDF5FFC5EDF5FFC4EFF8FFD0FBFFFFDA9344FFE3AA6CFF + AC6B16E60000000E0000000000000007A66917B3D49954FFE19E58FFD2D5C4FF + C1F0FBFFC3EEF6FFC4EFF6FFC4EEF6FFC5F1F8FFCBF9FFFF7E8A8BFF4E4643FF + 7D898BFFCCFAFFFFC5F1F8FFC2EDF4FFC2ECF3FFC2ECF3FFC2ECF3FFC2ECF3FF + C2ECF3FFC3EEF5FFC4EFF6FFC3EEF6FFC1F0FBFFD2D5C4FFE19E58FFD49954FF + A66917B3000000070000000000000001945E1656BC7B2AFFF0B67BFFCFB082FF + C4F0FFFFC2F0F8FF758385FFC5F1F9FFC8F8FFFF808D8FFF554C4AFF808D8EFF + C9F9FFFFC3F0F7FFC1EDF4FFC0EBF2FFC0EBF2FFC0EBF2FFC0EBF2FFC0EBF2FF + C0EBF3FFC2EEF5FF758385FFC2F0F8FFC4F0FFFFCFB082FFF0B67BFFBC7B2AFF + 945E165600000001000000000000000000000009AF6D16F7E4AB6DFFE09B51FF + C4D9D8FFBFECF9FFBFEFF7FFC2F2FAFF828E8EFF5C524FFF849092FFC6F7FFFF + C0EFF6FFBFEDF4FFC0EEF5FFBFECF3FFBDEAF1FFBDEAF1FFBDEAF1FFBDEBF1FF + BDEBF2FFBEECF3FFBFEFF6FFBFECF9FFC4D9D8FFE09B51FFE4AB6DFFAF6D16F7 + 00000009000000000000000000000000000000029D621766C18133FFF2BA83FF + D19B5AFFB9E4FAFFBBEBF6FFC0F1FAFF838F8FFF869394FFC4F7FFFFBEEDF6FF + BCEBF3FFBFEEF7FF728386FFBFEEF7FFBCEAF2FFBBE9F1FFBDEBF3FFBDECF5FF + BDEBF3FFBBEBF4FFBBEAF5FFB9E4FAFFD19B5AFFF2BA82FFC18133FF9D621767 + 000000020000000000000000000000000000000000000006AF6D17E7D99F5BFF + EAAD6CFFC6A67AFFB1DEF5FFB8E7F4FFBEF2FDFF718588FFBDEEF7FFB9E8F2FF + B9E8F2FFBDEDF7FF718487FFBDEDF7FFB9E8F2FFB8E8F1FFBBEBF4FF6D7E81FF + BBEDF6FFB6E4F1FFB0DEF5FFC6A67AFFEDB071FFD99F5BFFAF6D17E700000006 + 0000000000000000000000000000000000000000000000018E5A1527AF6C14FF + EEB880FFEBAE6DFFC69E6BFFACD3E6FFAFDDF1FFB7E8F5FFB8EBF4FFB7E8F1FF + B7E8F1FFBBECF5FF6E8082FFBBECF5FFB7E8F1FFB7E8F1FFB8EBF4FFB6E7F4FF + AEDDF0FFACD3E6FFC59E6AFFEBAE6DFFEEB880FFAF6C14FF6E45111200000000 + 000000000000000000000000000000000000000000000000000000019D621738 + B4721CFFEFBA83FFEDB172FFCF914CFFB5B6A7FFA2D2EEFFA6D3E9FFAADAEAFF + AFE0EEFFB2E4F0FFB3E5F2FFB2E4F0FFAFE0EEFFAADAEAFFA6D3E9FFA2D2EEFF + B5B6A7FFCF914CFFF0B578FFEFBA82FFB4721CFF8F5A15230000000100000000 + 0000000000000000000000000000000000000000000000000000000000000001 + 935C1522AF6C14FFDCA362FFF9C692FFE39F57FFCA8B44FFB2AE99FFA4BFC8FF + 99CDECFF9ACCEBFF9ACCEBFF9ACCEBFF99CDECFFA4BFC8FFB2AE99FFCA8B44FF + E39F57FFF9C692FFDBA362FFAF6C13FF945D1623000000010000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000070461110AF6C16E6C38437FFEDB880FFFCC996FFE6A561FFDA9043FF + D0822DFFD1822CFFD1822CFFD1822CFFD0822DFFDA9043FFE6A561FFFCC996FF + EDB880FFC38437FFAF6C16E67046111000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000002A769175FAF6D15F7BE7F2EFFDEA767FFF2C18DFF + FFD5A9FFFFD5A8FFFFD5A8FFFFD5A8FFFFD5A9FFF2C18DFFDEA767FFBE7F2EFF + AF6D15F7A769175F000000020000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000001A769184CAC6B16ACAF6C15E2 + AF6B13FFAF6B13FFAF6B13FFAF6B13FFAF6B13FFAF6C15E2AC6B16ACA769184C + 0000000100000000000000000000000000000000000000000000000000000000 + 0000000000000000FFFFFFFFFFC001FFFF00007FFE00003FF800000FF0000007 + F0000007E0000003C0000001C000000180000000800000008000000080000000 + 8000000080000000800000008000000080000000800000008000000080000000 + 80000000C0000001C0000001E0000003E0000007F0000007F800000FFE00003F + FF00007FFFC001FF280000001000000020000000010020000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000002000000080000000B0000000B0000000A0000000500000000 + 0000000000000000000000000000000000000000000000000000000000000002 + 000000121910043C50330C8759380CA059380CA157360C9A4028096500000020 + 0000000700000000000000000000000000000000000000000000000206040122 + 764B13ABC27F2FFED18F42FFD9974AFFD99749FFD79547FFCA883AFFAA6D23E0 + 311F07620000000C000000000000000000000000000000020F0902259D6521D5 + D59347FFE1C595FFE4EEE0FFE7FFFFFFE7FFFFFFE6FAF7FFE3DCBEFFDDA765FF + C88639FF4B2F0B720000000A000000000000000000000012915D1CCBD9994FFF + E0E4D0FFCFE6E6FFE1FDFEFFE3FDFEFFBFD0D0FFE1FCFDFFCFE6E6FFE1FCFAFF + DEB67EFFC9883BFF321F075A00000003000000024B2F0B6DD29147FFDCD6B7FF + DCFCFEFFDCFAFCFFDBF9FBFFDDFBFCFFCBE4E6FFDBF9FBFFDCFAFCFFDCFAFCFF + DCFAFAFFDCA867FFAF7228DE0000001000000008A66D24C9DCA868FFD7FBFEFF + C5E0E3FFD7F6F9FFD9F9FCFFD9F9FCFFD7F7FAFFD7F6F9FFD7F6F9FFD7F7FAFF + C5E1E4FFD8D6BBFFD19147FF452B0A520000000BC7883DF9D6C398FFD2F6FBFF + D2F5F8FFD2F5F8FFAFC5C7FF8A9695FFD6FAFCFFD2F4F8FFD2F4F8FFD2F4F8FF + D2F5F8FFD2F4F4FFDE9D55FF57360B850000000BCC8E45FFD2C59EFFBCDCE1FF + ABC4C7FFCEF3F8FFD1F7FBFF889595FF7C8A8AFFCFF5FAFFCDF1F6FFBDDBE0FF + ABC4C7FFCDF8FDFFE0A058FF58360B8A0000000ACE9048FFD3C59CFFC9F2F8FF + CAF2F7FFC8F0F5FFCCF6FAFF829091FF7D8C8DFFCAF3F8FFC8EFF4FFC9F1F6FF + CAF2F7FFCBF7FBFFE1A15BFF58360B8A00000005C2853BE6D7C097FFC3EEF7FF + C4EDF5FFC7F2F9FF859495FF829293FFC8F3F9FFC3ECF3FFC3ECF3FFC3EDF4FF + C4EDF5FFC9EBEDFFDC9D57FF54350B6C000000007F511595E0AB6EFFC2E9F2FF + AED5DBFF89999AFF87989AFFC2F1F8FFC0ECF3FFBEEAF1FFBEEAF1FFBFECF3FF + ADD3DBFFCDC5AAFFCF924AFD311F0718000000003420071CCE914AF9CEB48EFF + B9E8F6FF8EA6AAFFBEEEF7FFBCEBF4FF97B8BEFFBAE8F1FFA8D0D7FFBAE9F3FF + BAD4D7FFE2A96AFF83541895000000000000000000000000764A1058DFA463FF + CBAC83FFAFD3DEFFAFE0EEFFB4E6F1FFA3CDD6FFB1E2EEFFADDDEFFFB7BDB2FF + E3AE74FFB87C31C83722080500000000000000000000000000000000905A134C + D19650F9E5AA6CFFC5A881FFB5A78CFFB5A78BFFB9A789FFD7A975FFE3A868FF + AA7027BD4A2E0B09000000000000000000000000000000000000000000000000 + 53340B1885551691CA8F47E3D7A05DFFD7A05DFFD39B57F8BB7E30BE72470E56 + 00000000000000000000000000000000F81FAC41E007AC41C003AC418001AC41 + 8000AC410000AC410000AC410000AC410000AC410000AC410000AC418000AC41 + 8001AC41C001AC41E003AC41F00FAC41 + } + end +end diff --git a/settings.pas b/settings.pas deleted file mode 100644 index d1ed05a..0000000 --- a/settings.pas +++ /dev/null @@ -1,230 +0,0 @@ -unit settings; - -{$mode objfpc}{$H+} - -interface - -uses - SysUtils, LResources, Forms, Graphics, Dialogs, StdCtrls, ComCtrls, Spin; - -type - - { TOptionsForm } - - TOptionsForm = class(TForm) - BtnOk: TButton; - BtnCancel: TButton; - BtnDefaults: TButton; - CheckAutoRestart: TCheckBox; - CheckHideSeconds: TCheckBox; - CheckSecondsMode: TCheckBox; - CheckAutoSave: TCheckBox; - CheckAlwaysOnTop: TCheckBox; - CheckTicking: TCheckBox; - CheckLoopAudio: TCheckBox; - CheckClickTime: TCheckBox; - CheckDblClickTime: TCheckBox; - FontColor: TColorButton; - FontNameBtn: TButton; - CheckAutostart: TCheckBox; - CheckMinToTray: TCheckBox; - BgColor: TColorButton; - FontSize: TSpinEdit; - Label1: TLabel; - FontName: TStaticText; - LabelTextColor: TLabel; - LabelTextColor1: TLabel; - TimerFontBox: TGroupBox; - PositionCombo: TComboBox; - GroupBox1: TGroupBox; - GroupBox2: TGroupBox; - NotifyAudio: TEdit; - NotifyAudioBtn: TButton; - NotifyAudioOn: TCheckBox; - NotifyAudioTest: TButton; - NotifyMsg: TEdit; - NotifyMsgOn: TCheckBox; - NotifyMsgTest: TButton; - NotifyRunApp: TEdit; - NotifyRunAppOn: TCheckBox; - NotifyRunBtn: TButton; - NotifyRunTest: TButton; - NotifyTrayMsg: TEdit; - NotifyTrayMsgOn: TCheckBox; - NotifyTrayMsgTest: TButton; - PageControl1: TPageControl; - GeneralTab: TTabSheet; - AlarmsTab: TTabSheet; - FontsTab: TTabSheet; - procedure ChooseFont(Sender: TObject); - procedure FormKeyPress(Sender: TObject; var Key: char); - procedure GetAudioFile(Sender: TObject); - procedure GetAppFile(Sender: TObject); - function GetFile(Orig: String; FilterStr: String; Dir : String): String; - procedure EnableFields(Sender: TObject); - procedure SetDefaults(Sender: TObject); - procedure TestAudio(Sender: TObject); - procedure TestMessage(Sender: TObject); - procedure TestRunApp(Sender: TObject); - procedure TestTrayMsg(Sender: TObject); - procedure UpdateFontColor(Sender: TObject); - procedure UpdateFonts(Sender: TObject); - procedure UpdateFontSize(Sender: TObject); - private - { private declarations } - public - { public declarations } - end; - -var - OptionsForm: TOptionsForm; - f: TFont; - -implementation -uses MainForm1; -{ TOptionsForm } - -// TODO Move all text strings to the top - -procedure TOptionsForm.GetAudioFile(Sender: TObject); -begin - NotifyAudio.Text := GetFile(NotifyAudio.Text, 'Wave files (*.wav)|*.wav', GetCurrentDir + '\sounds'); -end; - -procedure TOptionsForm.FormKeyPress(Sender: TObject; var Key: char); -begin - if key = #27 then Close; -end; - -procedure TOptionsForm.ChooseFont(Sender: TObject); -var - dlg : TFontDialog; -begin - dlg := TFontDialog.Create(nil); - dlg.Font := f; - - if dlg.Execute then - begin - f.Name := dlg.Font.Name; - f.Size := dlg.Font.Size; - // TODO Only set color if user changed it (XP dialog doesn't support custom colors) - // Works fine on Win7 - //if not (f.Color = dlg.Font.Color) then f.Color:= dlg.Font.Color; - //f.Color:= dlg.Font.Color; - f.CharSet:= dlg.Font.CharSet; - f.Style:= dlg.Font.Style; - UpdateFonts(Sender); - end; - dlg.Free; -end; - -procedure TOptionsForm.UpdateFonts(Sender: TObject); -begin - FontName.Caption := f.Name + ' : 1234567890'; - FontName.Font.Name := f.Name; - FontName.Font.Color := f.Color; - FontName.Font.CharSet := f.CharSet; - FontName.Font.Style := f.Style; - FontName.Font.Quality:= fqAntialiased; - FontName.Font.Size := 18; - - FontName.Color := BgColor.ButtonColor; - FontSize.Value := f.Size; - FontColor.ButtonColor := f.Color; -end; - -procedure TOptionsForm.UpdateFontSize(Sender: TObject); -begin - f.Size := FontSize.Value; - UpdateFonts(Sender); -end; - -procedure TOptionsForm.UpdateFontColor(Sender: TObject); -begin - f.Color := FontColor.ButtonColor; - UpdateFonts(Sender); -end; - -procedure TOptionsForm.GetAppFile(Sender: TObject); -begin - NotifyRunApp.Text := GetFile(NotifyRunApp.Text, 'Executables (*.exe)|*.exe|All files (*.*)|*.*', GetCurrentDir); -end; - -function TOptionsForm.GetFile(Orig: String; FilterStr: String; Dir : String): String; -var - dlg : TOpenDialog; - fname : String; - cwd : String; - relPath : String; -begin - dlg := TOpenDialog.Create(nil); - dlg.FileName := ''; - if DirectoryExists(Dir) - then dlg.InitialDir := Dir - else dlg.InitialDir := GetCurrentDir; - dlg.Options := [ofFileMustExist]; - dlg.Filter := FilterStr; - dlg.FilterIndex := 1; - - if dlg.Execute then - begin - fname := dlg.FileName; - cwd := GetCurrentDir + '\'; - relPath := ExtractRelativePath(cwd, ExtractFilePath(fname)); - Result := '.\' + relPath + ExtractFileName(fname); - end else begin - Result := Orig; - end; - dlg.Free; -end; - -procedure TOptionsForm.EnableFields(Sender: TObject); -begin - NotifyMsg.Enabled := NotifyMsgOn.Checked; - NotifyMsgTest.Enabled := NotifyMsgOn.Checked; - NotifyTrayMsg.Enabled := NotifyTrayMsgOn.Checked; - NotifyTrayMsgTest.Enabled := NotifyTrayMsgOn.Checked; - - NotifyAudio.Enabled := NotifyAudioOn.Checked; - NotifyAudioBtn.Enabled := NotifyAudioOn.Checked; - NotifyAudioTest.Enabled := NotifyAudioOn.Checked; - - NotifyRunApp.Enabled := NotifyRunAppOn.Checked; - NotifyRunBtn.Enabled := NotifyRunAppOn.Checked; - NotifyRunTest.Enabled := NotifyRunAppOn.Checked; -end; - -procedure TOptionsForm.SetDefaults(Sender: TObject); -begin - (Self.Owner as TMainForm).SetDefaults(Self); - UpdateFonts(Sender); -end; - -procedure TOptionsForm.TestAudio(Sender: TObject); -begin -with Self.Owner as TMainForm do - PlayAudio(NotifyAudio.Text, False); -end; - -procedure TOptionsForm.TestMessage(Sender: TObject); -begin -with Self.Owner as TMainForm do - ShowDoneMessage(NotifyMsg.Text); -end; - -procedure TOptionsForm.TestRunApp(Sender: TObject); -begin -with Self.Owner as TMainForm do - RunApp(NotifyRunApp.Text); -end; - -procedure TOptionsForm.TestTrayMsg(Sender: TObject); -begin -with Self.Owner as TMainForm do - ShowTrayMessage(NotifyTrayMsg.Text); -end; - -initialization - {$I settings.lrs} -end. - diff --git a/snaptimer.lpi b/snaptimer.lpi index ce79283..078e324 100644 --- a/snaptimer.lpi +++ b/snaptimer.lpi @@ -26,6 +26,7 @@ + @@ -64,13 +65,13 @@ - + - + @@ -84,34 +85,78 @@ - + - + - - - + - + - - - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -122,6 +167,7 @@ + diff --git a/snaptimer.lpr b/snaptimer.lpr index 3f45b9a..829f2ab 100644 --- a/snaptimer.lpr +++ b/snaptimer.lpr @@ -3,7 +3,7 @@ {$mode objfpc}{$H+} uses - Forms, Interfaces, MainForm1, About, settings; + Forms, Interfaces, MainForm1, utils, CompactMode, consts; {$R *.res} @@ -11,6 +11,7 @@ Application.Title:='SnapTimer'; Application.Initialize; Application.CreateForm(TMainForm, MainForm); + Application.CreateForm(TCompactModeForm, CompactModeForm); Application.Run; end. diff --git a/snaptimer.lps b/snaptimer.lps new file mode 100644 index 0000000..672bdfa --- /dev/null +++ b/snaptimer.lps @@ -0,0 +1,497 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/snaptimer.lrs b/snaptimer.lrs deleted file mode 100644 index f371f79..0000000 --- a/snaptimer.lrs +++ /dev/null @@ -1,374 +0,0 @@ -LazarusResources.Add('MAINICON','ICO',[ - #0#0#1#0#4#0' '#0#0#1#0#8#0#168#8#0#0'F'#0#0#0#16#16#0#0#1#0#8#0'h'#5#0#0#238 - +#8#0#0' '#0#0#1#0' '#0#168#16#0#0'V'#14#0#0#16#16#0#0#1#0' '#0'h'#4#0#0#254 - +#30#0#0'('#0#0#0' '#0#0#0'@'#0#0#0#1#0#8#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#0'711'#0'<44'#0'A88'#0'C=;'#0'H?='#0'NFC'#0'OGE'#0'ULJ' - +#0'\RO'#0'nxz'#0'p{}'#0#175'k'#19#0#175'l'#19#0#175'l'#20#0#176'm'#22#0#177 - +'o'#24#0#178'p'#25#0#177'q'#29#0#180'q'#28#0#183'u!'#0#186'w$'#0#185'x%'#0 - +#177'v*'#0#178'x+'#0#181'y,'#0#188'z)'#0#184'|/'#0#190#127'.'#0#208#130','#0 - +#193#129'3'#0#196#128'2'#0#195#132'7'#0#198#132'6'#0#203#136';'#0#201#136'<' - +#0#204#136'<'#0#214#141':'#0#217#145'='#0#177#134'M'#0#183#140'S'#0#179#156 - +'~'#0#202#139'D'#0#205#141'D'#0#209#141'B'#0#209#143'G'#0#207#145'L'#0#218 - +#145'B'#0#218#148'A'#0#218#147'D'#0#210#145'I'#0#213#145'I'#0#211#147'M'#0 - +#217#151'N'#0#221#153'I'#0#219#155'M'#0#220#155'M'#0#221#156'N'#0#192#149'\' - +#0#212#153'T'#0#219#154'Q'#0#220#157'Q'#0#223#158'U'#0#209#155'Z'#0#217#158 - +'Z'#0#220#156'Y'#0#224#158'M'#0#224#155'Q'#0#227#159'W'#0#225#158'X'#0#222 - +#161'U'#0#226#162'Q'#0#225#167'Z'#0#224#161'^'#0#199#155'a'#0#197#158'j'#0 - +#219#163'b'#0#220#163'b'#0#222#167'g'#0#198#166'z'#0#230#165'a'#0#227#170'l' - +#0#228#171'm'#0#231#172'o'#0#234#173'l'#0#232#174'r'#0#237#176'q'#0#233#176 - +'v'#0#235#178'y'#0#237#183'~'#0#240#181'z'#0'm~'#129#0'n'#128#130#0't'#128 - +#128#0'r'#131#134#0'u'#131#133#0'q'#132#135#0'x'#132#133#0'q'#133#136#0'z' - +#134#136#0'}'#137#138#0#130#138#139#0#129#139#141#0#129#141#142#0#133#141#142 - +#0#131#144#145#0#132#144#146#0#133#147#148#0#137#145#144#0#142#151#152#0#148 - +#157#156#0#189#165#135#0#178#174#153#0#153#162#161#0#181#182#167#0#207#176 - +#130#0#238#184#128#0#242#186#130#0#216#197#156#0#242#193#141#0#249#198#146#0 - +#252#201#150#0#220#207#171#0#227#206#163#0#255#213#168#0#226#211#176#0#164 - +#191#200#0#154#204#235#0#153#205#236#0#172#211#230#0#166#211#233#0#162#210 - +#238#0#170#218#234#0#174#221#240#0#176#222#245#0#175#224#238#0#178#228#240#0 - +#182#228#241#0#182#231#244#0#184#231#244#0#183#232#241#0#183#232#245#0#185 - +#232#241#0#188#234#241#0#190#236#243#0#186#234#244#0#187#236#245#0#190#237 - +#246#0#185#228#250#0#191#236#249#0#190#242#253#0#210#213#196#0#196#217#216#0 - +#213#228#216#0#222#241#235#0#192#235#242#0#194#236#243#0#193#237#245#0#197 - +#237#244#0#196#239#248#0#195#240#247#0#198#241#247#0#200#240#245#0#205#241 - +#246#0#193#240#249#0#197#241#248#0#196#240#255#0#197#247#255#0#201#242#249#0 - +#206#243#248#0#202#244#249#0#205#245#250#0#207#245#252#0#202#249#255#0#205 - +#250#254#0#207#252#255#0#210#244#248#0#213#246#249#0#209#246#252#0#216#247 - +#250#0#215#248#251#0#210#249#254#0#214#249#253#0#208#253#255#0#214#254#255#0 - +#217#248#251#0#221#250#251#0#217#249#252#0#221#250#252#0#218#253#255#0#221 - +#253#254#0#231#238#224#0#226#243#236#0#225#254#254#0#229#255#255#0#233#255 - +#255#0#144#0'b'#0#176#0'x'#0#207#0#142#0#240#0#164#0#255#17#179#0#255'1'#190 - +#0#255'Q'#199#0#255'q'#209#0#255#145#220#0#255#177#229#0#255#209#240#0#255 - +#255#255#0#0#0#0#0','#0'/'#0'K'#0'P'#0'i'#0'p'#0#135#0#144#0#165#0#176#0#196 - +#0#207#0#225#0#240#0#240#17#255#0#242'1'#255#0#244'Q'#255#0#246'q'#255#0#247 - +#145#255#0#249#177#255#0#251#209#255#0#255#255#255#0#0#0#0#0#27#0'/'#0'-'#0 - +'P'#0'?'#0'p'#0'R'#0#144#0'c'#0#176#0'v'#0#207#0#136#0#240#0#153#17#255#0#166 - +'1'#255#0#180'Q'#255#0#194'q'#255#0#207#145#255#0#220#177#255#0#235#209#255#0 - +#255#255#255#0#0#0#0#0#8#0'/'#0#14#0'P'#0#21#0'p'#0#27#0#144#0'!'#0#176#0'&' - +#0#207#0','#0#240#0'>'#17#255#0'X1'#255#0'qQ'#255#0#140'q'#255#0#166#145#255 - +#0#191#177#255#0#218#209#255#0#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0''''#24#17#17#19#17#18#24''''#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#0#0')'#18#20#31'$,,,,,$'#31#20#18')'#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#23#21'$389GGGGG973$'#21#23#0#0#0#0#0#0#0#0#0#0#0#0#0#0#17'!39H{' - +#191#195#195#195#195#195#191'{H93!'#17#0#0#0#0#0#0#0#0#0#0#0#0#19'25B}'#194 - +#194#194#194#194#195#194#194#194#194#194'}B52'#19#0#0#0#0#0#0#0#0#0#0#17'2v'#184#182#187#180#177#177#187#189#190#189 - +#179#177#177#177#179#177#177#180#187#182#184'v>+('#0#0#0#24'@6'#153#181#177 - +#177#177#176#177#189'he'#190#182#177#176#176#176#177#177#177#176#177#181#153 - +'6@'#24#0#0#0#16'S0'#183#181#176#178#176#176#176#184'l'#7'd'#190#182#177#176 - ,#176#176#176#176#176#176#178#183'0S'#16#0#0#0#16'U&'#175#172#178#182#178#176 - +#169#178#184'h'#4']'#189#178#169#169#169#176#178#181#181#172#174'0U'#15#0#0#0 - +#15'W&'#174#172'jki'#172#163#169#178#189'g'#1#10#181#169#163#163#171'iki'#178 - +#173'&W'#15#0#0#0#15'X%'#183#170#171#172#171#168#162#168#171#184'c'#2#11#181 - +#162#162#162#168#171#171#171#170#183'%X'#15#0#0#0#15'Y%'#175#161#162#162#162 - +#162#162#170#183'a'#3'a'#183#170#162#162#162#162#162#162#162#161#175'%Y'#15#0 - +#0#0#25'R1'#175#159#158#158#158#162#168#175'c'#5'c'#183#168#162#158#158#158 - +#158#158#158#158#165#175'1R'#25#0#0#0':;E'#151#150#159#160#159#165#173'd'#6 - +'d'#174#165#157#156#156#158#156#156#160#160#160#164#151'E;:'#0#0#0#0#26'Zs' - +#166#160'_'#165#173'g'#8'g'#173#160#157#155#156#155#155#155#155#160'_'#160 - +#166'sZ'#26#0#0#0#0#0#18'RC'#152#149#164#164'i'#9'j'#167#160#144#157#144#143 - +#143#143#143#144#144#147#149#152'CR'#18#0#0#0#0#0#0#30'u?'#148#146#164'ik' - +#167#147#144#149'^'#149#143#143#144#147#144#146#146#148'?u'#30#0#0#0#0#0#0#0 - +#25'@TO'#134#139#150'b'#147#145#142#147'b'#147#139#140#145'['#146#137#134'OV' - +'@'#25#0#0#0#0#0#0#0#0#14'tTK'#129#133#141#145#140#140#146'\'#146#140#140#145 - +#138#133#129'KTt'#14#0#0#0#0#0#0#0#0#0#0#19'uV.r'#131#130#132#135#136#137#136 - +#135#132#130#131'r.Zt'#19#0#0#0#0#0#0#0#0#0#0#0#0#14'MxD*p~'#128#127#127#127 - +#128'~p*DxL'#13#0#0#0#0#0#0#0#0#0#0#0#0#0#0#25' tyP/'#29#29#29#29#29'/Pyt ' - +#25#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#18#28'Nw|||||wN'#28#18#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#0#0#0'J'#27#12#12#12#12#12#27'J'#0#0#0#0#0#0#0#0#0#0#0 - +#255#255#255#255#255#255#255#255#255#255#255#255#255#240#7#255#255#128#0#255 - +#255#0#0#127#254#0#0'?'#252#0#0#31#248#0#0#15#240#0#0#7#224#0#0#3#224#0#0#3 - +#224#0#0#3#192#0#0#1#192#0#0#1#192#0#0#1#192#0#0#1#192#0#0#1#192#0#0#1#192#0 - +#0#1#192#0#0#1#192#0#0#1#224#0#0#3#224#0#0#3#240#0#0#7#240#0#0#7#248#0#0#15 - +#252#0#0#31#254#0#0'?'#255#0#0#127#255#192#1#255#255#240#7#255'('#0#0#0#16#0 - +#0#0' '#0#0#0#1#0#8#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#180'~='#0#194#127'/'#0#173'~E'#0#167'~J'#0#200#134'9'#0#201#136':'#0#185#132 - +'C'#0#184#139'R'#0#150#129'e'#0#153#133'l'#0#163#134'`'#0#164#146'z'#0#162 - +#147'~'#0#167#150#127#0#180#153'v'#0#182#155'x'#0#185#158'z'#0#200#138'A'#0 - +#204#142'E'#0#209#143'B'#0#199#144'N'#0#206#145'I'#0#207#147'N'#0#209#145'G' - +#0#213#147'G'#0#215#149'G'#0#217#151'I'#0#217#153'O'#0#192#149'^'#0#199#152 - +']'#0#207#155'['#0#210#152'T'#0#221#157'V'#0#212#157'['#0#215#160']'#0#224 - +#160'Y'#0#204#158'd'#0#223#164'c'#0#221#167'e'#0#220#168'g'#0#220#168'h'#0 - +#215#169'u'#0#222#182'~'#0#226#168'i'#0#224#171'n'#0#229#170'l'#0#227#174't' - +#0'|'#138#138#0'}'#140#141#0#130#145#146#0#133#148#149#0#137#149#149#0#135 - +#152#154#0#137#153#154#0#181#167#139#0#181#167#140#0#185#167#137#0#142#166 - +#170#0#151#184#190#0#183#189#178#0#197#168#129#0#203#172#131#0#206#180#142#0 - +#215#192#151#0#214#195#152#0#210#197#157#0#225#197#149#0#205#197#170#0#220 - +#214#183#0#216#214#187#0#227#220#190#0#171#196#199#0#175#197#199#0#163#205 - +#214#0#168#208#215#0#173#211#219#0#174#213#219#0#175#211#222#0#191#208#208#0 - +#186#212#215#0#173#221#239#0#189#219#224#0#188#220#225#0#175#224#238#0#177 - +#226#238#0#180#230#241#0#186#232#242#0#190#234#241#0#191#236#243#0#185#232 - +#246#0#188#235#244#0#190#238#247#0#224#228#208#0#197#224#227#0#197#225#228#0 - +#203#228#230#0#207#230#230#0#201#235#237#0#194#233#242#0#194#236#243#0#195 - +#237#245#0#196#237#245#0#200#239#244#0#201#241#246#0#205#241#246#0#194#241 - +#248#0#199#242#249#0#201#242#248#0#206#243#248#0#203#247#251#0#205#245#250#0 - +#205#248#253#0#210#244#244#0#209#245#248#0#215#246#249#0#214#250#253#0#219 - +#249#251#0#220#250#250#0#217#249#252#0#220#250#252#0#220#252#254#0#228#238 - +#224#0#230#250#247#0#225#252#250#0#225#252#253#0#231#255#255#0#255#255#255#0 - +#0#0#0#0'/&'#0#0'PA'#0#0'p['#0#0#144't'#0#0#176#142#0#0#207#169#0#0#240#195#0 - +#0#255#210#17#0#255#216'1'#0#255#221'Q'#0#255#228'q'#0#255#234#145#0#255#240 - +#177#0#255#246#209#0#255#255#255#0#0#0#0#0'/'#20#0#0'P"'#0#0'p0'#0#0#144'>'#0 - +#0#176'M'#0#0#207'['#0#0#240'i'#0#0#255'y'#17#0#255#138'1'#0#255#157'Q'#0#255 - +#175'q'#0#255#193#145#0#255#210#177#0#255#229#209#0#255#255#255#0#0#0#0#0'/' - +#3#0#0'P'#4#0#0'p'#6#0#0#144#9#0#0#176#10#0#0#207#12#0#0#240#14#0#0#255' '#18 - +#0#255'>1'#0#255'\Q'#0#255'zq'#0#255#151#145#0#255#182#177#0#255#212#209#0 - +#255#255#255#0#0#0#0#0'/'#0#14#0'P'#0#23#0'p'#0'!'#0#144#0'+'#0#176#0'6'#0 - +#207#0'@'#0#240#0'I'#0#255#17'Z'#0#255'1p'#0#255'Q'#134#0#255'q'#156#0#255 - +#145#178#0#255#177#200#0#255#209#223#0#255#255#255#0#0#0#0#0'/'#0' '#0'P'#0 - +'6'#0'p'#0'L'#0#144#0'b'#0#176#0'x'#0#207#0#142#0#240#0#164#0#255#17#179#0 - +#255'1'#190#0#255'Q'#199#0#255'q'#209#0#255#145#220#0#255#177#229#0#255#209 - +#240#0#255#255#255#0#0#0#0#0','#0'/'#0'K'#0'P'#0'i'#0'p'#0#135#0#144#0#165#0 - +#176#0#196#0#207#0#225#0#240#0#240#17#255#0#242'1'#255#0#244'Q'#255#0#246'q' - +#255#0#247#145#255#0#249#177#255#0#251#209#255#0#255#255#255#0#0#0#0#0#27#0 - ,'/'#0'-'#0'P'#0'?'#0'p'#0'R'#0#144#0'c'#0#176#0'v'#0#207#0#136#0#240#0#153#17 - +#255#0#166'1'#255#0#180'Q'#255#0#194'q'#255#0#207#145#255#0#220#177#255#0#235 - +#209#255#0#255#255#255#0#0#0#0#0#8#0'/'#0#14#0'P'#0#21#0'p'#0#27#0#144#0'!'#0 - +#176#0'&'#0#207#0','#0#240#0'>'#17#255#0'X1'#255#0'qQ'#255#0#140'q'#255#0#166 - +#145#255#0#191#177#255#0#218#209#255#0#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#13#9#9#10#0#0#0#0#0#0#0#0#0#0#11#2#20#27#27#26#6#1#0#0#0 - +#0#0#0#0#3#26'Cz~~{G'''#5#0#0#0#0#0#4#28']a}~O}a|+'#6#0#0#0#0#24'Eyxux`vxxv)' - +#7#0#0#8')t^swwwssw_F'#24#0#0#18'ArrrI4trrrrq!'#14#0#19'BSHmr40oiRHp$'#12#0 - +#22'Bllho21lghln$'#12#0#21'@efk32kddffb!'#0#0#15'-cM65jYXXYLD'#22#0#0#0#23'?' - +'Z:\[;WKWP,'#16#0#0#0#0'&>NTVJUQ'#255#205#251#255#255#207#245#252#255#210#247#252#255#211#248 - +#253#255#210#247#252#255#208#244#249#255#206#243#248#255#209#245#250#255#215 - +#255#255#255#132#142#142#255'C=;'#255't'#128#128#255#218#255#255#255#209#246 - +#251#255#206#242#247#255#206#242#247#255#206#242#247#255#208#244#249#255#210 - +#247#252#255#211#248#253#255#210#247#252#255#207#245#252#255#205#251#255#255 - +#217#146'>'#255#232#174'r'#255#176'n'#22#255#0#0#0#22#0#0#0#0#0#0#0#22#176'm' - +#22#255#233#176'v'#255#217#144'='#255#203#250#255#255#207#246#252#255#131#144 - +#145#255#133#147#148#255#131#144#145#255#207#244#250#255#204#241#247#255#205 - +#242#247#255#208#246#252#255#218#255#255#255#129#139#141#255'711'#255'nxz' - +#255#211#250#255#255#205#242#247#255#204#241#246#255#204#241#246#255#207#244 - +#250#255#131#144#145#255#133#147#148#255#131#144#145#255#207#246#252#255#203 - +#250#255#255#217#144'='#255#233#176'v'#255#176'm'#22#255#0#0#0#22#0#0#0#0#0#0 - +#0#22#176'm'#22#255#235#178'y'#255#215#142';'#255#208#253#255#255#202#243#250 - +#255#205#245#250#255#206#246#251#255#205#245#250#255#202#242#247#255#201#240 - +#245#255#201#241#246#255#205#246#251#255#215#255#255#255'y'#135#137#255'<44' - +#255'p{}'#255#207#249#254#255#202#241#246#255#201#240#245#255#201#240#245#255 - +#202#242#247#255#205#245#250#255#206#246#251#255#205#245#250#255#202#243#250 - +#255#208#253#255#255#215#142';'#255#235#178'y'#255#176'm'#22#255#0#0#0#22#0#0 - +#0#0#0#0#0#19#176'm'#22#255#237#183'~'#255#214#141':'#255#207#252#255#255#198 - +#241#247#255#200#240#245#255#200#240#245#255#200#240#245#255#199#239#244#255 - +#200#240#245#255#202#244#249#255#210#253#255#255'x'#132#133#255'A88'#255'w' - +#131#133#255#210#254#255#255#202#243#248#255#199#239#244#255#199#239#244#255 - +#199#239#244#255#199#239#244#255#200#240#245#255#200#240#245#255#200#240#245 - +#255#198#241#247#255#207#252#255#255#214#141':'#255#237#183'~'#255#176'm'#22 - +#255#0#0#0#19#0#0#0#0#0#0#0#14#172'k'#22#230#227#170'l'#255#218#147'D'#255 - +#208#251#255#255#196#239#248#255#197#237#245#255#197#237#245#255#197#237#244 - +#255#198#238#245#255#200#241#249#255#207#251#255#255'{'#134#136#255'H?='#255 - +'z'#134#136#255#208#252#255#255#201#242#249#255#198#238#245#255#197#237#244 - +#255#197#237#244#255#197#237#244#255#197#237#244#255#197#237#244#255#197#237 - +#245#255#197#237#245#255#196#239#248#255#208#251#255#255#218#147'D'#255#227 - ,#170'l'#255#172'k'#22#230#0#0#0#14#0#0#0#0#0#0#0#7#166'i'#23#179#212#153'T' - +#255#225#158'X'#255#210#213#196#255#193#240#251#255#195#238#246#255#196#239 - +#246#255#196#238#246#255#197#241#248#255#203#249#255#255'~'#138#139#255'NFC' - +#255'}'#137#139#255#204#250#255#255#197#241#248#255#194#237#244#255#194#236 - +#243#255#194#236#243#255#194#236#243#255#194#236#243#255#194#236#243#255#195 - +#238#245#255#196#239#246#255#195#238#246#255#193#240#251#255#210#213#196#255 - +#225#158'X'#255#212#153'T'#255#166'i'#23#179#0#0#0#7#0#0#0#0#0#0#0#1#148'^' - +#22'V'#188'{*'#255#240#182'{'#255#207#176#130#255#196#240#255#255#194#240#248 - +#255'u'#131#133#255#197#241#249#255#200#248#255#255#128#141#143#255'ULJ'#255 - +#128#141#142#255#201#249#255#255#195#240#247#255#193#237#244#255#192#235#242 - +#255#192#235#242#255#192#235#242#255#192#235#242#255#192#235#242#255#192#235 - +#243#255#194#238#245#255'u'#131#133#255#194#240#248#255#196#240#255#255#207 - +#176#130#255#240#182'{'#255#188'{*'#255#148'^'#22'V'#0#0#0#1#0#0#0#0#0#0#0#0 - +#0#0#0#9#175'm'#22#247#228#171'm'#255#224#155'Q'#255#196#217#216#255#191#236 - +#249#255#191#239#247#255#194#242#250#255#130#142#142#255'\RO'#255#132#144#146 - +#255#198#247#255#255#192#239#246#255#191#237#244#255#192#238#245#255#191#236 - +#243#255#189#234#241#255#189#234#241#255#189#234#241#255#189#235#241#255#189 - +#235#242#255#190#236#243#255#191#239#246#255#191#236#249#255#196#217#216#255 - +#224#155'Q'#255#228#171'm'#255#175'm'#22#247#0#0#0#9#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#2#157'b'#23'f'#193#129'3'#255#242#186#131#255#209#155'Z'#255#185#228 - +#250#255#187#235#246#255#192#241#250#255#131#143#143#255#134#147#148#255#196 - +#247#255#255#190#237#246#255#188#235#243#255#191#238#247#255'r'#131#134#255 - +#191#238#247#255#188#234#242#255#187#233#241#255#189#235#243#255#189#236#245 - +#255#189#235#243#255#187#235#244#255#187#234#245#255#185#228#250#255#209#155 - +'Z'#255#242#186#130#255#193#129'3'#255#157'b'#23'g'#0#0#0#2#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#6#175'm'#23#231#217#159'['#255#234#173'l'#255#198#166'z' - +#255#177#222#245#255#184#231#244#255#190#242#253#255'q'#133#136#255#189#238 - +#247#255#185#232#242#255#185#232#242#255#189#237#247#255'q'#132#135#255#189 - +#237#247#255#185#232#242#255#184#232#241#255#187#235#244#255'm~'#129#255#187 - +#237#246#255#182#228#241#255#176#222#245#255#198#166'z'#255#237#176'q'#255 - +#217#159'['#255#175'm'#23#231#0#0#0#6#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#1#142'Z'#21''''#175'l'#20#255#238#184#128#255#235#174'm'#255#198#158 - +'k'#255#172#211#230#255#175#221#241#255#183#232#245#255#184#235#244#255#183 - +#232#241#255#183#232#241#255#187#236#245#255'n'#128#130#255#187#236#245#255 - +#183#232#241#255#183#232#241#255#184#235#244#255#182#231#244#255#174#221#240 - +#255#172#211#230#255#197#158'j'#255#235#174'm'#255#238#184#128#255#175'l'#20 - +#255'nE'#17#18#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#1#157'b'#23'8'#180'r'#28#255#239#186#131#255#237#177'r'#255#207#145'L'#255 - +#181#182#167#255#162#210#238#255#166#211#233#255#170#218#234#255#175#224#238 - +#255#178#228#240#255#179#229#242#255#178#228#240#255#175#224#238#255#170#218 - +#234#255#166#211#233#255#162#210#238#255#181#182#167#255#207#145'L'#255#240 - +#181'x'#255#239#186#130#255#180'r'#28#255#143'Z'#21'#'#0#0#0#1#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1#147'\'#21'"'#175 - +'l'#20#255#220#163'b'#255#249#198#146#255#227#159'W'#255#202#139'D'#255#178 - +#174#153#255#164#191#200#255#153#205#236#255#154#204#235#255#154#204#235#255 - +#154#204#235#255#153#205#236#255#164#191#200#255#178#174#153#255#202#139'D' - +#255#227#159'W'#255#249#198#146#255#219#163'b'#255#175'l'#19#255#148']'#22'#' - +#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0'pF'#17#16#175'l'#22#230#195#132'7'#255#237#184#128#255 - +#252#201#150#255#230#165'a'#255#218#144'C'#255#208#130'-'#255#209#130','#255 - +#209#130','#255#209#130','#255#208#130'-'#255#218#144'C'#255#230#165'a'#255 - +#252#201#150#255#237#184#128#255#195#132'7'#255#175'l'#22#230'pF'#17#16#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#2#167'i'#23'_'#175'm'#21#247#190#127'.' - +#255#222#167'g'#255#242#193#141#255#255#213#169#255#255#213#168#255#255#213 - +#168#255#255#213#168#255#255#213#169#255#242#193#141#255#222#167'g'#255#190 - +#127'.'#255#175'm'#21#247#167'i'#23'_'#0#0#0#2#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1#167'i'#24'L'#172'k'#22#172#175'l'#21 - +#226#175'k'#19#255#175'k'#19#255#175'k'#19#255#175'k'#19#255#175'k'#19#255 - +#175'l'#21#226#172'k'#22#172#167'i'#24'L'#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255#192#1#255 - +#255#0#0#127#254#0#0'?'#248#0#0#15#240#0#0#7#240#0#0#7#224#0#0#3#192#0#0#1 - +#192#0#0#1#128#0#0#0#128#0#0#0#128#0#0#0#128#0#0#0#128#0#0#0#128#0#0#0#128#0 - ,#0#0#128#0#0#0#128#0#0#0#128#0#0#0#128#0#0#0#128#0#0#0#128#0#0#0#192#0#0#1 - +#192#0#0#1#224#0#0#3#224#0#0#7#240#0#0#7#248#0#0#15#254#0#0'?'#255#0#0#127 - +#255#192#1#255'('#0#0#0#16#0#0#0' '#0#0#0#1#0' '#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#2#0#0#0 - +#8#0#0#0#11#0#0#0#11#0#0#0#10#0#0#0#5#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#2#0#0#0#18#25#16#4' 1 then begin + // WriteLn('has options'); + //if Application.HasOption('h', 'help') then begin + // WriteLn('SnapTimer usage'); + // WriteLn('[number of minutes] (must be the only parameter)'); + // WriteLn('-h|--help\tShow this usage'); + // WriteLn('-i|--ini=\tPath to .ini file to use'); + //end else if Application.HasOption('i', 'ini') then begin + // //IniFilename := Application.GetOptionValue('i', 'ini'); + // WriteLn('ini option found'); + //end; + //end; + + if Config.Load = False then + begin + MessageDlg(MSG_OPEN_INI, mtError, [mbOK], 0); + Exit; + end; + + // Use TimeEdit argument if it's the only parameter and it's numeric + if (ParamCount = 1) and (TUtils.IsInteger(ParamStr(1))) then + TimeEdit.Value := StrToInt(ParamStr(1)); + + if Config.AutoStart then + ToggleCountdown(Sender); +end; + + + +procedure TMainForm.OnDestroyForm(Sender: TObject); +begin + if GetConfig.AutoSave then + SaveSettings(Sender); +end; + +procedure TMainForm.OnShowForm(Sender: TObject); +begin + if OnShowFormFirstTime then + begin + OnShowFormFirstTime:= False; + ApplyConfig; + // ApplyConfig does not set MainForm dimensions and TimeEdit(TSpinEdit) + TimeEdit.Value:= GetConfig.Minutes; + GetMainController.Timer.Reset; // This will trigger OnTimerStateChanged + end; +end; + +procedure TMainForm.FormWindowStateChange(Sender: TObject); +begin + if WindowState = wsMinimized then + begin + TrayMenuShow.Caption:= TRAY_MENU_SHOW; + if GetConfig.MinToTray then + begin + // SysTray hack + // https://forum.lazarus.freepascal.org/index.php/topic,2194.msg9843.html#msg9843 + WindowState:= wsNormal; + Hide; + ShowInTaskBar := stNever; + + // Restore WindowState to what it was + WindowState:= wsMinimized; + end; + end + else if WindowState = wsNormal then + begin + TrayMenuShow.Caption:= TRAY_MENU_HIDE; + if GetConfig.MinToTray then + begin + ShowInTaskBar := stDefault; + Show; + end; + end; + +end; + +procedure TMainForm.FormKeyPress(Sender: TObject; var Key: char); +begin + // TMainForm's KeyPreview property must be set to True for this to work. + if key = #27 then + Close; // 27 = Escape + if (TimeEdit.Focused) and (key = #13) then + ToggleCountdown(Sender); +end; + +procedure TMainForm.TrayIconMainClick(Sender: TObject); +begin + if GetMainController.CompactMode then + exit; // No hide or show + + if WindowState = wsNormal then + begin + // Windows: setting WindowState to wsMinimized does not minimize to taskbar. + //WindowState:= wsMinimized; + Application.Minimize; + end + else if WindowState = wsMinimized then + ShowForm; +end; + + +procedure TMainForm.CloseApp(Sender: TObject); +begin + OnDestroyForm(Sender); + Close; +end; + + +procedure TMainForm.ToggleCountdown(Sender: TObject); +begin + GetMainController.ToggleCountdown(Sender); +end; + +procedure TMainForm.ResetCountdown(Sender: TObject); +begin + GetMainController.ResetCountdown(Sender); +end; + + +procedure TMainForm.ShowOptions(Sender: TObject); +var + Config: TConfig; + Ok: Boolean; + r : TRect; +begin + OptionsForm := TOptionsForm.Create(Self); + Ok:= OptionsForm.ShowModal = mrOk; + OptionsForm.Free; + + if Ok then + begin + Config:= GetConfig; + r:= TUtils.GetFormRect(self); + Config.WndLeft:= r.Left; + Config.WndTop:= r.Top; + Config.WndWidth:= r.Width; + Config.WndHeight:= r.Height; + ApplyConfig; + + if GetMainController.Timer.State = TState.Running then + begin + if Config.TickingOn then + GetMainController.PlayTicking + else + TUtils.StopAudio; + end; + + if Config.AutoSave then + SaveSettings(Sender); + end; +end; + + +procedure TMainForm.ShowAbout(Sender: TObject); +var + AboutForm: TAboutForm; +begin + AboutForm := TAboutForm.Create(Self); + AboutForm.ShowModal; + AboutForm.Release; +end; + + +procedure TMainForm.SaveSettings(Sender: TObject); +var + Config: TConfig; + wRect: TRect; +begin + Config:= GetConfig; + + // These config values are not set in OptionsForm. + Config.Minutes:= TimeEdit.Value; + wRect:= TUtils.GetFormRect(self); + Config.WndWidth:= wRect.Width; + Config.WndHeight:= wRect.Height; + Config.WndLeft:= wRect.Left; + Config.WndTop:= wRect.Top; + + if Config.Save = False then + MessageDlg(MSG_WRITE_INI, mtError, [mbOK], 0); +end; + +procedure TMainForm.TimeEditChanged(Sender: TObject); +begin + if (GetMainController.Timer.State <> TState.Running) and (GetMainController.Timer.State <> TState.Paused) then + ResetCountdown(Sender); +end; + +procedure TMainForm.ShowForm; +begin + // Not sure why this behaviour is different. + +{$IFDEF WINDOWS} + // Setting WindowState to wsNormal does not call FormOnWindowStateChange + WindowState:= wsNormal; + FormWindowStateChange(nil); +{$ENDIF} + +{$IFDEF LINUX} + Show; +{$ENDIF} +end; + +procedure TMainForm.ApplyConfig; +var + Config: TConfig; + tw, th: Integer; +begin + Config:= GetConfig; + if Config.AlwaysOnTop then + FormStyle:= fsSystemStayOnTop + else + FormStyle:= fsNormal; + + if Config.SecondsMode then + TimeLabel.Caption := LBL_SECONDS + else + TimeLabel.Caption := LBL_MINUTES; + + Count.Font.Quality := fqAntialiased; + Count.Font.Name := Config.Font.Name; + Count.Font.CharSet := Config.Font.Charset; + Count.Font.Color := Config.Font.Color; + Count.Font.Size := Config.Font.Size; + Count.Font.Style := Config.Font.Style; + Count.Color := Config.Font.BgColor; + + + Count.Canvas.GetTextSize('00:00:00', tw, th); + if tw < 168 then + tw:= 168; + self.ClientWidth:= tw + 8; + self.ClientHeight:= th + 32; + + self.Position:= poDesigned; + case Config.WndPosition of + Remember: TUtils.SetControlPos(self, Config.WndLeft, Config.WndTop); + TopLeft: TUtils.SetControlPos(self, 0, 0); + TopRight: TUtils.SetControlPos(self, Monitor.WorkareaRect.Right - Width, 0); + BottomLeft: TUtils.SetControlPos(self, 0, Monitor.WorkareaRect.Bottom - Height); + BottomRight: TUtils.SetControlPos(self, Monitor.WorkareaRect.Right - Width, Monitor.WorkareaRect.Bottom - Height); + Center: + begin + Self.Position := poScreenCenter; + // After the main form was centered, we want to be able to position it and we + // don't want minimize/restore action to center it again. + Self.Position := poDesigned; + end; + end; + +end; + +initialization + {$I mainform1.lrs} +end. + diff --git a/ui/msgbox.lfm b/ui/msgbox.lfm new file mode 100644 index 0000000..77f6133 --- /dev/null +++ b/ui/msgbox.lfm @@ -0,0 +1,624 @@ +object MsgBoxForm: TMsgBoxForm + Left = 819 + Height = 136 + Top = 314 + Width = 162 + BorderStyle = bsDialog + Caption = 'Done' + ClientHeight = 136 + ClientWidth = 162 + FormStyle = fsSystemStayOnTop + Icon.Data = { + 662500000000010004002020000001001800A80C000046000000101000000100 + 180068030000EE0C00002020000001002000A810000056100000101000000100 + 200068040000FE2000002800000020000000400000000100180000000000000C + 0000640000006400000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000B1864DB2782BB27019B2 + 7019B4711CB27019B1711DB2782BB1864D000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000B39C7EB1711DB77521C48032CC883CD18D42D1 + 8D42D18D42D18D42D18D42CC883CC48032B77521B1711DB39C7E000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000B1762ABA7724CC883CD59149DC9B4DDD9C4EE2A251E2 + A251E2A251E2A251E2A251DD9C4EDB9B4DD59149CC883CBA7724B1762A000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000B27019C68436D59149DD9C4EE1A75AE3CEA3E7EEE0E9FFFFE9 + FFFFE9FFFFE9FFFFE9FFFFE7EEE0E3CEA3E1A75ADD9C4ED59149C68436B27019 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000B4711CD29149D9974EE09E4DE2D3B0E5FFFFE5FFFFE5FFFFE5FFFFE5 + FFFFE9FFFFE5FFFFE5FFFFE5FFFFE5FFFFE5FFFFE2D3B0E09E4DD9974ED29149 + B4711C0000000000000000000000000000000000000000000000000000000000 + 00B27019D29149DB9A51DEA155E2F3ECE5FFFFE5FFFFE5FFFFE1FEFEE5FFFFE5 + FFFF99A2A1E5FFFFE5FFFFE1FEFEE5FFFFE5FFFFE5FFFFE2F3ECDEA155DB9A51 + D29149B27019000000000000000000000000000000000000000000000000B176 + 2AC9883CDC9D51DEA155E1FEFEE1FEFEE1FEFE949D9CE1FEFEDDFAFCE1FEFEE5 + FFFF99A2A1E5FFFFE1FEFEDDFAFCE1FEFE949D9CE1FEFEE1FEFEE1FEFEDEA155 + DC9D51C9883CB2782B000000000000000000000000000000000000BDA587BC7A + 29DC9C59DD9949DEF1EBDDFDFEDDFDFEDDFDFEE1FEFEE1FEFEDDFAFCDDFAFCE1 + FEFE949D9CE5FFFFDDFAFCDDFAFBDDFDFEE1FEFEDDFDFEDDFDFEDDFDFEDEF1EB + DD9949DC9C59BC7A29BDA587000000000000000000000000000000B1711DD393 + 4DDC9D51DCCFABDDFDFEDDFDFEDDFAFCD9F9FCD9F8FBD9F8FBD9F8FBD9F9FCDD + FAFCDDFDFEDDFAFCD9F8FBD9F8FBD9F8FBD9F9FCD9F8FBDDFAFCDDFDFEDAFDFF + DCCFABDC9D51D3934DB1711D000000000000000000000000000000B97825E0A1 + 5EDC9D51DAFDFFDAFDFF8E9798DAFDFFD8F7FAD8F7FAD9F8FBD9F8FBD9F8FBD7 + F8FBD9F8FBD8F7FAD8F7FAD8F7FAD8F7FAD8F7FAD8F7FADAFDFF8E9798DAFDFF + DAFDFFDC9D51E0A15EB97825000000000000000000000000B78C53CD8D44DF9E + 55D8C59CD6FEFFD6F9FDD9F9FCD7F8FBD5F6F9D5F6F9D9F9FCDAFDFFDDFDFEDA + FDFFD8F7FAD5F6F9D5F6F9D5F6F9D8F7FAD5F6F9D5F6F9D7F8FBD9F9FCD6F9FD + D6FEFFD8C59CDF9E55CD8D44B78C53000000000000000000B2782BD99E5ADD99 + 49D5E4D8D2F9FED5F6F9D5F6F9D5F6F9D2F4F8D5F6F9DAFDFF858D8E828A8BDD + FDFED6F9FDD5F6F9D2F4F8D2F4F8D2F4F8D5F6F9D5F6F9D5F6F9D2F4F8D5F6F9 + D2F9FED5E4D8DD9949D99E5AB2782B000000000000000000B16F18E7AC6FDA94 + 41D0FDFFD2F9FED2F4F8D1F6FCD2F4F8D2F4F8D2F4F8D6FEFF8991904F47457D + 898ADDFDFED6F9FDD5F6F9D2F4F8D2F4F8D2F4F8D2F4F8D2F4F8D2F4F8D2F4F8 + D1F6FCD0FDFFDA9441E7AC6FB16F18000000000000000000B16F18E8AE72D991 + 3DCFFCFFCFF5FCD1F6FCD6F9FDD1F6FCD2F4F8CEF3F8D1F6FCD6FEFF858D8E43 + 3D3B748080DAFDFFD1F6FCCEF3F8CEF3F8CEF3F8D2F4F8D1F6FCD2F9FED2F9FE + CFF5FCCDFAFEDA9441E8AE72B06D16000000000000000000B06D16E9B076D991 + 3DCDFAFECFF5FC849092859394839091CFF5FCCDF1F6CEF3F8D1F6FCDAFDFF81 + 8D8E3731316E787AD2F9FECEF3F8CDF1F6CDF1F6CDF5FA839091859394839091 + D1F6FCCAF9FFD9913DE9B076B06D16000000000000000000B06D16EBB279D68D + 3AD0FDFFCAF4F9CDF5FACFF5FCCDF5FAC9F2F9C8F0F5C9F2F9CDF5FAD6FEFF7A + 86883C3434707B7DD2F9FEC8F0F5C8F0F5C8F0F5C9F2F9CDF5FACDF5FACDF5FA + CAF4F9D0FDFFD68D3AEBB279B06D16000000000000000000B06D16EDB77ED68D + 3ACFFCFFC6F1F7C8F0F5C8F0F5C8F0F5C8F0F5C8F0F5CAF4F9D0FDFF78848541 + 3838788485D0FDFFCAF4F9C8F0F5C8F0F5C8F0F5C8F0F5C8F0F5C8F0F5C8F0F5 + C6F1F7CFFCFFD68D3AEDB77EB06D16000000000000000000B5792CE4AB6DDA93 + 44CFFCFFC4EFF8C5EDF4C5EDF4C5EDF4C8F0F5C9F2F9CFFCFF7A8688483F3D7A + 8688D0FDFFC9F2F9C8F0F5C5EDF4C5EDF4C5EDF4C5EDF4C5EDF4C5EDF4C5EDF4 + C5F1F8CFFCFFDA9344E4AB6DB5792C000000000000000000C0955CD49954E19E + 58D2D5C4BEF2FDC4EFF8C3F0F7C4EFF8C5F1F8CAF9FF7D898A4E46437D898ACD + FAFEC5F1F8C1EDF5C2ECF3C2ECF3C5EDF4C2ECF3C2ECF3C3F0F7C3F0F7C3F0F7 + C1F0F9D2D5C4E19E58D49954C0955C000000000000000000000000BC7A29F0B5 + 7ACFB082C4F0FFC3F0F7758385C5F1F8CAF9FF818D8E554C4A818D8ECAF9FFC3 + F0F7C1EDF5C0EBF2C2ECF3C0EBF2C0EBF2C0EBF2C0EBF2C3F0F7758385C3F0F7 + C4F0FFCFB082F0B57ABC7A29000000000000000000000000000000B1711DE4AB + 6DE09B51C4D9D8BFECF9C1F0F9C1F0F98390915C524F849092C5F7FFC3F0F7BE + ECF3C1EDF5BEECF3BCEAF1BCEAF1BCEAF1BCEAF1BEECF3BEECF3BEEDF6BFECF9 + C4D9D8E09B51E4AB6DB1711D000000000000000000000000000000000000C181 + 33F2BA82D19B5AB9E4FABBECF5C1F0F9839091859394C5F7FFBEEDF6BEECF3BF + ECF9728386BFECF9BCEAF1BCEAF1BEECF3BEEDF6BEECF3BBECF5BBECF5B9E4FA + D19B5AF2BA82C18133000000000000000000000000000000000000000000B579 + 2CD99E5AEAAD6CC6A67AB0DEF5B8E7F4BEF2FD718588BEEDF6BAEAF4B9E8F1BE + EDF6718588BEEDF6B8E7F4B7E8F1BAEAF46D7E81BBECF5B6E4F1B0DEF5C6A67A + EDB071D99E5AB5792C0000000000000000000000000000000000000000000000 + 00AF6C14EEB880EAAD6CC59E6AACD3E6AEDDF0B7E8F5BAEAF4B7E8F1B7E8F1BB + ECF56E8082BBECF5B7E8F1B7E8F1BAEAF4B6E7F4AEDDF0ACD3E6C59E6AEAAD6C + EEB880AF6C140000000000000000000000000000000000000000000000000000 + 00000000B4711CF2BA82EDB071CF914CB5B6A7A2D2EEA6D3E9AADAEAAFE0EEB2 + E4F0B6E4F1B2E4F0AFE0EEAADAEAA6D3E9A2D2EEB5B6A7CF914CF0B57AEEB880 + B4711C0000000000000000000000000000000000000000000000000000000000 + 00000000000000AF6C14DCA362F9C692E39F57CA8B44B2AE99A4BFC899CDEC9A + CCEB9ACCEB9ACCEB99CDECA4BFC8B2AE99CA8B44E39F57F9C692DBA362AF6C13 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000B5792CC38437EEB880FCC996E6A561DA9142D0822CD0 + 822CD0822CD0822CD0822CDA9142E6A561FCC996EEB880C38437B5792C000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000B1711DBE7F2EDEA767F2C18DFFD5A8FF + D5A8FFD5A8FFD5A8FFD5A8F2C18DDEA767BE7F2EB1711D000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000C79B61B87C2FAF6B13AF + 6B13AF6B13AF6B13AF6B13B87C2FC79B61000000000000000000000000000000 + 000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFF0 + 07FFFF8000FFFF00007FFE00003FFC00001FF800000FF0000007E0000003E000 + 0003E0000003C0000001C0000001C0000001C0000001C0000001C0000001C000 + 0001C0000001C0000001E0000003E0000003F0000007F0000007F800000FFC00 + 001FFE00003FFF00007FFFC001FFFFF007FF2800000010000000200000000100 + 1800000000000003000064000000640000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000000000A2937E96 + 816596816599856C000000000000000000000000000000000000000000000000 + 000000000000A38660C27F2FD18F42D99749D99749D79547C9883AB47E3D0000 + 00000000000000000000000000000000000000AD7E45D79547E1C595E4EEE0E7 + FFFFE7FFFFE6FAF7E3DCBEDDA765C88639000000000000000000000000000000 + A77E4AD9994FE0E4D0CFE6E6E1FCFDE7FFFFBFD0D0E1FCFDCFE6E6E1FCFADEB6 + 7EC9883A000000000000000000000000D19147DCD6B7DCFCFEDCFAFCDBF9FBDC + FAFCCBE4E6DCFAFADCFAFCDCFAFCDCFAFADCA868B98443000000000000B88B52 + DCA868D6FAFDC5E0E3D7F6F9D9F9FCD9F9FCD9F9FCD7F6F9D7F6F9D9F9FCC5E1 + E4D8D6BBD19147000000000000C88A41D6C398D1F5F8D1F5F8D1F5F8AFC5C789 + 9595D6FAFDD1F5F8D1F5F8D1F5F8D1F5F8D2F4F4DD9D56A7967F000000CC8E45 + D2C59DBCDCE1ABC4C7CEF3F8D1F5F88995957C8A8ACDF5FACDF1F6BDDBE0ABC4 + C7CDF8FDE0A059A4927A000000CE9149D2C59DC9F2F8C9F2F8C9F1F6CDF5FA82 + 91927D8C8DC9F2F8C8EFF4C9F1F6C9F2F8CBF7FBE0A059A4927A000000C7904E + D7C097C3EDF5C4EDF5C7F2F9859495829192C7F2F9C2ECF3C2ECF3C4EDF5C4ED + F5C9EBEDDD9D56000000000000B49976E0AB6EC2E9F2AED5DB89999A87989AC2 + F1F8BFECF3BEEAF1BEEAF1BFECF3ADD3DBCDC5AACE9149000000000000000000 + CF934ECEB48EB9E8F68EA6AABEEEF7BCEBF497B8BEBAE8F2A8D0D7BAE8F2BAD4 + D7E2A869B69B78000000000000000000000000DFA463CBAC83AFD3DEAFE0EEB4 + E6F1A3CDD6B1E2EEADDDEFB7BDB2E3AE74C7985D000000000000000000000000 + 000000000000D29854E5AA6CC5A881B5A78CB5A78BB9A789D7A975E2A869C095 + 5E000000000000000000000000000000000000000000000000B99E7ACF9B5BD7 + A05DD7A05DD49D5BCC9E64000000000000000000000000000000FFFF0000FC3F + 0000F00F0000E00700B2C003D291C0019A51800155E28000E5FF8000FFFF8000 + FFE18001E5FF8001FFFFC001A1E5E003E5FFF007FEFEF81FFFE5280000002000 + 0000400000000100200000000000001000006400000064000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000001000000070000000E00000013000000160000 + 0016000000160000001600000016000000130000000E00000007000000010000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000002000000090000001500000024000000320000003C000000410000 + 00430000004300000043000000410000003C0000003200000024000000150000 + 0009000000020000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000600000014000000280000003C6741107C996117C3AA6B19EAB2701AFFB270 + 19FFB27019FFB27019FFB2701AFFAA6B19EA996117C36741107C0000003C0000 + 0028000000140000000600000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000001000000070000 + 001C000000377349128AB06F1AF9B77521FFC48032FFCB883BFFD28D43FFD18D + 42FFD18D42FFD18D42FFD28D43FFCB883BFFC48032FFB77521FFB06F1AF97349 + 128A000000370000001C00000007000000010000000000000000000000000000 + 00000000000000000000000000000000000000000001000000080000001F1910 + 0446AB6C19EDBA7724FFCC883CFFD59048FFDB9B4DFFDD9C4EFFE2A352FFE2A2 + 51FFE2A250FFE2A251FFE2A352FFDD9C4EFFDB9B4DFFD59048FFCC883CFFBA77 + 24FFAB6C19ED191004460000001F000000080000000100000000000000000000 + 000000000000000000000000000000000000000000070000001F3D260956B26F + 19FFC68436FFD6934BFFDC9B4DFFE1A75AFFE3CEA3FFE7EEE0FFE9FFFFFFE9FF + FFFFE9FFFFFFE9FFFFFFE9FFFFFFE7EEE0FFE3CEA3FFE1A75AFFDC9B4DFFD693 + 4BFFC68436FFB26F19FF3D2609560000001F0000000700000000000000000000 + 0000000000000000000000000000000000060000001C3C260953B4711CFFD18F + 47FFD9974EFFE09E4DFFE2D3B0FFE6FFFFFFE5FFFFFFE4FFFFFFE4FFFFFFE6FF + FFFFE7FFFFFFE6FFFFFFE4FFFFFFE4FFFFFFE5FFFFFFE6FFFFFFE2D3B0FFE09E + 4DFFD9974EFFD18F47FFB4711CFF3C2609530000001C00000006000000000000 + 0000000000000000000000000002000000141E130541B16F18FFD29149FFDB99 + 50FFDFA256FFE2F3ECFFE4FFFFFFE5FFFFFFE3FFFFFFE2FDFEFFE3FDFEFFE6FF + FFFF99A1A1FFE6FFFFFFE3FDFEFFE2FDFEFFE3FFFFFFE5FFFFFFE4FFFFFFE2F3 + ECFFDFA256FFDB9950FFD29149FFB16F18FF1E13054100000014000000020000 + 000000000000000000000000000900000028AC6C19ECC9883CFFDB9B52FFDEA1 + 54FFE0FFFFFFE0FFFFFFE1FFFFFF959D9CFFE1FEFFFFDFFBFCFFE0FCFDFFE4FF + FFFF99A3A1FFE4FFFFFFE0FCFDFFDFFBFCFFE1FEFFFF959D9CFFE1FFFFFFE0FF + FFFFE0FFFFFFDEA154FFDB9B52FFC9883CFFAC6C19EC00000028000000090000 + 00000000000000000001000000157D4F1381BC7A28FFDC9C59FFDE9A49FFDEF1 + EBFFDEFFFFFFDEFCFDFFDEFCFDFFDFFDFEFFDEFCFDFFDDFAFBFFDEFBFCFFE1FF + FFFF949E9EFFE1FFFFFFDEFBFCFFDDFAFBFFDEFCFDFFDFFDFEFFDEFCFDFFDEFC + FDFFDEFFFFFFDEF1EBFFDE9A49FFDC9C59FFBC7A28FF7D4F1381000000150000 + 0001000000000000000700000024B06E19F9D3934DFFDD9C50FFDCCFABFFDBFF + FFFFDCFCFFFFDBFAFDFFDAF8FCFFDAF8FCFFDAF8FBFFDAF8FBFFDAF8FBFFDCFA + FDFFDDFBFEFFDCFAFDFFDAF8FBFFDAF8FBFFDAF8FBFFDAF8FCFFDAF8FCFFDBFA + FDFFDCFCFFFFDBFFFFFFDCCFABFFDD9C50FFD3934DFFB06E19F9000000240000 + 0007000000000000000E774B136BB97825FFE0A15EFFDC9E52FFD8FAFFFFDAFD + FFFF8E9798FFDAFAFDFFD8F7FAFFD8F7FAFFD8F7FAFFD9F8FBFFD9F8FBFFD8F8 + FBFFD8F8FBFFD8F7FAFFD8F7FAFFD8F7FAFFD8F7FAFFD8F7FAFFD8F7FAFFDAFA + FDFF8E9798FFDAFDFFFFD8FAFFFFDC9E52FFE0A15EFFB97825FF774B136B0000 + 000E00000000000000139E6417BCCD8D44FFDF9E55FFD8C59CFFD6FDFFFFD7F9 + FDFFD8F9FCFFD7F8FBFFD6F6F9FFD6F6F9FFD8F9FCFFDBFDFFFFDCFDFFFFD9FA + FDFFD7F7FAFFD6F6F9FFD6F6F9FFD6F6F9FFD6F6F9FFD6F6F9FFD6F6F9FFD7F8 + FBFFD8F9FCFFD7F9FDFFD6FDFFFFD8C59CFFDF9E55FFCD8D44FF9E6417BC0000 + 00130000000000000016AB6B17E8DA9D5AFFDC984AFFD5E4D8FFD3F9FFFFD3F6 + F9FFD3F5F8FFD3F5F8FFD3F5F8FFD4F6F9FFD8FCFFFF868D8EFF828A8BFFDDFF + FFFFD6FAFDFFD3F6F9FFD3F5F8FFD3F5F8FFD3F5F8FFD3F5F8FFD3F5F8FFD3F5 + F8FFD3F5F8FFD3F6F9FFD3F9FFFFD5E4D8FFDD994BFFDA9D5AFFAB6B17E80000 + 00160000000000000016B16E17FFE7AC6FFFDA9441FFD0FFFFFFD1F7FCFFD2F5 + F9FFD2F5F9FFD2F5F9FFD1F4F8FFD2F5F9FFD6FBFFFF899190FF4F4745FF7C88 + 88FFDDFFFFFFD5F9FDFFD2F5F9FFD1F4F8FFD1F4F8FFD1F4F8FFD1F4F8FFD2F5 + F9FFD2F5F9FFD2F5F9FFD1F7FCFFD0FFFFFFDA9341FFE7AC6FFFB16E17FF0000 + 00160000000000000016B06E16FFE8AE72FFD9923EFFCDFBFFFFCFF5FCFFD2F7 + FCFFD3F8FDFFD2F7FCFFD0F4F9FFCEF3F8FFD1F5FAFFD7FFFFFF848E8EFF433D + 3BFF748080FFDAFFFFFFD1F6FBFFCEF2F7FFCEF2F7FFCEF2F7FFD0F4F9FFD2F7 + FCFFD3F8FDFFD2F7FCFFCFF5FCFFCDFBFFFFD9923EFFE8AE72FFB06E16FF0000 + 00160000000000000016B06D16FFE9B076FFD9903DFFCBFAFFFFCFF6FCFF8390 + 91FF859394FF839091FFCFF4FAFFCCF1F7FFCDF2F7FFD0F6FCFFDAFFFFFF818B + 8DFF373131FF6E787AFFD3FAFFFFCDF2F7FFCCF1F6FFCCF1F6FFCFF4FAFF8390 + 91FF859394FF839091FFCFF6FCFFCBFAFFFFD9903DFFE9B076FFB06D16FF0000 + 00160000000000000016B06D16FFEBB279FFD78E3BFFD0FDFFFFCAF3FAFFCDF5 + FAFFCEF6FBFFCDF5FAFFCAF2F7FFC9F0F5FFC9F1F6FFCDF6FBFFD7FFFFFF7987 + 89FF3C3434FF707B7DFFCFF9FEFFCAF1F6FFC9F0F5FFC9F0F5FFCAF2F7FFCDF5 + FAFFCEF6FBFFCDF5FAFFCAF3FAFFD0FDFFFFD78E3BFFEBB279FFB06D16FF0000 + 00160000000000000013B06D16FFEDB77EFFD68D3AFFCFFCFFFFC6F1F7FFC8F0 + F5FFC8F0F5FFC8F0F5FFC7EFF4FFC8F0F5FFCAF4F9FFD2FDFFFF788485FF4138 + 38FF778385FFD2FEFFFFCAF3F8FFC7EFF4FFC7EFF4FFC7EFF4FFC7EFF4FFC8F0 + F5FFC8F0F5FFC8F0F5FFC6F1F7FFCFFCFFFFD68D3AFFEDB77EFFB06D16FF0000 + 0013000000000000000EAC6B16E6E3AA6CFFDA9344FFD0FBFFFFC4EFF8FFC5ED + F5FFC5EDF5FFC5EDF4FFC6EEF5FFC8F1F9FFCFFBFFFF7B8688FF483F3DFF7A86 + 88FFD0FCFFFFC9F2F9FFC6EEF5FFC5EDF4FFC5EDF4FFC5EDF4FFC5EDF4FFC5ED + F4FFC5EDF5FFC5EDF5FFC4EFF8FFD0FBFFFFDA9344FFE3AA6CFFAC6B16E60000 + 000E0000000000000007A66917B3D49954FFE19E58FFD2D5C4FFC1F0FBFFC3EE + F6FFC4EFF6FFC4EEF6FFC5F1F8FFCBF9FFFF7E8A8BFF4E4643FF7D898BFFCCFA + FFFFC5F1F8FFC2EDF4FFC2ECF3FFC2ECF3FFC2ECF3FFC2ECF3FFC2ECF3FFC3EE + F5FFC4EFF6FFC3EEF6FFC1F0FBFFD2D5C4FFE19E58FFD49954FFA66917B30000 + 00070000000000000001945E1656BC7B2AFFF0B67BFFCFB082FFC4F0FFFFC2F0 + F8FF758385FFC5F1F9FFC8F8FFFF808D8FFF554C4AFF808D8EFFC9F9FFFFC3F0 + F7FFC1EDF4FFC0EBF2FFC0EBF2FFC0EBF2FFC0EBF2FFC0EBF2FFC0EBF3FFC2EE + F5FF758385FFC2F0F8FFC4F0FFFFCFB082FFF0B67BFFBC7B2AFF945E16560000 + 0001000000000000000000000009AF6D16F7E4AB6DFFE09B51FFC4D9D8FFBFEC + F9FFBFEFF7FFC2F2FAFF828E8EFF5C524FFF849092FFC6F7FFFFC0EFF6FFBFED + F4FFC0EEF5FFBFECF3FFBDEAF1FFBDEAF1FFBDEAF1FFBDEBF1FFBDEBF2FFBEEC + F3FFBFEFF6FFBFECF9FFC4D9D8FFE09B51FFE4AB6DFFAF6D16F7000000090000 + 00000000000000000000000000029D621766C18133FFF2BA83FFD19B5AFFB9E4 + FAFFBBEBF6FFC0F1FAFF838F8FFF869394FFC4F7FFFFBEEDF6FFBCEBF3FFBFEE + F7FF728386FFBFEEF7FFBCEAF2FFBBE9F1FFBDEBF3FFBDECF5FFBDEBF3FFBBEB + F4FFBBEAF5FFB9E4FAFFD19B5AFFF2BA82FFC18133FF9D621767000000020000 + 000000000000000000000000000000000006AF6D17E7D99F5BFFEAAD6CFFC6A6 + 7AFFB1DEF5FFB8E7F4FFBEF2FDFF718588FFBDEEF7FFB9E8F2FFB9E8F2FFBDED + F7FF718487FFBDEDF7FFB9E8F2FFB8E8F1FFBBEBF4FF6D7E81FFBBEDF6FFB6E4 + F1FFB0DEF5FFC6A67AFFEDB071FFD99F5BFFAF6D17E700000006000000000000 + 0000000000000000000000000000000000018E5A1527AF6C14FFEEB880FFEBAE + 6DFFC69E6BFFACD3E6FFAFDDF1FFB7E8F5FFB8EBF4FFB7E8F1FFB7E8F1FFBBEC + F5FF6E8082FFBBECF5FFB7E8F1FFB7E8F1FFB8EBF4FFB6E7F4FFAEDDF0FFACD3 + E6FFC59E6AFFEBAE6DFFEEB880FFAF6C14FF6E45111200000000000000000000 + 000000000000000000000000000000000000000000019D621738B4721CFFEFBA + 83FFEDB172FFCF914CFFB5B6A7FFA2D2EEFFA6D3E9FFAADAEAFFAFE0EEFFB2E4 + F0FFB3E5F2FFB2E4F0FFAFE0EEFFAADAEAFFA6D3E9FFA2D2EEFFB5B6A7FFCF91 + 4CFFF0B578FFEFBA82FFB4721CFF8F5A15230000000100000000000000000000 + 0000000000000000000000000000000000000000000000000001935C1522AF6C + 14FFDCA362FFF9C692FFE39F57FFCA8B44FFB2AE99FFA4BFC8FF99CDECFF9ACC + EBFF9ACCEBFF9ACCEBFF99CDECFFA4BFC8FFB2AE99FFCA8B44FFE39F57FFF9C6 + 92FFDBA362FFAF6C13FF945D1623000000010000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000007046 + 1110AF6C16E6C38437FFEDB880FFFCC996FFE6A561FFDA9043FFD0822DFFD182 + 2CFFD1822CFFD1822CFFD0822DFFDA9043FFE6A561FFFCC996FFEDB880FFC384 + 37FFAF6C16E67046111000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000002A769175FAF6D15F7BE7F2EFFDEA767FFF2C18DFFFFD5A9FFFFD5 + A8FFFFD5A8FFFFD5A8FFFFD5A9FFF2C18DFFDEA767FFBE7F2EFFAF6D15F7A769 + 175F000000020000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000001A769184CAC6B16ACAF6C15E2AF6B13FFAF6B + 13FFAF6B13FFAF6B13FFAF6B13FFAF6C15E2AC6B16ACA769184C000000010000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000FFFFFFFFFFC001FFFF00007FFE00003FF800000FF0000007F0000007E000 + 0003C0000001C000000180000000800000008000000080000000800000008000 + 000080000000800000008000000080000000800000008000000080000000C000 + 0001C0000001E0000003E0000007F0000007F800000FFE00003FFF00007FFFC0 + 01FF280000001000000020000000010020000000000000040000640000006400 + 0000000000000000000000000000000000000000000000000000000000000000 + 0002000000080000000B0000000B0000000A0000000500000000000000000000 + 0000000000000000000000000000000000000000000000000002000000121910 + 043C50330C8759380CA059380CA157360C9A4028096500000020000000070000 + 0000000000000000000000000000000000000000000206040122764B13ABC27F + 2FFED18F42FFD9974AFFD99749FFD79547FFCA883AFFAA6D23E0311F07620000 + 000C000000000000000000000000000000020F0902259D6521D5D59347FFE1C5 + 95FFE4EEE0FFE7FFFFFFE7FFFFFFE6FAF7FFE3DCBEFFDDA765FFC88639FF4B2F + 0B720000000A000000000000000000000012915D1CCBD9994FFFE0E4D0FFCFE6 + E6FFE1FDFEFFE3FDFEFFBFD0D0FFE1FCFDFFCFE6E6FFE1FCFAFFDEB67EFFC988 + 3BFF321F075A00000003000000024B2F0B6DD29147FFDCD6B7FFDCFCFEFFDCFA + FCFFDBF9FBFFDDFBFCFFCBE4E6FFDBF9FBFFDCFAFCFFDCFAFCFFDCFAFAFFDCA8 + 67FFAF7228DE0000001000000008A66D24C9DCA868FFD7FBFEFFC5E0E3FFD7F6 + F9FFD9F9FCFFD9F9FCFFD7F7FAFFD7F6F9FFD7F6F9FFD7F7FAFFC5E1E4FFD8D6 + BBFFD19147FF452B0A520000000BC7883DF9D6C398FFD2F6FBFFD2F5F8FFD2F5 + F8FFAFC5C7FF8A9695FFD6FAFCFFD2F4F8FFD2F4F8FFD2F4F8FFD2F5F8FFD2F4 + F4FFDE9D55FF57360B850000000BCC8E45FFD2C59EFFBCDCE1FFABC4C7FFCEF3 + F8FFD1F7FBFF889595FF7C8A8AFFCFF5FAFFCDF1F6FFBDDBE0FFABC4C7FFCDF8 + FDFFE0A058FF58360B8A0000000ACE9048FFD3C59CFFC9F2F8FFCAF2F7FFC8F0 + F5FFCCF6FAFF829091FF7D8C8DFFCAF3F8FFC8EFF4FFC9F1F6FFCAF2F7FFCBF7 + FBFFE1A15BFF58360B8A00000005C2853BE6D7C097FFC3EEF7FFC4EDF5FFC7F2 + F9FF859495FF829293FFC8F3F9FFC3ECF3FFC3ECF3FFC3EDF4FFC4EDF5FFC9EB + EDFFDC9D57FF54350B6C000000007F511595E0AB6EFFC2E9F2FFAED5DBFF8999 + 9AFF87989AFFC2F1F8FFC0ECF3FFBEEAF1FFBEEAF1FFBFECF3FFADD3DBFFCDC5 + AAFFCF924AFD311F0718000000003420071CCE914AF9CEB48EFFB9E8F6FF8EA6 + AAFFBEEEF7FFBCEBF4FF97B8BEFFBAE8F1FFA8D0D7FFBAE9F3FFBAD4D7FFE2A9 + 6AFF83541895000000000000000000000000764A1058DFA463FFCBAC83FFAFD3 + DEFFAFE0EEFFB4E6F1FFA3CDD6FFB1E2EEFFADDDEFFFB7BDB2FFE3AE74FFB87C + 31C83722080500000000000000000000000000000000905A134CD19650F9E5AA + 6CFFC5A881FFB5A78CFFB5A78BFFB9A789FFD7A975FFE3A868FFAA7027BD4A2E + 0B0900000000000000000000000000000000000000000000000053340B188555 + 1691CA8F47E3D7A05DFFD7A05DFFD39B57F8BB7E30BE72470E56000000000000 + 00000000000000000000F81F0000E0070000C003000080010000800000000000 + 00000000FFFF0000FFFF0000FFFF0000F1F10000B7B78000959580019393C001 + 9393E0039393F00F9696 + } + Position = poDesktopCenter + LCLVersion = '2.0.10.0' + object Button1: TButton + Left = 40 + Height = 26 + Top = 88 + Width = 88 + Caption = 'Ok' + OnClick = Button1Click + TabOrder = 0 + end + object Label1: TLabel + Left = 72 + Height = 15 + Top = 41 + Width = 53 + Caption = 'Time''s Up' + ParentColor = False + end + object Image1: TImage + Left = 24 + Height = 32 + Top = 33 + Width = 32 + Picture.Data = { + 055449636F6E662300000000010004002020000001000800A808000046000000 + 101000000100080068050000EE0800002020000001002000A8100000560E0000 + 101000000100200068040000FE1E000028000000200000004000000001000800 + 0000000000000000000000000000000000000000000000000000000037313100 + 3C34340041383800433D3B00483F3D004E4643004F474500554C4A005C524F00 + 6E787A00707B7D00AF6B1300AF6C1300AF6C1400B06D1600B16F1800B2701900 + B1711D00B4711C00B7752100BA772400B9782500B1762A00B2782B00B5792C00 + BC7A2900B87C2F00BE7F2E00D0822C00C1813300C4803200C3843700C6843600 + CB883B00C9883C00CC883C00D68D3A00D9913D00B1864D00B78C5300B39C7E00 + CA8B4400CD8D4400D18D4200D18F4700CF914C00DA914200DA944100DA934400 + D2914900D5914900D3934D00D9974E00DD994900DB9B4D00DC9B4D00DD9C4E00 + C0955C00D4995400DB9A5100DC9D5100DF9E5500D19B5A00D99E5A00DC9C5900 + E09E4D00E09B5100E39F5700E19E5800DEA15500E2A25100E1A75A00E0A15E00 + C79B6100C59E6A00DBA36200DCA36200DEA76700C6A67A00E6A56100E3AA6C00 + E4AB6D00E7AC6F00EAAD6C00E8AE7200EDB07100E9B07600EBB27900EDB77E00 + F0B57A006D7E81006E8082007480800072838600758385007184870078848500 + 718588007A8688007D898A00828A8B00818B8D00818D8E00858D8E0083909100 + 8490920085939400899190008E979800949D9C00BDA58700B2AE990099A2A100 + B5B6A700CFB08200EEB88000F2BA8200D8C59C00F2C18D00F9C69200FCC99600 + DCCFAB00E3CEA300FFD5A800E2D3B000A4BFC8009ACCEB0099CDEC00ACD3E600 + A6D3E900A2D2EE00AADAEA00AEDDF000B0DEF500AFE0EE00B2E4F000B6E4F100 + B6E7F400B8E7F400B7E8F100B7E8F500B9E8F100BCEAF100BEECF300BAEAF400 + BBECF500BEEDF600B9E4FA00BFECF900BEF2FD00D2D5C400C4D9D800D5E4D800 + DEF1EB00C0EBF200C2ECF300C1EDF500C5EDF400C4EFF800C3F0F700C6F1F700 + C8F0F500CDF1F600C1F0F900C5F1F800C4F0FF00C5F7FF00C9F2F900CEF3F800 + CAF4F900CDF5FA00CFF5FC00CAF9FF00CDFAFE00CFFCFF00D2F4F800D5F6F900 + D1F6FC00D8F7FA00D7F8FB00D2F9FE00D6F9FD00D0FDFF00D6FEFF00D9F8FB00 + DDFAFB00D9F9FC00DDFAFC00DAFDFF00DDFDFE00E7EEE000E2F3EC00E1FEFE00 + E5FFFF00E9FFFF0090006200B0007800CF008E00F000A400FF11B300FF31BE00 + FF51C700FF71D100FF91DC00FFB1E500FFD1F000FFFFFF00000000002C002F00 + 4B0050006900700087009000A500B000C400CF00E100F000F011FF00F231FF00 + F451FF00F671FF00F791FF00F9B1FF00FBD1FF00FFFFFF00000000001B002F00 + 2D0050003F007000520090006300B0007600CF008800F0009911FF00A631FF00 + B451FF00C271FF00CF91FF00DCB1FF00EBD1FF00FFFFFF000000000008002F00 + 0E005000150070001B0090002100B0002600CF002C00F0003E11FF005831FF00 + 7151FF008C71FF00A691FF00BFB1FF00DAD1FF00FFFFFF000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000027181111131112182700000000000000000000000000000000000000 + 002912141F242C2C2C2C2C241F14122900000000000000000000000000000000 + 1715243338394747474747393733241517000000000000000000000000000011 + 213339487BBFC3C3C3C3C3BF7B48393321110000000000000000000000001332 + 35427DC2C2C2C2C2C3C2C2C2C2C27D423532130000000000000000000011323C + 46C0C2C2C2C1C2C271C2C2C1C2C2C2C0463C3211000000000000000017233D46 + C1C1C16EC1BCC1C271C2C1BCC16EC1C1C1463D23180000000000006F1A41369A + BEBEBEC1C1BCBCC16EC2BCBABEC1BEBEBE9A36411A6F000000000012343D7ABE + BEBCBBB9B9B9BBBCBEBCB9B9B9BBB9BCBEBD7A3D3412000000000016493DBDBD + 6DBDB3B3B9B9B9B4B9B3B3B3B3B3B3BD6DBDBD3D491600000000282B3E76B8B6 + BBB4B1B1BBBDBEBDB3B1B1B1B3B1B1B4BBB6B8763E2B2800000018403699B5B1 + B1B1B0B1BD6865BEB6B1B0B0B0B1B1B1B0B1B599364018000000105330B7B5B0 + B2B0B0B0B86C0764BEB6B1B0B0B0B0B0B0B0B2B7305310000000105526AFACB2 + B6B2B0A9B2B868045DBDB2A9A9A9B0B2B5B5ACAE30550F0000000F5726AEAC6A + 6B69ACA3A9B2BD67010AB5A9A3A3AB696B69B2AD26570F0000000F5825B7AAAB + ACABA8A2A8ABB863020BB5A2A2A2A8ABABABAAB725580F0000000F5925AFA1A2 + A2A2A2A2AAB7610361B7AAA2A2A2A2A2A2A2A1AF25590F000000195231AF9F9E + 9E9EA2A8AF630563B7A8A29E9E9E9E9E9E9EA5AF3152190000003A3B4597969F + A09FA5AD640664AEA59D9C9C9E9C9CA0A0A0A497453B3A000000001A5A73A6A0 + 5FA5AD670867ADA09D9B9C9B9B9B9BA05FA0A6735A1A00000000001252439895 + A4A469096AA7A0909D908F8F8F8F90909395984352120000000000001E753F94 + 92A4696BA79390955E958F8F9093909292943F751E000000000000001940544F + 868B966293918E9362938B8C915B9289864F56401900000000000000000E7454 + 4B81858D918C8C925C928C8C918A85814B54740E000000000000000000001375 + 562E728382848788898887848283722E5A74130000000000000000000000000E + 4D78442A707E807F7F7F807E702A44784C0D0000000000000000000000000000 + 19207479502F1D1D1D1D1D2F5079742019000000000000000000000000000000 + 0000121C4E777C7C7C7C7C774E1C120000000000000000000000000000000000 + 000000004A1B0C0C0C0C0C1B4A0000000000000000000000FFFFFFFFFFFFFFFF + FFFFFFFFFFF007FFFF8000FFFF00007FFE00003FFC00001FF800000FF0000007 + E0000003E0000003E0000003C0000001C0000001C0000001C0000001C0000001 + C0000001C0000001C0000001C0000001E0000003E0000003F0000007F0000007 + F800000FFC00001FFE00003FFF00007FFFC001FFFFF007FF2800000010000000 + 2000000001000800000000000000000000000000000000000000000000000000 + 00000000B47E3D00C27F2F00AD7E4500A77E4A00C8863900C9883A00B9844300 + B88B52009681650099856C00A3866000A4927A00A2937E00A7967F00B4997600 + B69B7800B99E7A00C88A4100CC8E4500D18F4200C7904E00CE914900CF934E00 + D1914700D5934700D7954700D9974900D9994F00C0955E00C7985D00CF9B5B00 + D2985400DD9D5600D49D5B00D7A05D00E0A05900CC9E6400DFA46300DDA76500 + DCA86700DCA86800D7A97500DEB67E00E2A86900E0AB6E00E5AA6C00E3AE7400 + 7C8A8A007D8C8D0082919200859495008995950087989A0089999A00B5A78B00 + B5A78C00B9A789008EA6AA0097B8BE00B7BDB200C5A88100CBAC8300CEB48E00 + D7C09700D6C39800D2C59D00E1C59500CDC5AA00DCD6B700D8D6BB00E3DCBE00 + ABC4C700AFC5C700A3CDD600A8D0D700ADD3DB00AED5DB00AFD3DE00BFD0D000 + BAD4D700ADDDEF00BDDBE000BCDCE100AFE0EE00B1E2EE00B4E6F100BAE8F200 + BEEAF100BFECF300B9E8F600BCEBF400BEEEF700E0E4D000C5E0E300C5E1E400 + CBE4E600CFE6E600C9EBED00C2E9F200C2ECF300C3EDF500C4EDF500C8EFF400 + C9F1F600CDF1F600C2F1F800C7F2F900C9F2F800CEF3F800CBF7FB00CDF5FA00 + CDF8FD00D2F4F400D1F5F800D7F6F900D6FAFD00DBF9FB00DCFAFA00D9F9FC00 + DCFAFC00DCFCFE00E4EEE000E6FAF700E1FCFA00E1FCFD00E7FFFF00FFFFFF00 + 000000002F26000050410000705B000090740000B08E0000CFA90000F0C30000 + FFD21100FFD83100FFDD5100FFE47100FFEA9100FFF0B100FFF6D100FFFFFF00 + 000000002F1400005022000070300000903E0000B04D0000CF5B0000F0690000 + FF791100FF8A3100FF9D5100FFAF7100FFC19100FFD2B100FFE5D100FFFFFF00 + 000000002F030000500400007006000090090000B00A0000CF0C0000F00E0000 + FF201200FF3E3100FF5C5100FF7A7100FF979100FFB6B100FFD4D100FFFFFF00 + 000000002F000E00500017007000210090002B00B0003600CF004000F0004900 + FF115A00FF317000FF518600FF719C00FF91B200FFB1C800FFD1DF00FFFFFF00 + 000000002F0020005000360070004C0090006200B0007800CF008E00F000A400 + FF11B300FF31BE00FF51C700FF71D100FF91DC00FFB1E500FFD1F000FFFFFF00 + 000000002C002F004B0050006900700087009000A500B000C400CF00E100F000 + F011FF00F231FF00F451FF00F671FF00F791FF00F9B1FF00FBD1FF00FFFFFF00 + 000000001B002F002D0050003F007000520090006300B0007600CF008800F000 + 9911FF00A631FF00B451FF00C271FF00CF91FF00DCB1FF00EBD1FF00FFFFFF00 + 0000000008002F000E005000150070001B0090002100B0002600CF002C00F000 + 3E11FF005831FF007151FF008C71FF00A691FF00BFB1FF00DAD1FF00FFFFFF00 + 000000000000000000000000000000000000000000000D09090A000000000000 + 000000000B02141B1B1A060100000000000000031A437A7E7E7B472705000000 + 0000041C5D617D7E4F7D617C2B06000000001845797875786076787876290700 + 000829745E737777777373775F4618000012417272724934747272727271210E + 00134253486D7234306F69524870240C0016426C6C686F32316C67686C6E240C + 00154065666B33326B64646666622100000F2D634D36356A595858594C441600 + 0000173F5A3A5C5B3B574B57502C1000000000263E4E54564A55513C2F1E0000 + 00000000202E3D3837392A2C1D0000000000000000111F232322250000000000 + FFFF0000FC3F0000F00F0000E0070000C0030000C00100008001000080000000 + 80000000800000008001000080010000C0010000E0030000F0070000F81F0000 + 2800000020000000400000000100200000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000001000000070000000E00000013 + 0000001600000016000000160000001600000016000000130000000E00000007 + 0000000100000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000002000000090000001500000024000000320000003C + 00000041000000430000004300000043000000410000003C0000003200000024 + 0000001500000009000000020000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000600000014000000280000003C6741107C996117C3AA6B19EA + B2701AFFB27019FFB27019FFB27019FFB2701AFFAA6B19EA996117C36741107C + 0000003C00000028000000140000000600000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000001 + 000000070000001C000000377349128AB06F1AF9B77521FFC48032FFCB883BFF + D28D43FFD18D42FFD18D42FFD18D42FFD28D43FFCB883BFFC48032FFB77521FF + B06F1AF97349128A000000370000001C00000007000000010000000000000000 + 0000000000000000000000000000000000000000000000000000000100000008 + 0000001F19100446AB6C19EDBA7724FFCC883CFFD59048FFDB9B4DFFDD9C4EFF + E2A352FFE2A251FFE2A250FFE2A251FFE2A352FFDD9C4EFFDB9B4DFFD59048FF + CC883CFFBA7724FFAB6C19ED191004460000001F000000080000000100000000 + 000000000000000000000000000000000000000000000000000000070000001F + 3D260956B26F19FFC68436FFD6934BFFDC9B4DFFE1A75AFFE3CEA3FFE7EEE0FF + E9FFFFFFE9FFFFFFE9FFFFFFE9FFFFFFE9FFFFFFE7EEE0FFE3CEA3FFE1A75AFF + DC9B4DFFD6934BFFC68436FFB26F19FF3D2609560000001F0000000700000000 + 0000000000000000000000000000000000000000000000060000001C3C260953 + B4711CFFD18F47FFD9974EFFE09E4DFFE2D3B0FFE6FFFFFFE5FFFFFFE4FFFFFF + E4FFFFFFE6FFFFFFE7FFFFFFE6FFFFFFE4FFFFFFE4FFFFFFE5FFFFFFE6FFFFFF + E2D3B0FFE09E4DFFD9974EFFD18F47FFB4711CFF3C2609530000001C00000006 + 0000000000000000000000000000000000000002000000141E130541B16F18FF + D29149FFDB9950FFDFA256FFE2F3ECFFE4FFFFFFE5FFFFFFE3FFFFFFE2FDFEFF + E3FDFEFFE6FFFFFF99A1A1FFE6FFFFFFE3FDFEFFE2FDFEFFE3FFFFFFE5FFFFFF + E4FFFFFFE2F3ECFFDFA256FFDB9950FFD29149FFB16F18FF1E13054100000014 + 000000020000000000000000000000000000000900000028AC6C19ECC9883CFF + DB9B52FFDEA154FFE0FFFFFFE0FFFFFFE1FFFFFF959D9CFFE1FEFFFFDFFBFCFF + E0FCFDFFE4FFFFFF99A3A1FFE4FFFFFFE0FCFDFFDFFBFCFFE1FEFFFF959D9CFF + E1FFFFFFE0FFFFFFE0FFFFFFDEA154FFDB9B52FFC9883CFFAC6C19EC00000028 + 00000009000000000000000000000001000000157D4F1381BC7A28FFDC9C59FF + DE9A49FFDEF1EBFFDEFFFFFFDEFCFDFFDEFCFDFFDFFDFEFFDEFCFDFFDDFAFBFF + DEFBFCFFE1FFFFFF949E9EFFE1FFFFFFDEFBFCFFDDFAFBFFDEFCFDFFDFFDFEFF + DEFCFDFFDEFCFDFFDEFFFFFFDEF1EBFFDE9A49FFDC9C59FFBC7A28FF7D4F1381 + 0000001500000001000000000000000700000024B06E19F9D3934DFFDD9C50FF + DCCFABFFDBFFFFFFDCFCFFFFDBFAFDFFDAF8FCFFDAF8FCFFDAF8FBFFDAF8FBFF + DAF8FBFFDCFAFDFFDDFBFEFFDCFAFDFFDAF8FBFFDAF8FBFFDAF8FBFFDAF8FCFF + DAF8FCFFDBFAFDFFDCFCFFFFDBFFFFFFDCCFABFFDD9C50FFD3934DFFB06E19F9 + 0000002400000007000000000000000E774B136BB97825FFE0A15EFFDC9E52FF + D8FAFFFFDAFDFFFF8E9798FFDAFAFDFFD8F7FAFFD8F7FAFFD8F7FAFFD9F8FBFF + D9F8FBFFD8F8FBFFD8F8FBFFD8F7FAFFD8F7FAFFD8F7FAFFD8F7FAFFD8F7FAFF + D8F7FAFFDAFAFDFF8E9798FFDAFDFFFFD8FAFFFFDC9E52FFE0A15EFFB97825FF + 774B136B0000000E00000000000000139E6417BCCD8D44FFDF9E55FFD8C59CFF + D6FDFFFFD7F9FDFFD8F9FCFFD7F8FBFFD6F6F9FFD6F6F9FFD8F9FCFFDBFDFFFF + DCFDFFFFD9FAFDFFD7F7FAFFD6F6F9FFD6F6F9FFD6F6F9FFD6F6F9FFD6F6F9FF + D6F6F9FFD7F8FBFFD8F9FCFFD7F9FDFFD6FDFFFFD8C59CFFDF9E55FFCD8D44FF + 9E6417BC000000130000000000000016AB6B17E8DA9D5AFFDC984AFFD5E4D8FF + D3F9FFFFD3F6F9FFD3F5F8FFD3F5F8FFD3F5F8FFD4F6F9FFD8FCFFFF868D8EFF + 828A8BFFDDFFFFFFD6FAFDFFD3F6F9FFD3F5F8FFD3F5F8FFD3F5F8FFD3F5F8FF + D3F5F8FFD3F5F8FFD3F5F8FFD3F6F9FFD3F9FFFFD5E4D8FFDD994BFFDA9D5AFF + AB6B17E8000000160000000000000016B16E17FFE7AC6FFFDA9441FFD0FFFFFF + D1F7FCFFD2F5F9FFD2F5F9FFD2F5F9FFD1F4F8FFD2F5F9FFD6FBFFFF899190FF + 4F4745FF7C8888FFDDFFFFFFD5F9FDFFD2F5F9FFD1F4F8FFD1F4F8FFD1F4F8FF + D1F4F8FFD2F5F9FFD2F5F9FFD2F5F9FFD1F7FCFFD0FFFFFFDA9341FFE7AC6FFF + B16E17FF000000160000000000000016B06E16FFE8AE72FFD9923EFFCDFBFFFF + CFF5FCFFD2F7FCFFD3F8FDFFD2F7FCFFD0F4F9FFCEF3F8FFD1F5FAFFD7FFFFFF + 848E8EFF433D3BFF748080FFDAFFFFFFD1F6FBFFCEF2F7FFCEF2F7FFCEF2F7FF + D0F4F9FFD2F7FCFFD3F8FDFFD2F7FCFFCFF5FCFFCDFBFFFFD9923EFFE8AE72FF + B06E16FF000000160000000000000016B06D16FFE9B076FFD9903DFFCBFAFFFF + CFF6FCFF839091FF859394FF839091FFCFF4FAFFCCF1F7FFCDF2F7FFD0F6FCFF + DAFFFFFF818B8DFF373131FF6E787AFFD3FAFFFFCDF2F7FFCCF1F6FFCCF1F6FF + CFF4FAFF839091FF859394FF839091FFCFF6FCFFCBFAFFFFD9903DFFE9B076FF + B06D16FF000000160000000000000016B06D16FFEBB279FFD78E3BFFD0FDFFFF + CAF3FAFFCDF5FAFFCEF6FBFFCDF5FAFFCAF2F7FFC9F0F5FFC9F1F6FFCDF6FBFF + D7FFFFFF798789FF3C3434FF707B7DFFCFF9FEFFCAF1F6FFC9F0F5FFC9F0F5FF + CAF2F7FFCDF5FAFFCEF6FBFFCDF5FAFFCAF3FAFFD0FDFFFFD78E3BFFEBB279FF + B06D16FF000000160000000000000013B06D16FFEDB77EFFD68D3AFFCFFCFFFF + C6F1F7FFC8F0F5FFC8F0F5FFC8F0F5FFC7EFF4FFC8F0F5FFCAF4F9FFD2FDFFFF + 788485FF413838FF778385FFD2FEFFFFCAF3F8FFC7EFF4FFC7EFF4FFC7EFF4FF + C7EFF4FFC8F0F5FFC8F0F5FFC8F0F5FFC6F1F7FFCFFCFFFFD68D3AFFEDB77EFF + B06D16FF00000013000000000000000EAC6B16E6E3AA6CFFDA9344FFD0FBFFFF + C4EFF8FFC5EDF5FFC5EDF5FFC5EDF4FFC6EEF5FFC8F1F9FFCFFBFFFF7B8688FF + 483F3DFF7A8688FFD0FCFFFFC9F2F9FFC6EEF5FFC5EDF4FFC5EDF4FFC5EDF4FF + C5EDF4FFC5EDF4FFC5EDF5FFC5EDF5FFC4EFF8FFD0FBFFFFDA9344FFE3AA6CFF + AC6B16E60000000E0000000000000007A66917B3D49954FFE19E58FFD2D5C4FF + C1F0FBFFC3EEF6FFC4EFF6FFC4EEF6FFC5F1F8FFCBF9FFFF7E8A8BFF4E4643FF + 7D898BFFCCFAFFFFC5F1F8FFC2EDF4FFC2ECF3FFC2ECF3FFC2ECF3FFC2ECF3FF + C2ECF3FFC3EEF5FFC4EFF6FFC3EEF6FFC1F0FBFFD2D5C4FFE19E58FFD49954FF + A66917B3000000070000000000000001945E1656BC7B2AFFF0B67BFFCFB082FF + C4F0FFFFC2F0F8FF758385FFC5F1F9FFC8F8FFFF808D8FFF554C4AFF808D8EFF + C9F9FFFFC3F0F7FFC1EDF4FFC0EBF2FFC0EBF2FFC0EBF2FFC0EBF2FFC0EBF2FF + C0EBF3FFC2EEF5FF758385FFC2F0F8FFC4F0FFFFCFB082FFF0B67BFFBC7B2AFF + 945E165600000001000000000000000000000009AF6D16F7E4AB6DFFE09B51FF + C4D9D8FFBFECF9FFBFEFF7FFC2F2FAFF828E8EFF5C524FFF849092FFC6F7FFFF + C0EFF6FFBFEDF4FFC0EEF5FFBFECF3FFBDEAF1FFBDEAF1FFBDEAF1FFBDEBF1FF + BDEBF2FFBEECF3FFBFEFF6FFBFECF9FFC4D9D8FFE09B51FFE4AB6DFFAF6D16F7 + 00000009000000000000000000000000000000029D621766C18133FFF2BA83FF + D19B5AFFB9E4FAFFBBEBF6FFC0F1FAFF838F8FFF869394FFC4F7FFFFBEEDF6FF + BCEBF3FFBFEEF7FF728386FFBFEEF7FFBCEAF2FFBBE9F1FFBDEBF3FFBDECF5FF + BDEBF3FFBBEBF4FFBBEAF5FFB9E4FAFFD19B5AFFF2BA82FFC18133FF9D621767 + 000000020000000000000000000000000000000000000006AF6D17E7D99F5BFF + EAAD6CFFC6A67AFFB1DEF5FFB8E7F4FFBEF2FDFF718588FFBDEEF7FFB9E8F2FF + B9E8F2FFBDEDF7FF718487FFBDEDF7FFB9E8F2FFB8E8F1FFBBEBF4FF6D7E81FF + BBEDF6FFB6E4F1FFB0DEF5FFC6A67AFFEDB071FFD99F5BFFAF6D17E700000006 + 0000000000000000000000000000000000000000000000018E5A1527AF6C14FF + EEB880FFEBAE6DFFC69E6BFFACD3E6FFAFDDF1FFB7E8F5FFB8EBF4FFB7E8F1FF + B7E8F1FFBBECF5FF6E8082FFBBECF5FFB7E8F1FFB7E8F1FFB8EBF4FFB6E7F4FF + AEDDF0FFACD3E6FFC59E6AFFEBAE6DFFEEB880FFAF6C14FF6E45111200000000 + 000000000000000000000000000000000000000000000000000000019D621738 + B4721CFFEFBA83FFEDB172FFCF914CFFB5B6A7FFA2D2EEFFA6D3E9FFAADAEAFF + AFE0EEFFB2E4F0FFB3E5F2FFB2E4F0FFAFE0EEFFAADAEAFFA6D3E9FFA2D2EEFF + B5B6A7FFCF914CFFF0B578FFEFBA82FFB4721CFF8F5A15230000000100000000 + 0000000000000000000000000000000000000000000000000000000000000001 + 935C1522AF6C14FFDCA362FFF9C692FFE39F57FFCA8B44FFB2AE99FFA4BFC8FF + 99CDECFF9ACCEBFF9ACCEBFF9ACCEBFF99CDECFFA4BFC8FFB2AE99FFCA8B44FF + E39F57FFF9C692FFDBA362FFAF6C13FF945D1623000000010000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000070461110AF6C16E6C38437FFEDB880FFFCC996FFE6A561FFDA9043FF + D0822DFFD1822CFFD1822CFFD1822CFFD0822DFFDA9043FFE6A561FFFCC996FF + EDB880FFC38437FFAF6C16E67046111000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000002A769175FAF6D15F7BE7F2EFFDEA767FFF2C18DFF + FFD5A9FFFFD5A8FFFFD5A8FFFFD5A8FFFFD5A9FFF2C18DFFDEA767FFBE7F2EFF + AF6D15F7A769175F000000020000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000001A769184CAC6B16ACAF6C15E2 + AF6B13FFAF6B13FFAF6B13FFAF6B13FFAF6B13FFAF6C15E2AC6B16ACA769184C + 0000000100000000000000000000000000000000000000000000000000000000 + 0000000000000000FFFFFFFFFFC001FFFF00007FFE00003FF800000FF0000007 + F0000007E0000003C0000001C000000180000000800000008000000080000000 + 8000000080000000800000008000000080000000800000008000000080000000 + 80000000C0000001C0000001E0000003E0000007F0000007F800000FFE00003F + FF00007FFFC001FF280000001000000020000000010020000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000002000000080000000B0000000B0000000A0000000500000000 + 0000000000000000000000000000000000000000000000000000000000000002 + 000000121910043C50330C8759380CA059380CA157360C9A4028096500000020 + 0000000700000000000000000000000000000000000000000000000206040122 + 764B13ABC27F2FFED18F42FFD9974AFFD99749FFD79547FFCA883AFFAA6D23E0 + 311F07620000000C000000000000000000000000000000020F0902259D6521D5 + D59347FFE1C595FFE4EEE0FFE7FFFFFFE7FFFFFFE6FAF7FFE3DCBEFFDDA765FF + C88639FF4B2F0B720000000A000000000000000000000012915D1CCBD9994FFF + E0E4D0FFCFE6E6FFE1FDFEFFE3FDFEFFBFD0D0FFE1FCFDFFCFE6E6FFE1FCFAFF + DEB67EFFC9883BFF321F075A00000003000000024B2F0B6DD29147FFDCD6B7FF + DCFCFEFFDCFAFCFFDBF9FBFFDDFBFCFFCBE4E6FFDBF9FBFFDCFAFCFFDCFAFCFF + DCFAFAFFDCA867FFAF7228DE0000001000000008A66D24C9DCA868FFD7FBFEFF + C5E0E3FFD7F6F9FFD9F9FCFFD9F9FCFFD7F7FAFFD7F6F9FFD7F6F9FFD7F7FAFF + C5E1E4FFD8D6BBFFD19147FF452B0A520000000BC7883DF9D6C398FFD2F6FBFF + D2F5F8FFD2F5F8FFAFC5C7FF8A9695FFD6FAFCFFD2F4F8FFD2F4F8FFD2F4F8FF + D2F5F8FFD2F4F4FFDE9D55FF57360B850000000BCC8E45FFD2C59EFFBCDCE1FF + ABC4C7FFCEF3F8FFD1F7FBFF889595FF7C8A8AFFCFF5FAFFCDF1F6FFBDDBE0FF + ABC4C7FFCDF8FDFFE0A058FF58360B8A0000000ACE9048FFD3C59CFFC9F2F8FF + CAF2F7FFC8F0F5FFCCF6FAFF829091FF7D8C8DFFCAF3F8FFC8EFF4FFC9F1F6FF + CAF2F7FFCBF7FBFFE1A15BFF58360B8A00000005C2853BE6D7C097FFC3EEF7FF + C4EDF5FFC7F2F9FF859495FF829293FFC8F3F9FFC3ECF3FFC3ECF3FFC3EDF4FF + C4EDF5FFC9EBEDFFDC9D57FF54350B6C000000007F511595E0AB6EFFC2E9F2FF + AED5DBFF89999AFF87989AFFC2F1F8FFC0ECF3FFBEEAF1FFBEEAF1FFBFECF3FF + ADD3DBFFCDC5AAFFCF924AFD311F0718000000003420071CCE914AF9CEB48EFF + B9E8F6FF8EA6AAFFBEEEF7FFBCEBF4FF97B8BEFFBAE8F1FFA8D0D7FFBAE9F3FF + BAD4D7FFE2A96AFF83541895000000000000000000000000764A1058DFA463FF + CBAC83FFAFD3DEFFAFE0EEFFB4E6F1FFA3CDD6FFB1E2EEFFADDDEFFFB7BDB2FF + E3AE74FFB87C31C83722080500000000000000000000000000000000905A134C + D19650F9E5AA6CFFC5A881FFB5A78CFFB5A78BFFB9A789FFD7A975FFE3A868FF + AA7027BD4A2E0B09000000000000000000000000000000000000000000000000 + 53340B1885551691CA8F47E3D7A05DFFD7A05DFFD39B57F8BB7E30BE72470E56 + 00000000000000000000000000000000F81FAC41E007AC41C003AC418001AC41 + 8000AC410000AC410000AC410000AC410000AC410000AC410000AC418000AC41 + 8001AC41C001AC41E003AC41F00FAC41 + } + end +end diff --git a/ui/msgbox.pas b/ui/msgbox.pas new file mode 100644 index 0000000..ab232d7 --- /dev/null +++ b/ui/msgbox.pas @@ -0,0 +1,59 @@ +unit msgbox; + +{$mode objfpc} + +interface + +uses + Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls, + ExtCtrls; + +type + + { TMsgBoxForm } + + TMsgBoxForm = class(TForm) + Button1: TButton; + Image1: TImage; + Label1: TLabel; + procedure Button1Click(Sender: TObject); + private + + public + procedure SetText(Msg: String); + end; + +var + MsgBoxForm: TMsgBoxForm; + +implementation + +{ TMsgBoxForm } + +procedure TMsgBoxForm.Button1Click(Sender: TObject); +begin + Close; +end; + +procedure TMsgBoxForm.SetText(Msg: String); +const MinFormSize = 162; + TextThresholdWidth = 68; + DefButtonLeft = 40; +var TextW,Delta : Integer; +begin + Label1.Caption:= Msg; + TextW:= Label1.Canvas.GetTextWidth(Msg); + if TextW > TextThresholdWidth then + begin + Delta:= TextW - TextThresholdWidth; + Width:= MinFormSize + Delta; + Button1.Left:= DefButtonLeft + Delta div 2; + end; +end; + +initialization + //{$I msgbox.lrs} + {$R msgbox.lfm} + +end. + diff --git a/settings.lfm b/ui/options.lfm similarity index 57% rename from settings.lfm rename to ui/options.lfm index 2cf15ee..cf99fa0 100644 --- a/settings.lfm +++ b/ui/options.lfm @@ -1,25 +1,26 @@ object OptionsForm: TOptionsForm Left = 465 - Height = 351 - Top = 319 - Width = 825 + Height = 254 + Top = 322 + Width = 652 BorderIcons = [biSystemMenu] BorderStyle = bsDialog Caption = 'Options' - ClientHeight = 351 - ClientWidth = 825 - DesignTimePPI = 144 + ClientHeight = 254 + ClientWidth = 652 + Font.Name = 'Default' KeyPreview = True - OnCreate = EnableFields + OnCreate = FormCreate + OnDestroy = FormDestroy OnKeyPress = FormKeyPress Position = poScreenCenter ShowInTaskBar = stNever LCLVersion = '2.0.10.0' object BtnOk: TButton - Left = 576 - Height = 38 - Top = 300 - Width = 112 + Left = 480 + Height = 25 + Top = 216 + Width = 75 Caption = '&OK' Default = True ModalResult = 1 @@ -27,10 +28,10 @@ object OptionsForm: TOptionsForm TabOrder = 1 end object BtnCancel: TButton - Left = 696 - Height = 38 - Top = 300 - Width = 112 + Left = 568 + Height = 25 + Top = 216 + Width = 75 Caption = '&Cancel' ModalResult = 2 ParentFont = False @@ -38,24 +39,24 @@ object OptionsForm: TOptionsForm end object PageControl1: TPageControl Left = 0 - Height = 288 + Height = 208 Top = 0 - Width = 828 - ActivePage = GeneralTab + Width = 652 + ActivePage = TabSheet1 ParentFont = False - TabIndex = 0 + TabIndex = 3 TabOrder = 0 object GeneralTab: TTabSheet Caption = 'General' - ClientHeight = 250 - ClientWidth = 820 + ClientHeight = 172 + ClientWidth = 644 ParentFont = False object CheckAutostart: TCheckBox - Left = 256 - Height = 29 + Left = 171 + Height = 19 Hint = 'Begin counting down when the application starts' - Top = 111 - Width = 150 + Top = 74 + Width = 100 Caption = '&Autostart timer' ParentFont = False ParentShowHint = False @@ -63,11 +64,11 @@ object OptionsForm: TOptionsForm TabOrder = 4 end object CheckMinToTray: TCheckBox - Left = 18 - Height = 29 + Left = 12 + Height = 19 Hint = 'Don''t show the application in the taskbar when minimized' - Top = 159 - Width = 158 + Top = 106 + Width = 106 Caption = '&Minimize to tray' ParentFont = False ParentShowHint = False @@ -75,23 +76,23 @@ object OptionsForm: TOptionsForm TabOrder = 2 end object GroupBox2: TGroupBox - Left = 6 - Height = 72 - Top = 19 - Width = 240 + Left = 4 + Height = 48 + Top = 12 + Width = 160 Caption = 'Starting position' - ClientHeight = 42 - ClientWidth = 236 + ClientHeight = 28 + ClientWidth = 156 ParentFont = False TabOrder = 0 object PositionCombo: TComboBox - Left = 9 - Height = 33 + Left = 6 + Height = 23 Hint = 'Where to place the application window when it starts' - Top = 3 - Width = 216 + Top = 2 + Width = 144 DropDownCount = 6 - ItemHeight = 25 + ItemHeight = 15 ParentFont = False ParentShowHint = False ShowHint = True @@ -100,11 +101,11 @@ object OptionsForm: TOptionsForm end end object CheckClickTime: TCheckBox - Left = 256 - Height = 29 + Left = 171 + Height = 19 Hint = 'Click the timer numerals to start/pause the timer' - Top = 159 - Width = 168 + Top = 106 + Width = 113 Caption = 'Cl&ick time to start' ParentFont = False ParentShowHint = False @@ -112,11 +113,11 @@ object OptionsForm: TOptionsForm TabOrder = 5 end object CheckDblClickTime: TCheckBox - Left = 256 - Height = 29 + Left = 171 + Height = 19 Hint = 'Double-click the timer numerals to reset the timer' - Top = 207 - Width = 233 + Top = 138 + Width = 156 Caption = '&Double-click time to reset' ParentFont = False ParentShowHint = False @@ -124,11 +125,11 @@ object OptionsForm: TOptionsForm TabOrder = 6 end object CheckAutoRestart: TCheckBox - Left = 522 - Height = 29 + Left = 400 + Height = 19 Hint = 'Start the timer again when the time reaches zero' - Top = 111 - Width = 239 + Top = 74 + Width = 161 Caption = 'Automatically &restart timer' ParentFont = False ParentShowHint = False @@ -136,11 +137,11 @@ object OptionsForm: TOptionsForm TabOrder = 8 end object CheckLoopAudio: TCheckBox - Left = 522 - Height = 29 + Left = 400 + Height = 19 Hint = 'Continue playing the audio file until timer is reset' - Top = 159 - Width = 170 + Top = 106 + Width = 113 Caption = '&Loop audio alarm' ParentFont = False ParentShowHint = False @@ -148,11 +149,11 @@ object OptionsForm: TOptionsForm TabOrder = 9 end object CheckAutoSave: TCheckBox - Left = 18 - Height = 29 + Left = 12 + Height = 19 Hint = 'Automatically save settings to the .ini file on exit' - Top = 207 - Width = 171 + Top = 138 + Width = 113 Caption = 'Auto&save settings' ParentFont = False ParentShowHint = False @@ -160,11 +161,11 @@ object OptionsForm: TOptionsForm TabOrder = 3 end object CheckAlwaysOnTop: TCheckBox - Left = 18 - Height = 29 + Left = 12 + Height = 19 Hint = 'Show the window even when it''s deactivated' - Top = 111 - Width = 144 + Top = 74 + Width = 95 Caption = 'Al&ways on top' ParentFont = False ParentShowHint = False @@ -172,11 +173,11 @@ object OptionsForm: TOptionsForm TabOrder = 1 end object CheckTicking: TCheckBox - Left = 522 - Height = 29 + Left = 400 + Height = 19 Hint = 'Play a ticking sound when timer is running' - Top = 204 - Width = 174 + Top = 138 + Width = 117 Caption = '&Play ticking sound' ParentFont = False ParentShowHint = False @@ -184,11 +185,11 @@ object OptionsForm: TOptionsForm TabOrder = 10 end object CheckSecondsMode: TCheckBox - Left = 522 - Height = 29 + Left = 400 + Height = 19 Hint = 'Enter seconds instead of minutes' - Top = 62 - Width = 204 + Top = 42 + Width = 135 Caption = '&Enable seconds mode' ParentFont = False ParentShowHint = False @@ -196,11 +197,11 @@ object OptionsForm: TOptionsForm TabOrder = 7 end object CheckHideSeconds: TCheckBox - Left = 256 - Height = 29 + Left = 171 + Height = 19 Hint = 'Begin counting down when the application starts' - Top = 62 - Width = 137 + Top = 41 + Width = 91 Caption = '&Hide seconds' ParentFont = False ParentShowHint = False @@ -210,148 +211,148 @@ object OptionsForm: TOptionsForm end object AlarmsTab: TTabSheet Caption = 'Alarms' - ClientHeight = 166 - ClientWidth = 544 + ClientHeight = 172 + ClientWidth = 644 ParentFont = False object GroupBox1: TGroupBox - Left = 6 - Height = 216 - Top = 15 - Width = 801 + Left = 4 + Height = 138 + Top = 16 + Width = 574 Caption = 'Notification actions' - ClientHeight = 186 - ClientWidth = 797 + ClientHeight = 118 + ClientWidth = 570 ParentFont = False TabOrder = 0 object NotifyRunAppOn: TCheckBox - Left = 8 - Height = 17 - Top = 138 - Width = 84 + Left = 5 + Height = 19 + Top = 92 + Width = 93 Caption = '&Run program:' OnClick = EnableFields ParentFont = False TabOrder = 10 end object NotifyAudioOn: TCheckBox - Left = 8 - Height = 17 - Top = 94 - Width = 88 + Left = 5 + Height = 19 + Top = 63 + Width = 94 Caption = '&Play wave file:' OnClick = EnableFields ParentFont = False TabOrder = 6 end object NotifyTrayMsgOn: TCheckBox - Left = 8 - Height = 17 - Top = 48 - Width = 104 + Left = 5 + Height = 19 + Top = 32 + Width = 113 Caption = '&Show tray popup:' OnClick = EnableFields ParentFont = False TabOrder = 3 end object NotifyMsgOn: TCheckBox - Left = 8 - Height = 17 - Top = 4 - Width = 101 + Left = 5 + Height = 19 + Top = 3 + Width = 110 Caption = '&Display message:' OnClick = EnableFields ParentFont = False TabOrder = 0 end object NotifyTrayMsgTest: TButton - Left = 678 - Height = 38 - Top = 45 - Width = 112 + Left = 488 + Height = 25 + Top = 30 + Width = 75 Caption = 'Test' OnClick = TestTrayMsg ParentFont = False TabOrder = 5 end object NotifyMsgTest: TButton - Left = 678 - Height = 38 - Top = 2 - Width = 112 + Left = 488 + Height = 25 + Top = 1 + Width = 75 Caption = 'Test' OnClick = TestMessage ParentFont = False TabOrder = 2 end object NotifyRunTest: TButton - Left = 678 - Height = 38 - Top = 135 - Width = 112 + Left = 488 + Height = 25 + Top = 88 + Width = 75 Caption = 'Test' OnClick = TestRunApp ParentFont = False TabOrder = 13 end object NotifyAudioTest: TButton - Left = 678 - Height = 38 - Top = 92 - Width = 112 + Left = 488 + Height = 25 + Top = 56 + Width = 75 Caption = 'Test' OnClick = TestAudio ParentFont = False TabOrder = 9 end object NotifyTrayMsg: TEdit - Left = 195 - Height = 21 - Top = 48 - Width = 472 + Left = 160 + Height = 23 + Top = 32 + Width = 315 ParentFont = False TabOrder = 4 end object NotifyRunBtn: TButton - Left = 558 - Height = 38 - Top = 135 - Width = 112 + Left = 400 + Height = 25 + Top = 88 + Width = 75 Caption = 'Browse' OnClick = GetAppFile ParentFont = False TabOrder = 12 end object NotifyRunApp: TEdit - Left = 195 - Height = 21 - Top = 138 - Width = 348 + Left = 160 + Height = 23 + Top = 88 + Width = 232 ParentFont = False TabOrder = 11 end object NotifyAudioBtn: TButton - Left = 558 - Height = 38 - Top = 92 - Width = 112 + Left = 400 + Height = 25 + Top = 63 + Width = 75 Caption = 'Browse' OnClick = GetAudioFile ParentFont = False TabOrder = 8 end object NotifyAudio: TEdit - Left = 195 - Height = 21 - Top = 94 - Width = 348 + Left = 160 + Height = 23 + Top = 61 + Width = 232 ParentFont = False TabOrder = 7 end object NotifyMsg: TEdit - Left = 195 - Height = 21 - Top = 4 - Width = 472 + Left = 160 + Height = 23 + Top = 3 + Width = 315 ParentFont = False TabOrder = 1 end @@ -359,34 +360,33 @@ object OptionsForm: TOptionsForm end object FontsTab: TTabSheet Caption = 'Font' - ClientHeight = 250 - ClientWidth = 820 - OnShow = UpdateFonts + ClientHeight = 172 + ClientWidth = 644 ParentFont = False object TimerFontBox: TGroupBox - Left = 6 - Height = 156 - Top = 15 - Width = 801 + Left = 4 + Height = 104 + Top = 10 + Width = 534 Caption = 'Timer font' - ClientHeight = 126 - ClientWidth = 797 + ClientHeight = 84 + ClientWidth = 530 ParentFont = False TabOrder = 0 object Label1: TLabel - Left = 9 - Height = 25 - Top = 9 - Width = 35 + Left = 6 + Height = 15 + Top = 6 + Width = 23 Caption = 'Size:' ParentColor = False ParentFont = False end object FontColor: TColorButton - Left = 252 - Height = 38 - Top = 2 - Width = 112 + Left = 176 + Height = 25 + Top = 1 + Width = 75 BorderWidth = 2 ButtonColorSize = 16 ButtonColor = clBlack @@ -394,64 +394,63 @@ object OptionsForm: TOptionsForm ParentFont = False end object BgColor: TColorButton - Left = 543 - Height = 38 - Top = 2 - Width = 112 + Left = 384 + Height = 25 + Top = 1 + Width = 75 BorderWidth = 2 ButtonColorSize = 16 ButtonColor = clSilver - OnColorChanged = UpdateFonts + OnColorChanged = UpdateFontBgColor ParentFont = False end object LabelTextColor: TLabel - Left = 189 - Height = 25 - Top = 9 - Width = 47 + Left = 126 + Height = 15 + Top = 6 + Width = 32 Caption = 'Color:' ParentColor = False ParentFont = False end object LabelTextColor1: TLabel - Left = 429 - Height = 25 - Top = 9 - Width = 99 + Left = 286 + Height = 15 + Top = 6 + Width = 67 Caption = 'Background:' ParentColor = False ParentFont = False end object FontSize: TSpinEdit - Left = 69 - Height = 33 - Top = 4 - Width = 70 + Left = 46 + Height = 23 + Top = 3 + Width = 47 MaxValue = 1000 - OnChange = UpdateFontSize ParentFont = False TabOrder = 0 end - object FontName: TStaticText - Left = 141 - Height = 41 - Top = 70 - Width = 96 - Alignment = taCenter - AutoSize = True - BorderSpacing.InnerBorder = 4 + object FontPreview: TStaticText + Left = 94 + Height = 27 + Top = 47 + Width = 292 + Anchors = [akTop, akBottom] + BorderSpacing.InnerBorder = 3 Caption = '00:00:00' - Color = clCaptionText - Font.Height = -24 + Color = clDefault + Font.Height = -16 ParentFont = False ParentColor = False TabOrder = 2 + Transparent = False end object FontNameBtn: TButton - Left = 8 - Height = 38 - Top = 72 - Width = 112 + Left = 5 + Height = 25 + Top = 48 + Width = 75 Caption = '&Font...' OnClick = ChooseFont ParentFont = False @@ -459,18 +458,97 @@ object OptionsForm: TOptionsForm end end object BtnDefaults: TButton - Left = 15 - Height = 38 + Left = 10 + Height = 25 Hint = 'Reset font to default settings' - Top = 201 - Width = 112 + Top = 134 + Width = 75 Caption = '&Defaults' - OnClick = SetDefaults + OnClick = SetFontDefaults ParentFont = False ParentShowHint = False ShowHint = True TabOrder = 1 end end + object TabSheet1: TTabSheet + Caption = 'Compact Mode' + ClientHeight = 180 + ClientWidth = 644 + object CheckCompactMode: TCheckBox + Left = 16 + Height = 19 + Top = 16 + Width = 62 + Caption = 'Enabled' + OnClick = EnableFields + TabOrder = 0 + end + object AlphaLabel: TLabel + Left = 200 + Height = 15 + Top = 20 + Width = 31 + Caption = 'Alpha' + ParentColor = False + end + object AlphaValueTrackBar: TTrackBar + Left = 240 + Height = 25 + Top = 16 + Width = 104 + LineSize = 0 + Max = 255 + Min = 10 + Position = 128 + TickMarks = tmTopLeft + TickStyle = tsNone + TabOrder = 1 + end + object TransparencyRadioGroup: TRadioGroup + Left = 16 + Height = 112 + Top = 56 + Width = 168 + AutoFill = True + Caption = 'Transparency' + ChildSizing.LeftRightSpacing = 6 + ChildSizing.EnlargeHorizontal = crsHomogenousChildResize + ChildSizing.EnlargeVertical = crsHomogenousChildResize + ChildSizing.ShrinkHorizontal = crsScaleChilds + ChildSizing.ShrinkVertical = crsScaleChilds + ChildSizing.Layout = cclLeftToRightThenTopToBottom + ChildSizing.ControlsPerLine = 1 + ClientHeight = 92 + ClientWidth = 164 + TabOrder = 2 + object RadioTrNone: TRadioButton + Left = 6 + Height = 31 + Top = 0 + Width = 152 + Caption = 'None' + OnClick = EnableFields + TabOrder = 2 + end + object RadioTrBackground: TRadioButton + Left = 6 + Height = 31 + Top = 31 + Width = 152 + Caption = 'Transparent background' + TabOrder = 0 + end + object RadioTrAlphaBlending: TRadioButton + Left = 6 + Height = 30 + Top = 62 + Width = 152 + Caption = 'Alpha blending' + OnChange = EnableFields + TabOrder = 1 + end + end + end end end diff --git a/ui/options.pas b/ui/options.pas new file mode 100644 index 0000000..1ab1c2b --- /dev/null +++ b/ui/options.pas @@ -0,0 +1,379 @@ +unit Options; + +{$mode objfpc}{$H+} + +interface + +uses + SysUtils, LResources, Forms, Graphics, Dialogs, StdCtrls, ComCtrls, Spin, + ExtCtrls, Classes; + +type + + { TOptionsForm } + + TOptionsForm = class(TForm) + BtnOk: TButton; + BtnCancel: TButton; + BtnDefaults: TButton; + CheckAutoRestart: TCheckBox; + CheckCompactMode: TCheckBox; + CheckHideSeconds: TCheckBox; + CheckSecondsMode: TCheckBox; + CheckAutoSave: TCheckBox; + CheckAlwaysOnTop: TCheckBox; + CheckTicking: TCheckBox; + CheckLoopAudio: TCheckBox; + CheckClickTime: TCheckBox; + CheckDblClickTime: TCheckBox; + FontColor: TColorButton; + FontNameBtn: TButton; + CheckAutostart: TCheckBox; + CheckMinToTray: TCheckBox; + BgColor: TColorButton; + FontSize: TSpinEdit; + Label1: TLabel; + FontPreview: TStaticText; + AlphaLabel: TLabel; + LabelTextColor: TLabel; + LabelTextColor1: TLabel; + RadioTrNone: TRadioButton; + RadioTrBackground: TRadioButton; + RadioTrAlphaBlending: TRadioButton; + TransparencyRadioGroup: TRadioGroup; + TabSheet1: TTabSheet; + TimerFontBox: TGroupBox; + PositionCombo: TComboBox; + GroupBox1: TGroupBox; + GroupBox2: TGroupBox; + NotifyAudio: TEdit; + NotifyAudioBtn: TButton; + NotifyAudioOn: TCheckBox; + NotifyAudioTest: TButton; + NotifyMsg: TEdit; + NotifyMsgOn: TCheckBox; + NotifyMsgTest: TButton; + NotifyRunApp: TEdit; + NotifyRunAppOn: TCheckBox; + NotifyRunBtn: TButton; + NotifyRunTest: TButton; + NotifyTrayMsg: TEdit; + NotifyTrayMsgOn: TCheckBox; + NotifyTrayMsgTest: TButton; + PageControl1: TPageControl; + GeneralTab: TTabSheet; + AlarmsTab: TTabSheet; + FontsTab: TTabSheet; + AlphaValueTrackBar: TTrackBar; + procedure FormCreate(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure FormKeyPress(Sender: TObject; var Key: char); + + function GetFile(Orig: String; FilterStr: String; Dir : String): String; + procedure GetAudioFile(Sender: TObject); + procedure GetAppFile(Sender: TObject); + procedure ChooseFont(Sender: TObject); + procedure EnableFields(Sender: TObject); + procedure SetFontDefaults(Sender: TObject); + procedure TestAudio(Sender: TObject); + procedure TestMessage(Sender: TObject); + procedure TestRunApp(Sender: TObject); + procedure TestTrayMsg(Sender: TObject); + procedure UpdateFontColor(Sender: TObject); + procedure UpdateFontBgColor(Sender: TObject); + private + public + { public declarations } + end; + +var + OptionsForm: TOptionsForm; + +implementation + +uses Controls, MainForm1, Config, Utils, MainController, Consts; +{ TOptionsForm } + +const + FONT_PREVIEW_FONT_SIZE = 18; + +procedure TOptionsForm.FormCreate(Sender: TObject); +var Config: TConfig; + WndPositions: TStrings; +begin + //Application.MessageBox(PChar(String(GetFontData(self.Font.Handle).Name)), ''); + Config:= GetConfig; + + PageControl1.TabIndex := 0; + + // Main + WndPositions := TStringList.Create; + WndPositions.Add('Centered'); + WndPositions.Add('Remember position'); + WndPositions.Add('Top left'); + WndPositions.Add('Top right'); + WndPositions.Add('Bottom left'); + WndPositions.Add('Bottom right'); + PositionCombo.Items := WndPositions; + PositionCombo.ItemIndex := Ord(Config.WndPosition); + + CheckAlwaysOnTop.Checked:= Config.AlwaysOnTop; + CheckMinToTray.Checked:= Config.MinToTray; + CheckAutostart.Checked:= Config.AutoStart; + CheckHideSeconds.Checked:= Config.HideSeconds; + CheckClicktime.Checked:= Config.ClickTime; + CheckDblClickTime.Checked:= Config.DblClickTime; + CheckAutoRestart.Checked:= Config.AutoRestart; + CheckLoopAudio.Checked:= Config.LoopAudio; + CheckTicking.Checked:= Config.TickingOn; + CheckAutoSave.Checked:= Config.AutoSave; + CheckSecondsMode.Checked:= Config.SecondsMode; + + // Alarms + NotifyMsg.Text:= Config.DoneMessage; + NotifyMsgOn.Checked:= Config.DoneMessageEnabled; + + NotifyTrayMsg.Text:= Config.DoneTrayMsg; + NotifyTrayMsgOn.Checked:= Config.DoneTrayMsgEnabled; + + NotifyAudio.Text:= Config.DoneAudio; + NotifyAudioOn.Checked:= Config.DoneAudioEnabled; + + NotifyRunApp.Text:= Config.DoneApp; + NotifyRunAppOn.Checked:= Config.DoneAppEnabled; + + // Fonts + FontSize.Value:= Config.Font.Size; + FontColor.ButtonColor:= Config.Font.Color; + BgColor.ButtonColor:= Config.Font.BgColor; + FontPreview.Font.Name:= Config.Font.Name; + //FontPreview.Font.Size:= Config.Font.Size; // size is fixed + FontPreview.Font.Size:= FONT_PREVIEW_FONT_SIZE; + FontPreview.Font.CharSet:= Config.Font.Charset; + FontPreview.Font.Color:= Config.Font.Color; + FontPreview.Font.Style:= Config.Font.Style; + FontPreview.Color:= Config.Font.BgColor; + FontPreview.Caption:= Config.Font.Name + ' : 1234567890'; + + // Compact Mode + CheckCompactMode.Checked:= Config.CompactMode.Enabled; + case Config.CompactMode.Transparency of + None: RadioTrNone.Checked:= True; + TransparentBackground: RadioTrBackground.Checked:= True; + AlphaBlending: RadioTrAlphaBlending.Checked:= True; + end; + AlphaValueTrackBar.Position:= Config.CompactMode.AlphaValue; + EnableFields(Sender); + +{$IFDEF LINUX} + // TODO: Not supported yet + // Create a thread that will call play command? + CheckLoopAudio.Enabled:= False; + CheckTicking.Enabled:= False; + RadioTrBackground.Enabled:= False; +{$ENDIF} +end; + + +procedure TOptionsForm.FormDestroy(Sender: TObject); +var Config : TConfig; +begin + if ModalResult = mrOk then + begin + // Update Config + Config:= GetConfig; + // Main + Config.AlwaysOnTop:= CheckAlwaysOnTop.Checked; + Config.MinToTray:= CheckMinToTray.Checked; + Config.AutoStart:= CheckAutostart.Checked; + Config.HideSeconds:= CheckHideSeconds.Checked; + Config.ClickTime:= CheckClicktime.Checked; + Config.DblClickTime:= CheckDblClickTime.Checked; + Config.AutoRestart:= CheckAutoRestart.Checked; + Config.LoopAudio:= CheckLoopAudio.Checked; + Config.TickingOn:= CheckTicking.Checked; + Config.AutoSave:= CheckAutoSave.Checked; + Config.SecondsMode:= CheckSecondsMode.Checked; + + // Placement + Config.WndPosition:= TPosition(PositionCombo.ItemIndex); + + // Alarms + Config.DoneMessage:= NotifyMsg.Text; + Config.DoneMessageEnabled:= NotifyMsgOn.Checked; + Config.DoneTrayMsg:= NotifyTrayMsg.Text; + Config.DoneTrayMsgEnabled:= NotifyTrayMsgOn.Checked; + Config.DoneAudio:= NotifyAudio.Text; + Config.DoneAudioEnabled:= NotifyAudioOn.Checked; + Config.DoneApp:= NotifyRunApp.Text; + Config.DoneAppEnabled:= NotifyRunAppOn.Checked; + + // Fonts + Config.Font.Name:= FontPreview.Font.Name; + Config.Font.Charset:= FontPreview.Font.CharSet; + Config.Font.Color:= FontPreview.Font.Color; + Config.Font.BgColor:= FontPreview.Color; + Config.Font.Size:= FontSize.Value; // FontPreview has fixed size + Config.Font.Style:= FontPreview.Font.Style; + + // Compact Mode + Config.CompactMode.Enabled:= CheckCompactMode.Checked; + if RadioTrNone.Checked then + Config.CompactMode.Transparency:= None + else if RadioTrBackground.Checked then + Config.CompactMode.Transparency:= TransparentBackground + else if RadioTrAlphaBlending.Checked then + Config.CompactMode.Transparency:= AlphaBlending; + Config.CompactMode.AlphaValue:= AlphaValueTrackBar.Position; + end; +end; + +procedure TOptionsForm.FormKeyPress(Sender: TObject; var Key: char); +begin + if key = #27 then Close; +end; + +// TODO Move all text strings to the top + +function TOptionsForm.GetFile(Orig: String; FilterStr: String; Dir : String): String; +var + dlg : TOpenDialog; + fname : String; + cwd : String; + relPath : String; +begin + dlg := TOpenDialog.Create(nil); + dlg.FileName := ''; + if DirectoryExists(Dir) then + dlg.InitialDir := Dir + else + dlg.InitialDir := GetCurrentDir; + dlg.Options := [ofFileMustExist]; + dlg.Filter := FilterStr; + dlg.FilterIndex := 1; + + if dlg.Execute then + begin + fname := dlg.FileName; + cwd := GetCurrentDir + SEPARATOR; + relPath := ExtractRelativePath(cwd, ExtractFilePath(fname)); + Result := '.' + SEPARATOR + relPath + ExtractFileName(fname); + end else begin + Result := Orig; + end; + dlg.Free; +end; + +procedure TOptionsForm.GetAudioFile(Sender: TObject); +begin + NotifyAudio.Text := GetFile(NotifyAudio.Text, 'Wave files (*.wav)|*.wav', GetCurrentDir + SEPARATOR + 'sounds'); +end; + +procedure TOptionsForm.GetAppFile(Sender: TObject); +begin +{$IFDEF WINDOWS} + NotifyRunApp.Text := GetFile(NotifyRunApp.Text, 'Executables (*.exe)|*.exe|All files (*.*)|*.*', GetCurrentDir); +{$ENDIF} + +{$IFDEF LINUX} + NotifyRunApp.Text := GetFile(NotifyRunApp.Text, 'All files (*.*)|*.*', GetCurrentDir); +{$ENDIF} +end; + + +procedure TOptionsForm.ChooseFont(Sender: TObject); +var + dlg : TFontDialog; +begin + dlg := TFontDialog.Create(nil); + dlg.Font:= FontPreview.Font; + dlg.Font.Size:= FontSize.Value; + if dlg.Execute then + begin + FontSize.Value:= Dlg.Font.Size; + FontColor.ButtonColor:= Dlg.Font.Color; + FontPreview.Caption:= Dlg.Font.Name + ' : 1234567890'; + FontPreview.Font:= Dlg.Font; + FontPreview.Font.Size:= FONT_PREVIEW_FONT_SIZE; + end; + dlg.Free; +end; + + + +procedure TOptionsForm.EnableFields(Sender: TObject); +begin + NotifyMsg.Enabled := NotifyMsgOn.Checked; + NotifyMsgTest.Enabled := NotifyMsgOn.Checked; + NotifyTrayMsg.Enabled := NotifyTrayMsgOn.Checked; + NotifyTrayMsgTest.Enabled := NotifyTrayMsgOn.Checked; + + NotifyAudio.Enabled := NotifyAudioOn.Checked; + NotifyAudioBtn.Enabled := NotifyAudioOn.Checked; + NotifyAudioTest.Enabled := NotifyAudioOn.Checked; + + NotifyRunApp.Enabled := NotifyRunAppOn.Checked; + NotifyRunBtn.Enabled := NotifyRunAppOn.Checked; + NotifyRunTest.Enabled := NotifyRunAppOn.Checked; + + TransparencyRadioGroup.Enabled:= CheckCompactMode.Checked; + AlphaLabel.Enabled:= CheckCompactMode.Checked And RadioTrAlphaBlending.Checked; + AlphaValueTrackBar.Enabled:= CheckCompactMode.Checked And RadioTrAlphaBlending.Checked; +end; + + +procedure TOptionsForm.UpdateFontColor(Sender: TObject); +begin + FontPreview.Font.Color:= FontColor.ButtonColor; +end; + +procedure TOptionsForm.UpdateFontBgColor(Sender: TObject); +begin + FontPreview.Color:= BgColor.ButtonColor; + +end; + + +procedure TOptionsForm.SetFontDefaults(Sender: TObject); +var + DefFont : TFontConfig; +begin + DefFont:= GetConfig.GetDefaultFont; + + FontSize.Value:= DefFont.Size; + FontColor.ButtonColor:= DefFont.Color; + BgColor.ButtonColor:= DefFont.BgColor; + FontPreview.Caption:= DefFont.Name + ' : 1234567890'; + FontPreview.Font.Name:= DefFont.Name; + //FontPreview.Font.Size:= DefFont.Size; + FontPreview.Font.CharSet:= DefFont.Charset; + FontPreview.Font.Color:= DefFont.Color; + FontPreview.Font.Style:= DefFont.Style; + FontPreview.Color:= DefFont.BgColor; +end; + +procedure TOptionsForm.TestAudio(Sender: TObject); +begin + with Self.Owner as TMainForm do + TUtils.PlayAudio(NotifyAudio.Text, False); +end; + +procedure TOptionsForm.TestMessage(Sender: TObject); +begin + GetMainController.ShowDoneMessage(NotifyMsg.Text); +end; + +procedure TOptionsForm.TestRunApp(Sender: TObject); +begin + TUtils.RunApp(NotifyRunApp.Text); +end; + +procedure TOptionsForm.TestTrayMsg(Sender: TObject); +begin + GetMainController.ShowTrayMessage(NotifyTrayMsg.Text); +end; + +initialization + {$I options.lrs} +end. + diff --git a/version.inc b/version.inc index 89274e3..e0e84b5 100644 --- a/version.inc +++ b/version.inc @@ -1 +1 @@ -'0.2' \ No newline at end of file +'0.3' \ No newline at end of file